* [PATCH 6.18 000/686] 6.18.64-rc1 review
@ 2026-11-13 15:42 Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 001/686] smb: client: validate the data area in SMB2_read() Greg Kroah-Hartman
` (685 more replies)
0 siblings, 686 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, linux-kernel, torvalds, akpm, linux,
shuah, patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
This is the start of the stable review cycle for the 6.18.64 release.
There are 686 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/v6.x/stable-review/patch-6.18.64-rc1.gz
or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.18.y
and the diffstat can be found below.
thanks,
greg k-h
-------------
Pseudo-Shortlog of commits:
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Linux 6.18.64-rc1
José Miguel Castellanos Valladolid <josstamy@gmail.com>
ALSA: hda/realtek: Enable mute LEDs on HP OmniBook X Flip 14-fm0xxx
Jaeho Cho <jaeho2025@gmail.com>
ALSA: hda/realtek: Enable mute LEDs on HP OmniBook 7 17-dc0xxx
Gianluca Balboni <gianluca.balboni06@gmail.com>
ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx
Armaan Sandhu <armaan.sandhu0504@gmail.com>
lib/cmdline: fix get_options() count and overflow with large ranges
Shuvam Pandey <shuvampandey1@gmail.com>
lib/tests: extend cmdline KUnit with next_arg() tests
Wang Yan <wangyan01@kylinos.cn>
selftests/landlock: Fix snprintf truncation checks in test files
Arnaldo Carvalho de Melo <acme@redhat.com>
perf python: Free the parse error entries when parsing fails
Karl Mehltretter <kmehltretter@gmail.com>
fbdev: sh_mobile_lcdcfb: Restore the per-overlay sysfs attributes
Chintan Patel <chintanlike@gmail.com>
fbdev: sh_mobile_lcdc: Make FB_DEVICE dependency optional
Chintan Patel <chintanlike@gmail.com>
fb: Add dev_of_fbinfo() helper for optional sysfs support
Mario Limonciello <mario.limonciello@amd.com>
platform/x86/amd/pmf: Add AMDI0112 ACPI ID
Myeonghun Pak <mhun512@gmail.com>
fbdev: nvidia: Release write-combining handle on probe failure
Shixiong Ou <oushixiong@kylinos.cn>
fbdev: nvidia: Convert to managed PCI and ioremap API
Wentao Liang <vulab@iscas.ac.cn>
power: supply: ltc2941: Fix of_node reference leak in ltc294x_i2c_probe()
Au Dang <au.dang.jx@renesas.com>
irqchip/renesas-rzv2h: Preserve TIEN state in rzv2h_tint_set_type()
Guangshuo Li <lgs201920130244@gmail.com>
crypto: omap-sham - fix crypto engine cleanup
Thorsten Blum <thorsten.blum@linux.dev>
crypto: omap - add omap_sham_unregister_algs helper
Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
hwmon: (coretemp) Return -ENODATA for invalid temperature readings
Andrea Parri <parri.andrea@gmail.com>
iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA
Lorenzo Stoakes (ARM) <ljs@kernel.org>
mm/vma: avoid broken uffd merge on mremap
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
David Hildenbrand (Arm) <david@kernel.org>
mm/huge_memory: split huge PUDs when adjusting VMA boundaries
Rudi Heitbaum <rudi@heitbaum.com>
PCI: imx6: Avoid dereferencing a NULL clock name
Hung-Jui Lin <alex.lin.programmer@gmail.com>
posix-timers: Report zero remaining time for disarmed SIGEV_NONE timers
Thomas Gleixner <tglx@kernel.org>
posix-timers: Handle the timer_[re]arm() return value
Evgeny Akhtimirov <evgeny@devduty.com>
ALSA: hda/realtek: Enable all four speaker amps on Lenovo ThinkBook X G2 IAH
Bradley Morgan <brads@mainlining.org>
panic: restore variable arguments to nmi_panic()
Steve Wahl <steve.wahl@hpe.com>
watchdog/hpwdt: Refine hpwdt message for UV platform
Yingjie Wang <1075151112@qq.com>
nvme-tcp: validate the TLS handshake timeout
Yingjie Wang <1075151112@qq.com>
nvmet-tcp: validate the TLS handshake timeout
Borislav Petkov (AMD) <bp@alien8.de>
Documentation/kernel-parameters: Move the kernel build options
Huacai Chen <chenhuacai@kernel.org>
LoongArch: Don't init & online empty nodes
Chao Yu <chao@kernel.org>
f2fs: fix to invalidate curseg if change_curseg() fails
David Carlier <devnexen@gmail.com>
mm/shmem: don't release a swapin-error marker as a swap entry
Christian Brauner <brauner@kernel.org>
iomap: don't mark unwritten parts of a folio uptodate
Linmao Li <lilinmao@kylinos.cn>
PCI: cadence: Store the core controller in platform drvdata
Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
arm64/gcs: release GCS on failed fork
Giorgi Kobakhia <gkobakhi@asu.edu>
ocfs2: fix array out of bound access in __ocfs2_find_path()
Edward Adam Davis <eadavis@qq.com>
ocfs2: fix oob in __ocfs2_find_path
Tiezhu Yang <yangtiezhu@loongson.cn>
LoongArch: Fix one-shot limitation for perf hardware breakpoints
Nikolaos Karaolidis <nick@karaolidis.com>
fs: don't lose inodes that another LRU walker is isolating
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
Hongfu Li <lihongfu@kylinos.cn>
mm/memfd: fix hugetlb reservation accounting in error paths
Jinmeng Zhou <jinmengzhou22@gmail.com>
mm/hugetlb: charge folios to the target mm's memcg
Josef Bacik <josef@toxicpanda.com>
mm/vma: don't leak the commit charge on mmap failure
Hongfu Li <lihongfu@kylinos.cn>
mm/memcg: migrate per-node hugetlb lruvec stat together with hugetlb folio
Ye Liu <ye.liu@linux.dev>
mm: use enum migrate_reason instead of int for migration reason parameters
Qi Zheng <zhengqi.arch@bytedance.com>
mm: memcontrol: refactor mod_memcg_state() and mod_memcg_lruvec_state()
Nikolaos Karaolidis <nick@karaolidis.com>
fs: rotate inodes whose page cache could not be dropped
Jan Kara <jack@suse.cz>
fs: Ignore inode metadata buffers in inode_lru_isolate()
Mateusz Guzik <mjguzik@gmail.com>
fs: provide accessors for ->i_state
Mateusz Guzik <mjguzik@gmail.com>
fs: spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb
Mateusz Guzik <mjguzik@gmail.com>
fs: add missing fences to I_NEW handling
Mateusz Guzik <mjguzik@gmail.com>
fs: assert on ->i_count in iput_final()
Alexander Sverdlin <alexander.sverdlin@gmail.com>
tpm: tpm2_probe: propagate transport errors
Alexey Charkov <alchark@flipper.net>
nvmem: rockchip-otp: Serialize reads
Rosen Penev <rosenp@gmail.com>
nvmem: rockchip-otp: alloc clks with main struct
Ming Lei <tom.leiming@gmail.com>
ublk: mark the io command cancelable before publishing it
Gregory Price <gourry@gourry.net>
mm/mempolicy: use vm_normal_folio_pmd() in queue_folios_pmd()
Wentao Liang <vulab@iscas.ac.cn>
xen/gntdev: Fix gntdev_dmabuf ref leak in dmabuf_exp_wait_released()
Ackerley Tng <ackerleytng@google.com>
mm: hugetlb: drop refcount before freeing on memcg charge failure
Ackerley Tng <ackerleytng@google.com>
mm: hugetlb: return -ENOSPC on memcg charge failure
Yao Yiqi <yaoyiqi3@huawei.com>
fbcon: Retry rotated font allocation after failure
Antoniu Miclaus <antoniu.miclaus@analog.com>
iio: adc: ad4080: enable address ascension for chip identification
Rong Zhang <i@rong.moe>
platform/x86: lenovo-wmi-capdata: Do not stop the AC notifier chain on error
Rong Zhang <i@rong.moe>
platform/x86: Rename lenovo-wmi-capdata01 to lenovo-wmi-capdata
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
Art O Cathain <art.home@gmail.com>
ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265
Sehat Mahde <hskmahde@gmail.com>
ASoC: amd: acp-config: force SoundWire probe on HP OmniBook X Flip 16
Jackie Dong <xy-jackie@139.com>
ASoC: amd: acp: Add DMI quirk for Lenovo Yoga Pro 7 15ASH11
Jasper Smet <josbeir@gmail.com>
ASoC: amd: acp: Add DMI quirk for ASUS Zenbook S16 UM5606GA
Hasun Park <hasunpark@gmail.com>
ASoC: amd: acp: add DMI override for ACP70 flag
Devin Wittmayer <lucid_duck@justthetip.ca>
wifi: mt76: move the channel survey when the channel changes
Devin Wittmayer <lucid_duck@justthetip.ca>
wifi: mt76: mt7921: assert sniffer on chanctx change
Stanley Jhu <stanleyjhu@google.com>
scsi: ufs: core: Add a helper for clearing hba->outstanding_reqs
Chao Yu <chao@kernel.org>
f2fs: fix to use bio_in_atomic() in f2fs_read_end_io()
Tal Zussman <tz2294@columbia.edu>
block: introduce bio_in_atomic()
Kaixuan Li <kaixuanli0131@gmail.com>
f2fs: bound the SIT/NAT bitmaps by the checkpoint pack
Chi Zhiling <chizhiling@kylinos.cn>
exfat: advance valid_size to EOF for append writes
Andrea Parri <parri.andrea@gmail.com>
iomap: don't lose a failed direct I/O bio's error when zeroing the tail
Pankaj Raghav <p.raghav@samsung.com>
iomap: use largest_zero_folio() in iomap_dio_zero()
Vladyslav Tymoshchuk <tvlad744@gmail.com>
ASoC: qcom: q6apm-dai: wrap the position of a full ring to 0
Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
media: iris: Fix power-off ordering to disable power domain after clocks
Martin Fuzzey <martin.fuzzey@flowbird.group>
serial: sc16is7xx: fix data corruption due to unexpected xon/xoff
Sinan Turunc <enscrpt@pm.me>
ALSA: ua101: Bound packet copies by the PCM buffer size
Ruide Cao <caoruide123@gmail.com>
mptcp: fix MP_CAPABLE token migration when cloning reqsk
Xuanqiang Luo <luoxuanqiang@kylinos.cn>
rculist: Add hlist_nulls_replace_rcu() and hlist_nulls_replace_init_rcu()
Sung Byeongchan <tjdqudcks0424@naver.com>
virtiofs: validate fixed-output response length
Yuto Ohnuki <ytohnuki@amazon.com>
virtiofs: add FUSE protocol validation
Hugo Villeneuve <hvilleneuve@dimonoff.com>
serial: sc16is7xx: declare MCR and IER as volatile registers
Hugo Villeneuve <hvilleneuve@dimonoff.com>
serial: sc16is7xx: add comments for lock requirements
Hugo Villeneuve <hvilleneuve@dimonoff.com>
serial: sc16is7xx: declare SPR/TLR/XOFF2 register as volatile
Tobias Schumacher <ts@linux.ibm.com>
s390/pci: Add error cleanup in zpci_directed_irq_init()
Darrick J. Wong <djwong@kernel.org>
xfarray: don't crash when sorting if array element crosses a folio
Matthew Wilcox (Oracle) <willy@infradead.org>
xfs: Use folio_next_pos()
Matthew Wilcox (Oracle) <willy@infradead.org>
filemap: Add folio_next_pos()
Fan Wu <fanwu01@zju.edu.cn>
media: rockchip: rga: quiesce IRQ before releasing m2m state
Sven Püschel <s.pueschel@pengutronix.de>
media: rockchip: rga: use clk_bulk api
Marc Zyngier <maz@kernel.org>
KVM: arm64: nv: Move L2->L1 switch on interrupt early
Marco Scardovi <scardracs@disroot.org>
platform/x86: asus-wmi: Serialize WMI method evaluations with a mutex
Ma Ke <make_ruc2021@163.com>
ALSA: hda: cs35l41: Fix ACPI device reference leak on probe failure
Takashi Iwai <tiwai@suse.de>
ALSA: hda: cs35l41: Use auto-cleanup for put_device()
Myeonghun Pak <mhun512@gmail.com>
mfd: twl-core: Unregister the auxiliary platform device on unbind
Thorsten Blum <thorsten.blum@linux.dev>
mfd: twl-core: Use i2c_check_functionality as boolean value
Kenneth Feng <kenneth.feng@amd.com>
drm/amd/pm:restate all customized OD features on every table upload for smu 13.0.0/smu 14.0.2
Daeho Jeong <daehojeong@google.com>
f2fs: return -EIO for a lost inode block after cp_error
Ridong Chen <chenridong@xiaomi.com>
mm/mglru: fix ineffective memory protection for non-kswapd reclaim
Tejun Heo <tj@kernel.org>
cgroup: Expose some cgroup helpers
Chao Yu <chao@kernel.org>
f2fs: zone: fix to avoid bio split on sequential zone
Ethan Nelson-Moore <enelsonmoore@gmail.com>
ata: sata_inic162x: remove dangerous broken driver
Bart Van Assche <bvanassche@acm.org>
ata: libata: Add an argument to ata_eh_reset()
Li RongQing <lirongqing@baidu.com>
vfio/pci: Restore 8-byte ioeventfd support
Karl Mehltretter <kmehltretter@gmail.com>
spi: atmel-quadspi: balance runtime PM and pclk across system sleep
Robert Marko <robert.marko@sartura.hr>
spi: atmel-quadspi: use init callback for gclk variants
Robert Marko <robert.marko@sartura.hr>
spi: atmel-quadspi: add controller init callback
Matej Sochan <matej.sochan@gmail.com>
ALSA: hda/realtek: Fix silent speakers on Lenovo Legion S7 15IMH05
Nicholas Bonello <hadobedo@gmail.com>
ALSA: hda/realtek: Fix Legion 7 16ITHG6 speaker amp binding
Rámon van Raaij <ramon@vanraaij.eu>
ALSA: hda/realtek: Add codec SSID quirk for Lenovo Yoga Pro 9 16IMH9
Jiale Yao <yaojiale02@163.com>
iio: dac: mcp4821: reject devices without match data
Myeonghun Pak <mhun512@gmail.com>
ASoC: stm: stm32_i2s: request IRQ after regmap initialization
bui duc phuc <phucduc.bui@gmail.com>
ASoC: stm: stm32_i2s: Drop redundant error messages
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
Tom Verdonck <tom.verdonck@inspiral.be>
hwmon: (tmp108) Fix jiffies wraparound in conversion-ready check
Yunpeng Tian <shionthanatos@gmail.com>
udf: validate the device specification EA before using it
Chris Mason <mason@kernel.org>
ovl: fail the mount if the casefold flag has changed
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
Zhiling Zou <zhilinz@nebusec.ai>
ipmr: only copy pktinfo to cache reports
Eric Dumazet <edumazet@google.com>
ipmr: prevent info-leak in pmr_cache_report()
Baolin Wang <baolin.wang@linux.alibaba.com>
mm: memory: fix truncation removing mapped folios
Weibin Liu <liuwb@xiaopeng.com>
spi: cadence-xspi: reject SDMA transfers larger than the requested length
Jisheng Zhang <jszhang@kernel.org>
spi: cadence-xspi: group marvell support code together
Hans Zhang <18255117159@163.com>
spi: cadence-xspi: Use FIELD_MODIFY()
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
spi: cadence-xspi: Replace ACPI specifics by agnostic APIs
Chris Mason <mason@kernel.org>
mm/shmem: honour F_SEAL_EXEC when an ACL is set
Kyle Zeng <kylebot@openai.com>
mm/page_vma_mapped: continue past nonmatching huge PMDs
Jiangshan Yi <yijiangshan@kylinos.cn>
ceph: fix longname buffer overflow in ceph_fname_to_usr()
David Hildenbrand (Arm) <david@kernel.org>
mm/userfaultfd: only allocate anon_vma in CoW mappings
Josef Bacik <josef@toxicpanda.com>
mm/hugetlb: unmap the page where the other VMA maps it
Yuejie Shi <syjcnss@gmail.com>
fs/ntfs3: validate the EA value length in ntfs_read_ea()
Vaibhav Nagare <vnagare@redhat.com>
bnxt_en: don't leave an XDP program installed when the open fails
Michael Chan <michael.chan@broadcom.com>
bnxt_en: Refactor some basic ring setup and adjustment logic
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
Fuad Tabba <fuad.tabba@linux.dev>
KVM: arm64: Pin the host vCPU before adjusting its PC under pKVM
Dave Jiang <dave.jiang@intel.com>
cxl/port: Clear cached dport pointers when a dport is removed
Dan Williams <dan.j.williams@intel.com>
cxl/port: Cleanup handling of the nr_dports 0 -> 1 transition
Yifei Gao <gyf161023@gmail.com>
misc: fastrpc: fix double-free in fastrpc_map_attach() error path
Kumari Pallavi <kumari.pallavi@oss.qualcomm.com>
misc: fastrpc: Rename phys to dma_addr for clarity
Ming Lei <tom.leiming@gmail.com>
ublk: keep a canceled FETCH round canceling until the server is gone
Sean Christopherson <seanjc@google.com>
KVM: guest_memfd: Establish memslot<=>guest_memfd bindings *after* memslot is ready
Guangshuo Li <lgs201920130244@gmail.com>
media: i2c: ov5647: fix power cleanup on remove
Sean Young <sean@mess.org>
media: redrat3: Error path leaves device in transmitting state
Esben Haabendal <esben@geanix.com>
iio: light: ltr501: Power down chip if request irq fails
Pan Chuang <panchuang@vivo.com>
iio: light: Remove redundant dev_err()/dev_err_probe()
Chao Yu <chao@kernel.org>
f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly
Gaurav Batra <gbatra@linux.ibm.com>
powerpc/pseries/iommu: Add TCEs for 16GB pages when RAM is pre-mapped
Christopher Lusk <clusk@northecho.dev>
m68k: Fix seccomp filtering on ColdFire and 68000
Daniel Palmer <daniel@0x0f.com>
m68k: Fix task info flags handling for 68000
Chao Yu <chao@kernel.org>
f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio()
Guangshuo Li <lgs201920130244@gmail.com>
media: i2c: og01a1b: power off sensor on remove
Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams
Jiaming Zhang <r772577952@gmail.com>
gfs2: reject invalid inode sizes
Tom Verdonck <tom.verdonck@inspiral.be>
hwmon: (tmp102) Fix jiffies wraparound in conversion-ready check
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
Danish Khateeb <danishkhateeb03@gmail.com>
ALSA: timer: Handle userspace-driven timer ioctls from 32-bit tasks
bui duc phuc <phucduc.bui@gmail.com>
ALSA: core: Clean up file_operations definitions
Jiale Yao <yaojiale02@163.com>
iio: adc: ad7192: reject devices without match data
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
iio: adc: ad7192: Revert "properly check spi_get_device_match_data()"
Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
media: iris: Fix iova allocation from restrict region
Sakari Ailus <sakari.ailus@linux.intel.com>
media: imx219: Account for rate_factor in control steps
Sakari Ailus <sakari.ailus@linux.intel.com>
media: imx219: Account rate_factor in setting upper exposure limit
Tarang Raval <tarang.raval@siliconsignals.io>
media: i2c: imx219: Replace exposure magic value with named constant
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
Balakrishnan Sambath <balakrishnan.s@microchip.com>
media: microchip-isc: store the unshifted PFE_CFG0 BPS value
Wei-Lin Chang <weilin.chang@arm.com>
KVM: arm64: ptdump: Check the page tables aren't freed when accessing
Fuad Tabba <fuad.tabba@linux.dev>
KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort()
Fabio Cesari <fabio.cesari@gmail.com>
iio: light: isl29028: fix runtime PM reference leak on error paths
Sang-Heon Jeon <ekffu200098@gmail.com>
iio: light: isl29028: remove isl29028_set_pm_runtime_busy() helper
Sean Christopherson <seanjc@google.com>
KVM: guest_memfd: Split bind() into prepare()+commit() phases
Hans de Goede <johannes.goede@oss.qualcomm.com>
platform/x86: int3472: Increase handshake GPIO delay to 200 ms
Tarang Raval <tarang.raval@siliconsignals.io>
platform: int3472: discrete: Support multiple HIDs per GPIO map entry
Koichiro Den <den@valinux.co.jp>
PCI: endpoint: pci-epf-vntb: Manage virtual NTB and PCI bus lifetime
Abel Vesa <abel.vesa@linaro.org>
soc: qcom: pmic_glink: Fix device access from worker during suspend
Sakari Ailus <sakari.ailus@linux.intel.com>
media: imx219: The horizontal blanking step is 8
Tarang Raval <tarang.raval@siliconsignals.io>
media: i2c: imx219: Propagate errors from control range updates
Cheng Ming Lin <chengminglin@mxic.com.tw>
mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D
Maxi Saparov <masaparov@coreweave.com>
kho: do not reserve scratch memory in the kdump kernel
Eric Biggers <ebiggers@kernel.org>
lib/crypto: mips: Disable Octeon SHA code on little-endian kernels
Abhishek Dubey <adubey@linux.ibm.com>
powerpc/bpf: fix buffer overflow in JIT for large BPF programs
Zhao Gongyi <zhaogongyi@bytedance.com>
ata: libata-scsi: reject data-in commands with a data-out buffer
Michal Blaszczyk <michalblk@google.com>
sched_ext: Reset runnable_at when a task leaves its scheduler
Oliver Hartkopp <socketcan@hartkopp.net>
can: raw, isotp: copy socket options outside of lock_sock()
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: only update flags for TT events
Sven Eckelmann <sven@narfation.org>
batman-adv: tt: ignore ROAM flag of received ADD changes
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
Sven Eckelmann <sven@narfation.org>
batman-adv: tpmeter: fix u32 truncation of reported bytes
SJ Park <sj@kernel.org>
mm/damon/core: move static variable last_nr_regions to damon_ctx
Ido Schimmel <idosch@nvidia.com>
vxlan: Stop rejecting dynamic FDB entries with a nexthop ID
Daehyeon Ko <4ncienth@gmail.com>
timekeeping: Require permission to set auxiliary clocks
Hamid Nassiby <hamid.nassiby@nokia.com>
Revert "mm/page_owner: fix memory leak in page_owner_stack_fops->release()"
Guanglei Zhu <zhugl3@xiaopeng.com>
ceph: clamp the inline data length in ceph_fill_inline_data()
Oliver Hartkopp <socketcan@hartkopp.net>
can: protect the receive lists with a per-device lock
Oliver Hartkopp <socketcan@hartkopp.net>
can: replace ARPHRD_CAN type checks with can_get_ml_priv()
Sasha Levin <sashal@kernel.org>
Revert "hugetlb: remove VMEMMAP_SYNCHRONIZE_RCU"
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
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
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
Christian Gmeiner <cgmeiner@igalia.com>
drm/etnaviv: Flush the tile status cache through both the PE and BLT
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
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()
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: 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
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
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
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
Dariusz Marcinkiewicz <darekm@google.com>
drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify
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
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
Jamal Hadi Salim <jhs@mojatatu.com>
net/sched: clamp skb->queue_mapping before indexing the tx queue
Chris Mason <mason@kernel.org>
ovl: do not let chattr change the casefold flag
Xia Yan <yanxia@cmss.chinamobile.com>
ipv6: fix device binding after failed datagram connect
Samiullah Khawaja <skhawaja@google.com>
mm/gup: check folio->mapping under folio lock in memfd_pin_folios()
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
Chris Mason <mason@kernel.org>
mm/vma: call ->may_split() before a partial merge
David Hildenbrand (Arm) <david@kernel.org>
mm/ksm: reset the unstable trees of all nodes
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
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()
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: isotp: check the return values of can_rx_register() in isotp_bind()
Cunhao Lu <1579567540@qq.com>
can: dev: can_put_echo_skb(): free skb on invalid echo index
Kaixuan Li <kaixuanli0131@gmail.com>
can: isotp: check the frame type, not just the length
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: 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
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
Cen Zhang <zzzccc427@gmail.com>
ocfs2: keep locking_state within the cluster connection lifetime
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
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
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
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/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
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
Hungyu Lin <dennylin0707@gmail.com>
mm/page-writeback: avoid 32-bit overflow in dirty threshold shares
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
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
Daejun Park <daejun7.park@samsung.com>
nvme: unregister when pr_register() is given a zero new key
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) 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: (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: 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: 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
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
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
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
Hungyu Lin <dennylin0707@gmail.com>
ext2: preserve completed DIO bytes when buffered fallback fails
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/memfd: make f_pos accesses atomic
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 truncate loop after boundary swapin failure
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: grant a POSIX ACL group entry only to the group's members
Federico Musto <federico@rimpianto.com>
net: atl1c: drop oversized RX frames instead of panicking
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
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
Breno Leitao <leitao@debian.org>
x86/bugs: Select the BHI mitigation based on the attack vector properly
Miguel Ojeda <ojeda@kernel.org>
rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()`
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 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: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type()
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: 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
Kyle Zeng <kylebot@openai.com>
batman-adv: mcast: validate tracker padding before forwarding
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()
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()
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
Christian Brauner <brauner@kernel.org>
ns: don't add init_ipc_ns and init_net without namespace support
Noam D. Eliyahu <noam.d.eliyahu@gmail.com>
tg3: Invert restart quirk logic to restrict SNP power-down bypass
Zhiling Zou <zhilinz@nebusec.ai>
ipmr: drop packets with unknown ingress VIF
Ido Schimmel <idosch@nvidia.com>
ipmr, ip6mr: validate packets injected into the register vif on xmit
Peng Wang <peng_wang@linux.alibaba.com>
tick/nohz: Reevaluate the tick for kicks flushed outside hardirq
Hungyu Lin <dennylin0707@gmail.com>
posix-timers: Accept NULL clock_getres() output in stubs
Yingjie Wang <x-professor@outlook.com>
scsi: handle out-of-range SG_SET_TIMEOUT values
Stanley Jhu <stanleyjhu@google.com>
scsi: ufs: bsg: Reject UIC commands with a non-zero result byte
Stanley Jhu <stanleyjhu@google.com>
scsi: ufs: bsg: Validate request_len before accessing request
Daeho Jeong <daehojeong@google.com>
f2fs: don't use truncate_inode_pages_final() on live inodes
Sahaj Chaudhari <sahaj123.sc@gmail.com>
gpio: pca953x: Preserve wakeup accounting on parent IRQ failure
Henry Martin <bsdhenrymartin@gmail.com>
rds: fix out-of-bounds conn_path walks via handshake exthdrs
Yun Zhou <yun.zhou@windriver.com>
net: erspan: set lltx to avoid sch_direct_xmit deadlock
Donggeun Yoo <donggeunyoo.kernel@gmail.com>
tracing: Add the bucket size to expr_field_str()
Guixin Liu <kanie@linux.alibaba.com>
cxl/events: Test CME counter expiry with equality, not bitwise AND
Bui Viet Dung <dungvn2345@gmail.com>
Bluetooth: selftest: Pin module for selftest debugfs file operations
Guangshuo Li <lgs201920130244@gmail.com>
mfd: ab8500: Fix child device leaks on probe failure
Andrey Misiurov <andrey.misyrov@gmail.com>
fbdev: core: Initialize modelist in framebuffer_alloc()
Breno Leitao <leitao@debian.org>
ACPI: APEI: accumulate the queued flag across error sections
Ridong Chen <chenridong@xiaomi.com>
mm/page_counter: avoid integer overflow in effective_protection()
Devin Wittmayer <lucid_duck@justthetip.ca>
wifi: mt76: take rcu_read_lock in the USB/SDIO tx completion path
Fuad Tabba <fuad.tabba@linux.dev>
KVM: arm64: timers: Compute an offset-applied CVAL from the current count
Jiayuan Chen <jiayuan.chen@linux.dev>
mm/memcontrol: fix data-race on reading jiffies_64
Priyank Rathod <rathodpriyank@google.com>
PCI/AER: Fix memory leak in aer_recover_work_func() when pci_dev is missing
Kazuki Hanai <hnkz.64@gmail.com>
media: mediatek: jpeg: Avoid context access after job finish
Rupesh Majhi <zoone.rupert@gmail.com>
iio: pressure: dps310: fix CFG_REG bit definitions
Ridham Khurana <khurana.ridham222@gmail.com>
hwmon: (lm70) Fix rounding of negative temperatures
Ruoyu Wang <ruoyuw560@gmail.com>
media: adv748x: Fix endpoint reference leaks on probe failure
Pengpeng Hou <pengpeng@iscas.ac.cn>
media: require two-byte Cypress type 04 records
Balakrishnan Sambath <balakrishnan.s@microchip.com>
media: microchip-isc: fix WB offset and gain register field masking
SJ Park <sj@kernel.org>
mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once
Eric Sandeen <sandeen@redhat.com>
devtmpfs: restore mount option reconfiguration on get_tree
Ben Dooks <ben.dooks@codethink.co.uk>
devtmpfs: make 'devtmpfs_context_ops' static
Kiryl Shutsemau (Meta) <kas@kernel.org>
mm: page_alloc: make defrag_mode retries follow the promoted order
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: give the sysctl timer limits in milliseconds
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: swap the AX.25 connection of a neighbour under a lock
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: drop the neighbour reference once when a cleared socket is closed
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: report a timed out call to connect()
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: hold the socket a received frame is delivered to
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: hold the listener while a Call Request is queued on it
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: only update the BPQ extension flag on circuit set-up frames
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: disconnect sockets under their lock when a device goes down
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: don't send part of a message that cannot be fragmented whole
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: check the window size given by the peer
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: drop a frame received with a TTL of 0
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: keep the selected route when a route of a node is removed
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: return the peer node in the address given by recvmsg()
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: don't give the same circuit ID to two sockets
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: give a frame back intact when it cannot be delivered
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: use the more flag of each frame taken from the resequencing queue
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: don't leak frames in nr_route_frame()
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: don't convert the maximum number of tries to jiffies
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: don't let connect() find its own socket when calling the same station
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: let a socket connect again after a failed or ended connection
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: keep the window below 8 when a socket goes back to modulo 8
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: make 16 the smallest maximum_packet_length of a port
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: don't leave half a message on a connection when fragmenting fails
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: free the copy of an IP packet that ax25_send_frame() turned down
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: don't test the socket flags of a connection that has no socket
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: put an incoming connection on the listener's queue once it is set up
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: free the old digipeater path of a listed socket under ax25_list_lock
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: don't copy an uninitialised address to recvmsg()'s caller
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: don't take a reference on a gone device in ax25_accept()
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: don't build a frame header from an uninitialised digipeater list
Bernard Pidoux <bernard.f6bvp@gmail.com>
6pack: restart the transmit queue when the interface is opened
Bernard Pidoux <bernard.f6bvp@gmail.com>
mkiss: restart the transmit queue when the interface is opened
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: free a closed socket when its device goes down
Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25: don't create a second connection for a link on an incoming SABM
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: don't give the same LCI to two calls placed at the same time
Bernard Pidoux <bernard.f6bvp@gmail.com>
netrom: ignore a BPQ transport timeout below the sysctl minimum
Bernard Pidoux <bernard.f6bvp@gmail.com>
rose: arm the neighbour timers with mod_timer()
Bernard Pidoux <bernard.f6bvp@gmail.com>
bpqether: fix truncated /proc/net/bpqether on partial reads
Bernard Pidoux <bernard.f6bvp@gmail.com>
bpqether: leave the Ethernet device's queue and counters alone
Bernard Pidoux <bernard.f6bvp@gmail.com>
mkiss: don't use a tty write error as a byte count
Bernard Pidoux <bernard.f6bvp@gmail.com>
mkiss: size the frame buffers for worst-case KISS escaping
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
Stanislaw Gruszka <stf_xl@wp.pl>
wifi: mac80211: queue frames while off-channel
Denis Pauk <pauk.denis@gmail.com>
hwmon: (nct6775) Add ASUS X870/W480 to WMI monitoring list
Maximilian Luz <luzmaximilian@gmail.com>
hwmon: (nct6775) Add ASUS ROG STRIX X870E-H GAMING WIFI7
Yi Cong <yicong@kylinos.cn>
wifi: mt76: mt792x: fix negative errno truncation in offload capability
Marek Vasut <marek.vasut+renesas@mailbox.org>
PCI: rcar-gen4: Limit Max_Read_Request_Size to 256 Bytes
Christian Borntraeger <borntraeger@linux.ibm.com>
s390/vmcp: Initialize full session info to zero
Jeff Layton <jlayton@kernel.org>
nfsd: shorten extack string returned with dodgy listener
Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
ksmbd: fix tree connection use-after-free in smb2_tree_connect()
Rosen Penev <rosenp@gmail.com>
net: bgmac: enable interrupts only after NAPI is ready
Rosen Penev <rosenp@gmail.com>
mtd: rawnand: ndfc: use devm_platform_ioremap_resource()
Rosen Penev <rosenp@gmail.com>
mtd: rawnand: ndfc: fix gcc uninitialized var
Arnd Bergmann <arnd@arndb.de>
mtd: rawnand: ndfc: add CONFIG_OF dependency
Rosen Penev <rosenp@gmail.com>
mtd: rawnand: ndfc: use ioread32be/iowrite32be and allow COMPILE_TEST
Eric Biggers <ebiggers@kernel.org>
raid6: add missing vzeroupper to AVX2 code
Diego Oliva <diego@bynar.io>
smb: client: reject FIND data areas that run past the received response
Paulo Alcantara <pc@manguebit.org>
smb: client: reclaim credits for decrypted reads with no matching mid
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
Qingfang Deng <qingfang.deng@linux.dev>
pppoe: delete session hash entries by pointer match
Liz Fong-Jones <lizf@honeycomb.io>
writeback: keep cleanup_offline_cgwb()'s scan out of syncs
Christian Loehle <christian.loehle@arm.com>
ACPI: CPPC: Accept requests to retain immutable autonomous selection
Christian Loehle <christian.loehle@arm.com>
ACPI: CPPC: Propagate errors from cross-CPU FFH calls
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
FUJITA Tomonori <fujita.tomonori@gmail.com>
rust: bug: update the SAFETY comment for warn_slowpath_fmt() on UML
FUJITA Tomonori <fujita.tomonori@gmail.com>
rust: bug: pass TAINT_WARN to warn_slowpath_fmt() on UML
SJ Park <sj@kernel.org>
mm/damon/core: filter out damos address filter-split failed region
SJ Park <sj@kernel.org>
mm/damon/core: remove unreachable damos charge_{target,addr}_from
SJ Park <sj@kernel.org>
mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total
SJ Park <sj@kernel.org>
mm/damon/core: skip applying scheme if region split for quota fails
Eric Biggers <ebiggers@kernel.org>
raid6: add missing vzeroupper to AVX-512 code
Eric Biggers <ebiggers@kernel.org>
xor: add missing vzeroupper to AVX code
Eric Biggers <ebiggers@kernel.org>
fsverity: Explicitly require FMODE_READ to retrieve hashes
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
Til Kaiser <mail@tk154.de>
mlxsw: Initialize register query payloads
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
Xiaoyao Li <xiaoyao.li@intel.com>
KVM: TDX: Don't assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason()
Xiaoyao Li <xiaoyao.li@intel.com>
KVM: TDX: Set bits 31:16 to 0 and use UNDEFINED when synthesizing exit reason
Xiaoyao Li <xiaoyao.li@intel.com>
KVM: TDX: Stuff exit_reason with UNDEFINED on wait_for_sept_zap return
Shivank Garg <shivankg@amd.com>
KVM: guest_memfd: take the invalidate lock when unbinding a dying file
Sean Christopherson <seanjc@google.com>
KVM: Only bind memslot to guest_memfd instance for CREATE operations
Sean Christopherson <seanjc@google.com>
KVM: Harden and prepare for modifying existing guest_memfd memslots
Sean Christopherson <seanjc@google.com>
KVM: nSVM: Reject KVM_SET_NESTED_STATE if L1 has EFER.LMA=1 && EFER.LME=0
Chuck Lever <chuck.lever@oracle.com>
NFSD: Complete a cld upcall when copying its reply fails
Chuck Lever <chuck.lever@oracle.com>
NFSD: Complete a cld upcall when the daemon closes the pipe
Chuck Lever <chuck.lever@oracle.com>
NFSD: Move the cld upcall message out of the caller's stack frame
Chuck Lever <chuck.lever@oracle.com>
NFSD: Send a meaningful CB_RECALL_ANY keep count
Chuck Lever <chuck.lever@oracle.com>
NFSD: Count the delegations held by each client
Mike Snitzer <snitzer@kernel.org>
NFS/localio: detect a short read or write before the iterator has moved
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
Jeff Layton <jlayton@kernel.org>
nfsd: don't offer flexfiles layouts when NFSv3 isn't being served
Christoph Hellwig <hch@lst.de>
exportfs,nfsd: rework checking for layout-based block device access support
Christoph Hellwig <hch@lst.de>
exportfs: split out the ops for layout-based block device access
André Almeida <andrealmeid@igalia.com>
exportfs: Complete kernel-doc for struct export_operations
Sergey Bashirov <sergeybashirov@gmail.com>
NFSD/blocklayout: Extract extent mapping from proc_layoutget
Chuck Lever <chuck.lever@oracle.com>
NFSD: map fh_verify() status codes for NFS_ACLv2 replies
Chuck Lever <chuck.lever@oracle.com>
NFSD: Move version-specific ACCESS maps into per-version code
Chuck Lever <chuck.lever@oracle.com>
NFSD: Replace nfsd_write()'s "stable" argument with "iocb_flags"
Bharath SM <bharathsm@microsoft.com>
smb: align durable reconnect v2 context to 8 byte boundary
Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
smb: client: bound POSIX lock data area by response length
Benjamin Coddington <ben.coddington@hammerspace.com>
NFSv4/pnfs: bound the CB_NOTIFY_DEVICEID array count before allocating
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
Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
smb: client: validate SMB1 EA list bounds before parsing
Zhaoyang Huang <zhaoyang.huang@unisoc.com>
mm: remove '!root_reclaim' checking in should_abort_scan()
Paulo Alcantara <pc@manguebit.org>
smb: client: require stable pages for SMB compression
Abdifatah Suruur <suruurism@gmail.com>
smb: client: reject short SESSION_SETUP responses
Diego Oliva <diego@bynar.io>
smb: client: fix OOB read in the SMB_FIND_FILE_UNIX name scan
Diego Oliva <diego@bynar.io>
smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2
ChenXiaoSong <chenxiaosong@kylinos.cn>
smb: move some duplicate struct definitions to common/fscc.h
ChenXiaoSong <chenxiaosong@kylinos.cn>
smb: move list of FileSystemAttributes to common/fscc.h
ZhangGuoDong <zhangguodong@kylinos.cn>
smb: move some duplicate definitions to common/smb2pdu.h
ChenXiaoSong <chenxiaosong@kylinos.cn>
smb: move create_durable_rsp_v2 to common/smb2pdu.h
ChenXiaoSong <chenxiaosong@kylinos.cn>
smb: move create_durable_handle_reconnect_v2 to common/smb2pdu.h
ChenXiaoSong <chenxiaosong@kylinos.cn>
smb: move create_durable_req_v2 to common/smb2pdu.h
ZhangGuoDong <zhangguodong@kylinos.cn>
smb: move smb_sockaddr_in and smb_sockaddr_in6 to common/smb2pdu.h
Eduard Zateev <hackerowskiy@gmail.com>
smb: client: hold server info until cifsd exits
Thomas Huth <thuth@redhat.com>
smb: client: Avoid leaking sensitive data to the heap in connect.c
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
Eric Biggers <ebiggers@kernel.org>
fsverity: Tell LSMs about signature only after verity is enabled
Eric Biggers <ebiggers@kernel.org>
crypto: sa2ul - Fix HMAC key preparation
Andrew Stellman <astellman@stellman-greene.com>
nvmet-rdma: fix out-of-bounds write in nvmet_rdma_map_sgl_inline()
Chris Mason <mason@kernel.org>
backing-file: always end a queued write
Ashok Raj <ashok.raj@oss.qualcomm.com>
cxl/features: Ensure that count is set before access to ent[] __counted_by()
Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
ALSA: x86: hdmi: fix chmap array missing terminator entry
Abdifatah Suruur <suruurism@gmail.com>
smb: client: validate the data area in SMB2_read()
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.rst | 97 +--
Documentation/admin-guide/kernel-parameters.txt | 109 +++
Documentation/filesystems/fsverity.rst | 3 +
Documentation/filesystems/overlayfs.rst | 3 +-
Documentation/filesystems/resctrl.rst | 87 +-
Documentation/hwmon/coretemp.rst | 3 +
MAINTAINERS | 2 +-
Makefile | 4 +-
arch/arm64/Kconfig | 1 +
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/process.c | 17 +
arch/arm64/kernel/sdei.c | 59 +-
arch/arm64/kernel/topology.c | 13 +-
arch/arm64/kvm/arch_timer.c | 27 +-
arch/arm64/kvm/arm.c | 4 +-
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 28 +-
arch/arm64/kvm/hyp/vhe/switch.c | 11 +-
arch/arm64/kvm/mmu.c | 4 +-
arch/arm64/kvm/nested.c | 10 +
arch/arm64/kvm/ptdump.c | 50 +-
arch/arm64/kvm/vgic/vgic-mmio-v3.c | 10 +
arch/arm64/kvm/vgic/vgic.c | 11 +-
arch/arm64/mm/mmap.c | 4 +-
arch/arm64/mm/proc.S | 8 +
arch/loongarch/include/asm/hw_breakpoint.h | 4 +-
arch/loongarch/include/asm/loongarch.h | 3 +
arch/loongarch/include/asm/processor.h | 1 +
arch/loongarch/include/asm/switch_to.h | 2 +-
arch/loongarch/kernel/hw_breakpoint.c | 39 +-
arch/loongarch/kernel/numa.c | 8 +-
arch/m68k/68000/entry.S | 24 +-
arch/m68k/coldfire/entry.S | 3 +-
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/powerpc/net/bpf_jit.h | 7 +
arch/powerpc/net/bpf_jit_comp.c | 35 +-
arch/powerpc/platforms/pseries/iommu.c | 67 +-
arch/s390/pci/pci_irq.c | 26 +-
arch/x86/boot/startup/sme.c | 2 +-
arch/x86/include/asm/vmware.h | 24 +-
arch/x86/include/asm/xor_avx.h | 4 +
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/svm/nested.c | 1 +
arch/x86/kvm/vmx/nested.c | 1 +
arch/x86/kvm/vmx/tdx.c | 42 +-
arch/x86/kvm/x86.c | 33 +-
arch/x86/mm/tlb.c | 16 +-
block/blk-iocost.c | 3 +
block/blk-mq.c | 17 +-
block/bsg.c | 5 +-
block/ioctl.c | 4 +-
drivers/acpi/apei/ghes.c | 6 +-
drivers/acpi/cppc_acpi.c | 58 +-
drivers/acpi/riscv/cppc.c | 26 +-
drivers/ata/Kconfig | 7 -
drivers/ata/Makefile | 1 -
drivers/ata/libata-eh.c | 6 +-
drivers/ata/libata-pmp.c | 16 +-
drivers/ata/libata-scsi.c | 25 +
drivers/ata/libata.h | 4 +-
drivers/ata/sata_inic162x.c | 902 ---------------------
drivers/base/devtmpfs.c | 108 ++-
drivers/block/ublk_drv.c | 60 +-
drivers/block/virtio_blk.c | 2 +-
drivers/bluetooth/btqca.c | 3 +-
drivers/char/hw_random/virtio-rng.c | 7 +
drivers/char/tpm/tpm2-cmd.c | 3 +-
drivers/clk/nuvoton/clk-ma35d1.c | 7 +-
drivers/cpufreq/amd-pstate.c | 25 +-
drivers/crypto/omap-sham.c | 28 +-
drivers/crypto/sa2ul.c | 119 +--
drivers/cxl/core/features.c | 2 +-
drivers/cxl/core/mbox.c | 8 +-
drivers/cxl/core/port.c | 60 +-
drivers/dma/qcom/bam_dma.c | 10 +-
drivers/gpio/gpio-pca953x.c | 7 +-
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 | 11 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c | 16 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 13 +-
drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c | 5 +
drivers/gpu/drm/amd/amdgpu/amdgpu_sync.c | 4 +-
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 +-
.../amd/display/dc/clk_mgr/dcn401/dcn401_clk_mgr.c | 3 +
.../display/dc/link/protocols/link_dp_capability.c | 6 +-
.../gpu/drm/amd/display/dc/optc/dcn20/dcn20_optc.c | 7 +
.../amd/display/dc/resource/dcn32/dcn32_resource.c | 15 +-
.../drm/amd/display/modules/freesync/freesync.c | 6 +-
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 2 +
.../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 35 +-
.../gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 32 +-
.../gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 38 +-
drivers/gpu/drm/bridge/nwl-dsi.c | 17 +-
drivers/gpu/drm/display/drm_dp_helper.c | 3 +-
drivers/gpu/drm/drm_crtc.c | 15 +-
drivers/gpu/drm/drm_panic.c | 7 +-
drivers/gpu/drm/etnaviv/etnaviv_buffer.c | 40 +-
.../gpu/drm/i915/display/intel_display_device.c | 5 +-
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/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/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_wmi_sensors.c | 13 +-
drivers/hwmon/chipcap2.c | 53 +-
drivers/hwmon/coretemp.c | 27 +-
drivers/hwmon/corsair-cpro.c | 3 +-
drivers/hwmon/gpio-fan.c | 7 +-
drivers/hwmon/hp-wmi-sensors.c | 29 +-
drivers/hwmon/lm70.c | 8 +-
drivers/hwmon/lm87.c | 7 +-
drivers/hwmon/nct6683.c | 4 +-
drivers/hwmon/nct6775-platform.c | 24 +
drivers/hwmon/peci/dimmtemp.c | 21 +-
drivers/hwmon/pmbus/pmbus_core.c | 51 +-
drivers/hwmon/pmbus/q54sj108a2.c | 2 +
drivers/hwmon/sht4x.c | 4 +-
drivers/hwmon/tmp102.c | 8 +-
drivers/hwmon/tmp108.c | 8 +-
drivers/iio/adc/ad4080.c | 3 +-
drivers/iio/adc/ad7192.c | 2 +-
drivers/iio/dac/mcp4821.c | 7 +-
drivers/iio/light/adux1020.c | 4 +-
drivers/iio/light/apds9160.c | 7 +-
drivers/iio/light/apds9300.c | 4 +-
drivers/iio/light/apds9306.c | 3 +-
drivers/iio/light/apds9960.c | 4 +-
drivers/iio/light/bh1745.c | 3 +-
drivers/iio/light/cm3605.c | 4 +-
drivers/iio/light/gp2ap002.c | 4 +-
drivers/iio/light/isl29028.c | 43 +-
drivers/iio/light/ltr390.c | 3 +-
drivers/iio/light/ltr501.c | 7 +-
drivers/iio/light/opt4060.c | 2 +-
drivers/iio/light/rpr0521.c | 5 +-
drivers/iio/light/si1145.c | 4 +-
drivers/iio/light/st_uvis25_core.c | 5 +-
drivers/iio/light/stk3310.c | 5 +-
drivers/iio/light/tsl2563.c | 2 +-
drivers/iio/light/tsl2772.c | 5 +-
drivers/iio/light/veml6030.c | 4 +-
drivers/iio/light/vl6180.c | 2 +-
drivers/iio/pressure/dps310.c | 6 +-
drivers/iommu/amd/init.c | 41 +-
drivers/iommu/iommufd/io_pagetable.c | 2 +-
drivers/iommu/iommufd/iova_bitmap.c | 18 +-
drivers/iommu/virtio-iommu.c | 6 +-
drivers/irqchip/irq-renesas-rzv2h.c | 6 +-
drivers/media/common/cypress_firmware.c | 2 +
drivers/media/i2c/adv748x/adv748x-core.c | 13 +-
drivers/media/i2c/imx219.c | 88 +-
drivers/media/i2c/og01a1b.c | 97 +--
drivers/media/i2c/ov5647.c | 4 +
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/mediatek/jpeg/mtk_jpeg_core.c | 4 +-
.../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/platform/qcom/iris/iris_core.h | 6 +
drivers/media/platform/qcom/iris/iris_probe.c | 62 +-
drivers/media/platform/qcom/iris/iris_vpu_common.c | 2 +-
drivers/media/platform/rockchip/rga/rga.c | 69 +-
drivers/media/platform/rockchip/rga/rga.h | 7 +-
drivers/media/rc/redrat3.c | 11 +-
drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 2 +
drivers/media/usb/uvc/uvc_driver.c | 20 +
drivers/mfd/ab8500-core.c | 44 +-
drivers/mfd/twl-core.c | 25 +-
drivers/misc/fastrpc.c | 81 +-
drivers/mtd/nand/raw/Kconfig | 3 +-
drivers/mtd/nand/raw/ndfc.c | 41 +-
drivers/mtd/spi-nor/macronix.c | 2 +
drivers/net/can/dev/netlink.c | 4 +-
drivers/net/can/dev/skb.c | 1 +
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 7 +-
drivers/net/ethernet/atheros/atl1c/atl1c_main.c | 33 +
drivers/net/ethernet/broadcom/bgmac.c | 10 +-
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 53 +-
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 +
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 5 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 52 +-
drivers/net/ethernet/broadcom/tg3.c | 42 +-
drivers/net/ethernet/jme.c | 37 +-
drivers/net/ethernet/jme.h | 1 +
drivers/net/ethernet/mellanox/mlxsw/core.c | 4 +-
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 4 +-
.../net/ethernet/mellanox/mlxsw/spectrum_span.c | 2 +-
drivers/net/ethernet/ti/am65-cpsw-nuss.c | 4 +-
drivers/net/hamradio/6pack.c | 6 +
drivers/net/hamradio/bpqether.c | 8 +-
drivers/net/hamradio/mkiss.c | 70 +-
drivers/net/ppp/pppoe.c | 22 +-
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/mediatek/mt76/mac80211.c | 14 +
drivers/net/wireless/mediatek/mt76/mt76.h | 2 +
drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 3 +
drivers/net/wireless/mediatek/mt76/mt7921/main.c | 7 +-
drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 3 +
drivers/net/wireless/mediatek/mt76/mt7925/main.c | 2 +
drivers/net/wireless/mediatek/mt76/mt792x_core.c | 12 +-
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 | 3 +-
drivers/nvme/host/pci.c | 2 +
drivers/nvme/host/pr.c | 8 +-
drivers/nvme/host/tcp.c | 196 ++++-
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/nvme/target/rdma.c | 3 +-
drivers/nvme/target/tcp.c | 26 +-
drivers/nvmem/rockchip-otp.c | 24 +-
drivers/pci/controller/cadence/pcie-cadence-plat.c | 33 +-
drivers/pci/controller/dwc/pci-imx6.c | 2 +-
drivers/pci/controller/dwc/pcie-designware.c | 2 +
drivers/pci/controller/dwc/pcie-designware.h | 1 +
drivers/pci/controller/dwc/pcie-rcar-gen4.c | 54 ++
drivers/pci/endpoint/functions/pci-epf-vntb.c | 69 +-
drivers/pci/pcie/aer.c | 23 +-
drivers/platform/x86/amd/pmf/core.c | 1 +
drivers/platform/x86/asus-wmi.c | 30 +-
drivers/platform/x86/intel/int3472/discrete.c | 53 +-
drivers/platform/x86/lenovo/Kconfig | 4 +-
drivers/platform/x86/lenovo/Makefile | 2 +-
.../x86/lenovo/{wmi-capdata01.c => wmi-capdata.c} | 142 ++--
.../x86/lenovo/{wmi-capdata01.h => wmi-capdata.h} | 10 +-
drivers/platform/x86/lenovo/wmi-other.c | 11 +-
drivers/power/supply/ltc2941-battery-gauge.c | 6 +-
drivers/ptp/ptp_sysfs.c | 6 +-
drivers/s390/char/vmcp.c | 4 +-
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 | 6 +-
drivers/scsi/scsi_ioctl.c | 11 +-
drivers/soc/qcom/pmic_glink_altmode.c | 4 +-
drivers/spi/atmel-quadspi.c | 34 +-
drivers/spi/spi-cadence-xspi.c | 522 ++++++------
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 +
drivers/tty/serial/sc16is7xx.c | 14 +-
drivers/ufs/core/ufs_bsg.c | 13 +
drivers/ufs/core/ufshcd.c | 48 +-
drivers/vdpa/solidrun/snet_ctrl.c | 3 +-
drivers/vdpa/vdpa_user/iova_domain.c | 11 +-
drivers/vfio/pci/vfio_pci_rdwr.c | 3 -
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 +-
drivers/video/fbdev/core/fb_info.c | 1 +
drivers/video/fbdev/core/fbcon_rotate.c | 3 +-
drivers/video/fbdev/nvidia/nvidia.c | 20 +-
drivers/video/fbdev/sh_mobile_lcdcfb.c | 34 +-
drivers/watchdog/hpwdt.c | 24 +-
drivers/xen/gntdev-dmabuf.c | 4 +-
fs/9p/v9fs.c | 16 +-
fs/9p/vfs_inode.c | 8 +
fs/backing-file.c | 5 +-
fs/btrfs/sysfs.c | 1 +
fs/buffer.c | 29 -
fs/ceph/addr.c | 6 +
fs/ceph/crypto.c | 8 +
fs/dcache.c | 4 +
fs/erofs/zdata.c | 11 +-
fs/exfat/file.c | 18 +-
fs/ext2/file.c | 3 +-
fs/ext2/inode.c | 13 +-
fs/f2fs/checkpoint.c | 13 +-
fs/f2fs/data.c | 25 +-
fs/f2fs/f2fs.h | 8 +-
fs/f2fs/file.c | 2 +-
fs/f2fs/gc.c | 2 +-
fs/f2fs/node.c | 71 +-
fs/f2fs/segment.c | 3 +-
fs/f2fs/super.c | 24 +
fs/fat/inode.c | 2 +
fs/fs-writeback.c | 13 +-
fs/fuse/virtio_fs.c | 59 +-
fs/gfs2/glops.c | 10 +-
fs/inode.c | 51 +-
fs/iomap/buffered-io.c | 3 +-
fs/iomap/direct-io.c | 56 +-
fs/nfs/callback_xdr.c | 7 +
fs/nfs/localio.c | 12 +-
fs/nfsd/blocklayout.c | 125 +--
fs/nfsd/export.c | 3 +-
fs/nfsd/nfs2acl.c | 64 +-
fs/nfsd/nfs3proc.c | 58 +-
fs/nfsd/nfs3xdr.c | 2 +
fs/nfsd/nfs4layouts.c | 31 +-
fs/nfsd/nfs4proc.c | 60 +-
fs/nfsd/nfs4recover.c | 49 +-
fs/nfsd/nfs4state.c | 21 +-
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/ntfs3/xattr.c | 25 +-
fs/ocfs2/alloc.c | 20 +-
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/super.c | 3 +
fs/ocfs2/xattr.c | 120 ++-
fs/overlayfs/export.c | 4 +-
fs/overlayfs/inode.c | 8 +
fs/overlayfs/namei.c | 13 +-
fs/overlayfs/overlayfs.h | 2 +-
fs/overlayfs/super.c | 12 +-
fs/proc/task_mmu.c | 2 +-
fs/smb/client/cifsglob.h | 3 +
fs/smb/client/cifspdu.h | 253 +-----
fs/smb/client/cifsproto.h | 1 +
fs/smb/client/cifssmb.c | 65 +-
fs/smb/client/connect.c | 36 +-
fs/smb/client/inode.c | 8 +-
fs/smb/client/readdir.c | 68 +-
fs/smb/client/smb2misc.c | 15 +
fs/smb/client/smb2ops.c | 14 +-
fs/smb/client/smb2pdu.c | 57 +-
fs/smb/client/smb2pdu.h | 82 --
fs/smb/client/trace.h | 1 +
fs/smb/common/fscc.h | 157 ++++
fs/smb/common/smb2pdu.h | 230 +++++-
fs/smb/server/mgmt/tree_connect.c | 8 +
fs/smb/server/oplock.c | 8 +-
fs/smb/server/smb2ops.c | 6 +-
fs/smb/server/smb2pdu.c | 162 ++--
fs/smb/server/smb2pdu.h | 69 --
fs/smb/server/smb_common.h | 195 +----
fs/smb/server/smbacl.c | 5 +-
fs/smb/server/vfs.c | 6 +-
fs/smb/server/vfs.h | 2 +
fs/udf/balloc.c | 11 +-
fs/udf/inode.c | 42 +-
fs/udf/super.c | 80 +-
fs/udf/truncate.c | 7 +-
fs/verity/enable.c | 8 +
fs/verity/fsverity_private.h | 8 +
fs/verity/measure.c | 10 +
fs/verity/open.c | 9 +
fs/verity/read_metadata.c | 14 +-
fs/verity/signature.c | 55 +-
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/scrub/xfarray.c | 69 +-
fs/xfs/xfs_aops.c | 2 +-
fs/xfs/xfs_discard.c | 26 +-
fs/xfs/xfs_export.c | 4 +-
fs/xfs/xfs_ioctl32.c | 4 +-
fs/xfs/xfs_iomap.c | 8 +
fs/xfs/xfs_pnfs.c | 76 +-
fs/xfs/xfs_pnfs.h | 11 +-
include/acpi/cppc_acpi.h | 6 +
include/asm-generic/tlb.h | 3 +-
include/dt-bindings/clock/nuvoton,ma35d1-clk.h | 3 +-
include/kvm/arm_arch_timer.h | 15 +
include/linux/backing-dev.h | 5 +-
include/linux/bio.h | 15 +
include/linux/buffer_head.h | 3 -
include/linux/can/can-ml.h | 3 +
include/linux/cgroup.h | 65 +-
include/linux/damon.h | 6 +
include/linux/exportfs.h | 22 +-
include/linux/exportfs_block.h | 89 ++
include/linux/fb.h | 9 +
include/linux/fs.h | 78 +-
include/linux/hugetlb.h | 24 +-
include/linux/memcontrol.h | 26 +-
include/linux/memfd.h | 9 +
include/linux/migrate.h | 8 +-
include/linux/mmu_notifier.h | 3 +-
include/linux/nfs4.h | 6 +
include/linux/page_owner.h | 7 +-
include/linux/pagemap.h | 11 +
include/linux/panic.h | 3 +-
include/linux/rculist_nulls.h | 59 ++
include/linux/srcu.h | 36 +
include/linux/sunrpc/clnt.h | 3 +-
include/linux/sunrpc/svc.h | 7 +-
include/linux/writeback.h | 4 +
include/net/espintcp.h | 5 +-
include/net/netns/can.h | 2 +-
include/net/netrom.h | 15 +-
include/net/rose.h | 3 +
include/net/sctp/sm.h | 1 +
include/sound/hwdep.h | 1 +
include/trace/events/migrate.h | 8 +-
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 +-
ipc/namespace.c | 7 +
ipc/shm.c | 2 -
kernel/cgroup/cgroup-internal.h | 6 -
kernel/cgroup/cgroup.c | 55 --
kernel/events/core.c | 9 +
kernel/kexec_handover.c | 7 +
kernel/panic.c | 10 +-
kernel/sched/ext.c | 14 +-
kernel/time/posix-stubs.c | 4 +-
kernel/time/posix-timers.c | 41 +-
kernel/time/tick-sched.c | 14 +-
kernel/time/timekeeping.c | 5 +
kernel/trace/trace_events_hist.c | 3 +
lib/cmdline.c | 13 +-
lib/crypto/Kconfig | 6 +-
lib/raid6/avx2.c | 6 +
lib/raid6/avx512.c | 6 +
lib/raid6/recov_avx2.c | 2 +
lib/raid6/recov_avx512.c | 2 +
lib/tests/cmdline_kunit.c | 101 +++
mm/cma.c | 4 +
mm/damon/core.c | 68 +-
mm/damon/sysfs-schemes.c | 8 +-
mm/damon/tests/core-kunit.h | 16 +-
mm/filemap.c | 55 +-
mm/gup.c | 68 +-
mm/huge_memory.c | 72 +-
mm/hugetlb.c | 133 ++-
mm/hugetlb_vmemmap.c | 20 +-
mm/internal.h | 2 +
mm/khugepaged.c | 29 +-
mm/ksm.c | 10 +-
mm/madvise.c | 9 +
mm/memcontrol.c | 111 ++-
mm/memfd.c | 33 +-
mm/memory-tiers.c | 29 +-
mm/memory.c | 77 +-
mm/mempolicy.c | 15 +-
mm/migrate.c | 17 +-
mm/mm_init.c | 2 -
mm/mmu_notifier.c | 24 +-
mm/mremap.c | 22 +-
mm/page-writeback.c | 8 +-
mm/page_alloc.c | 71 +-
mm/page_counter.c | 21 +-
mm/page_owner.c | 4 +-
mm/page_vma_mapped.c | 22 +-
mm/shmem.c | 109 ++-
mm/shmem_quota.c | 28 +-
mm/swapfile.c | 4 +-
mm/userfaultfd.c | 5 +-
mm/vma.c | 65 +-
mm/vmscan.c | 16 +-
net/9p/trans_usbg.c | 91 ++-
net/9p/trans_virtio.c | 5 +
net/9p/trans_xen.c | 10 +
net/ax25/af_ax25.c | 119 ++-
net/ax25/ax25_ds_timer.c | 2 +-
net/ax25/ax25_in.c | 56 +-
net/ax25/ax25_ip.c | 9 +-
net/ax25/ax25_out.c | 17 +-
net/ax25/ax25_std_timer.c | 2 +-
net/ax25/sysctl_net_ax25.c | 2 +-
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 | 134 ++-
net/batman-adv/types.h | 8 +-
net/bluetooth/hci_sync.c | 25 +-
net/bluetooth/l2cap_core.c | 47 +-
net/bluetooth/selftest.c | 1 +
net/bluetooth/smp.c | 1 +
net/can/af_can.c | 53 +-
net/can/bcm.c | 50 +-
net/can/gw.c | 7 +-
net/can/isotp.c | 236 +++---
net/can/proc.c | 69 +-
net/can/raw.c | 282 ++++---
net/core/filter.c | 23 +-
net/core/net_namespace.c | 4 +-
net/core/sock.c | 6 +-
net/ipv4/cipso_ipv4.c | 9 +-
net/ipv4/inet_connection_sock.c | 6 +-
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/inet_timewait_sock.c | 4 +-
net/ipv4/ip_gre.c | 1 +
net/ipv4/ipmr.c | 28 +-
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/ip6_gre.c | 1 +
net/ipv6/ip6mr.c | 5 +-
net/ipv6/raw.c | 3 +
net/l2tp/l2tp_core.c | 13 +-
net/mac80211/tdls.c | 3 +-
net/mac80211/tx.c | 57 +-
net/mptcp/pm_kernel.c | 1 +
net/mptcp/protocol.c | 31 +-
net/mptcp/protocol.h | 4 +-
net/mptcp/subflow.c | 17 +-
net/mptcp/token.c | 68 +-
net/mptcp/token_test.c | 4 +-
net/netrom/af_netrom.c | 109 ++-
net/netrom/nr_in.c | 50 +-
net/netrom/nr_out.c | 23 +-
net/netrom/nr_route.c | 100 +--
net/rds/recv.c | 6 +-
net/rose/af_rose.c | 130 ++-
net/rose/rose_in.c | 11 +-
net/rose/rose_link.c | 85 +-
net/rose/rose_loopback.c | 1 +
net/rose/rose_route.c | 67 +-
net/rose/sysctl_net_rose.c | 13 +-
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/bug.rs | 12 +-
rust/kernel/cpufreq.rs | 4 +-
sound/core/compress_offload.c | 18 +-
sound/core/control.c | 19 +-
sound/core/hwdep.c | 25 +-
sound/core/init.c | 23 +-
sound/core/jack.c | 38 +-
sound/core/oss/mixer_oss.c | 13 +-
sound/core/oss/pcm_oss.c | 21 +-
sound/core/pcm_native.c | 44 +-
sound/core/rawmidi.c | 16 +-
sound/core/seq/oss/seq_oss.c | 21 +-
sound/core/seq/seq_clientmgr.c | 19 +-
sound/core/sound.c | 9 +-
sound/core/timer.c | 26 +-
sound/core/timer_compat.c | 1 +
sound/core/ump_convert.c | 2 +-
sound/hda/codecs/realtek/alc269.c | 124 ++-
sound/hda/codecs/side-codecs/cs35l41_hda.c | 22 +-
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/acp-config.c | 43 +-
sound/soc/amd/yc/acp6x-mach.c | 7 +
sound/soc/codecs/hdac_hda.c | 25 +-
sound/soc/qcom/qdsp6/q6apm-dai.c | 12 +-
sound/soc/qcom/qdsp6/q6apm.c | 6 +-
sound/soc/qcom/qdsp6/q6prm.c | 3 +
sound/soc/sof/intel/hda-codec.c | 23 +-
sound/soc/stm/stm32_i2s.c | 27 +-
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/misc/ua101.c | 29 +-
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 +-
sound/x86/intel_hdmi_audio.c | 9 +-
tools/perf/tests/tool_pmu.c | 79 ++
tools/perf/util/evsel.c | 30 +-
tools/perf/util/hwmon_pmu.c | 2 +-
tools/perf/util/python.c | 2 +
tools/perf/util/tool_pmu.c | 2 +-
tools/testing/selftests/landlock/audit_test.c | 2 +-
tools/testing/selftests/landlock/net_test.c | 4 +-
tools/testing/selftests/landlock/ptrace_test.c | 2 +-
tools/testing/selftests/net/fib_nexthops.sh | 40 +-
tools/testing/vma/vma_internal.h | 2 +
virt/kvm/guest_memfd.c | 125 ++-
virt/kvm/kvm_main.c | 45 +-
virt/kvm/kvm_mm.h | 18 +-
645 files changed, 10332 insertions(+), 5997 deletions(-)
^ permalink raw reply [flat|nested] 687+ messages in thread
* [PATCH 6.18 001/686] smb: client: validate the data area in SMB2_read()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 002/686] ALSA: x86: hdmi: fix chmap array missing terminator entry Greg Kroah-Hartman
` (684 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Abdifatah Suruur, Namjae Jeon,
Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdifatah Suruur <suruurism@gmail.com>
[ Upstream commit 2ec9cdf469dd32bcf33073aeb30c08e9356e0ca1 ]
SMB2_read() copies le32_to_cpu(rsp->DataLength) bytes from
(char *)rsp + rsp->DataOffset without checking that the range lies
within the response actually received. A READ response with
DataOffset == 0 makes smb2_get_data_area_len() zero the data length, so
smb2_check_message() accepts a frame as short as the fixed response,
while SMB2_read() still uses the server-supplied DataLength, capped only
by CIFS_MAX_MSGSIZE and the caller's length.
A malicious server can answer the synchronous read used by the
mfsymlinks (or SFU) symlink parser with an 81-byte READ response
carrying DataOffset 0 and DataLength 1067, making the client copy 1067
bytes from a 448-byte receive object (KASAN slab-out-of-bounds; up to
16 KiB in the general case).
Clamp a zero (or header-overlapping) DataOffset to read_rsp_size, as
handle_read_data() does for the asynchronous path, and reject the
response unless DataOffset + DataLength fits within rsp_iov.iov_len.
The SMB1 helper was fixed the same way in 5be5bdda5863.
Fixes: d8e050398d23 ("CIFS: Add readpage support for SMB2")
Cc: stable@vger.kernel.org
Signed-off-by: Abdifatah Suruur <suruurism@gmail.com>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ sashal: Replaced the smb_EIO2() call with -EIO because smb_eio_trace_read_bad_offset is unavailable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2pdu.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 6d610f136f43e..5185f8cc8bcc8 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -4839,6 +4839,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
struct kvec iov[1];
struct kvec rsp_iov;
unsigned int total_len;
+ u16 data_offset;
int flags = CIFS_LOG_ERROR;
struct cifs_ses *ses = io_parms->tcon->ses;
@@ -4897,8 +4898,28 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
*nbytes = 0;
}
+ data_offset = rsp->DataOffset;
+ if (data_offset < io_parms->server->vals->read_rsp_size) {
+ /*
+ * win2k8 sometimes sends an offset of 0 when the read is beyond
+ * the EOF. Treat it as if the data starts just after the header,
+ * as handle_read_data() does.
+ */
+ cifs_dbg(FYI, "data offset %u inside read response header\n",
+ data_offset);
+ data_offset = io_parms->server->vals->read_rsp_size;
+ }
+
+ /* The data area must lie within the response actually received */
+ if (*nbytes && (size_t)data_offset + *nbytes > rsp_iov.iov_len) {
+ cifs_dbg(FYI, "bad data offset %u length %u for response of %zu\n",
+ data_offset, *nbytes, rsp_iov.iov_len);
+ rc = -EIO;
+ *nbytes = 0;
+ }
+
if (*buf) {
- memcpy(*buf, (char *)rsp + rsp->DataOffset, *nbytes);
+ memcpy(*buf, (char *)rsp + data_offset, *nbytes);
free_rsp_buf(resp_buftype, rsp_iov.iov_base);
} else if (resp_buftype != CIFS_NO_BUFFER) {
*buf = rsp_iov.iov_base;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 002/686] ALSA: x86: hdmi: fix chmap array missing terminator entry
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 001/686] smb: client: validate the data area in SMB2_read() Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 003/686] cxl/features: Ensure that count is set before access to ent[] __counted_by() Greg Kroah-Hartman
` (683 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Peter Ujfalusi, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
[ Upstream commit f5e1a9a3fddab8421416b68bb132ae9626d07156 ]
had_build_channel_allocation_map() allocates a single struct
snd_pcm_chmap_elem via kzalloc() and stores it as
intelhaddata->chmap->chmap. struct snd_pcm_chmap.chmap is expected to
be a zero-terminated array (see snd_pcm_std_chmaps[]), but
had_register_chmap_ctls() never overrides the TLV callback installed
by snd_pcm_add_chmap_ctls(), so the generic pcm_chmap_ctl_tlv() from
ALSA core is left in place.
pcm_chmap_ctl_tlv() is reachable by any local user via
SNDRV_CTL_IOCTL_TLV_READ on the "Playback Channel Map" control and
walks the array with "for (map = info->chmap; map->channels; map++)".
Since the driver's single element is never terminated, this walks
past the allocation. The same pointer is also freed on hot-unplug and
rebuilt on hot-plug under intelhaddata->mutex, while the TLV callback
runs under card->controls_rwsem without that mutex, so the walk can
also race a concurrent free of the array.
Fix this by allocating a second, zeroed element so the array is
properly terminated, and by dropping the inherited TLV callback
entirely at registration time, since the driver never implements one
of its own.
Fixes: 5dab11d89777 ("ALSA: x86: hdmi: Add audio support for BYT and CHT")
Cc: stable@vger.kernel.org
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://patch.msgid.link/20261008085411.13742-1-peter.ujfalusi@linux.intel.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
[ sashal: Adapted the allocation hunk to replace kzalloc(sizeof(*chmap), GFP_KERNEL) instead of kzalloc_obj(*chmap). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/x86/intel_hdmi_audio.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c
index 8e2a007311d36..21ee9c9154804 100644
--- a/sound/x86/intel_hdmi_audio.c
+++ b/sound/x86/intel_hdmi_audio.c
@@ -475,7 +475,8 @@ static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata)
kfree(intelhaddata->chmap->chmap);
intelhaddata->chmap->chmap = NULL;
- chmap = kzalloc(sizeof(*chmap), GFP_KERNEL);
+ /* info->chmap must be zero-terminated; allocate a spare terminator entry */
+ chmap = kzalloc_objs(*chmap, 2);
if (!chmap)
return;
@@ -575,6 +576,12 @@ static int had_register_chmap_ctls(struct snd_intelhad *intelhaddata,
intelhaddata->chmap->kctl->info = had_chmap_ctl_info;
intelhaddata->chmap->kctl->get = had_chmap_ctl_get;
intelhaddata->chmap->chmap = NULL;
+
+ /* drop the inherited TLV read: it walks chmap without our mutex */
+ intelhaddata->chmap->kctl->tlv.c = NULL;
+ intelhaddata->chmap->kctl->vd[0].access &=
+ ~(SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 003/686] cxl/features: Ensure that count is set before access to ent[] __counted_by()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 001/686] smb: client: validate the data area in SMB2_read() Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 002/686] ALSA: x86: hdmi: fix chmap array missing terminator entry Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 004/686] backing-file: always end a queued write Greg Kroah-Hartman
` (682 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ashok Raj, Dave Jiang,
Jonathan Cameron, Ahmed Abdelfattah, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ashok Raj <ashok.raj@oss.qualcomm.com>
commit c1031c2474f73261d8d5e4deef2b5dc20fb964f5 upstream.
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: Ahmed Abdelfattah <me@ahmedabdelfattah.dev>
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 bb73f205f16cf..0ea5a31275d38 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(struct_size(entries, ent, count), GFP_KERNEL);
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] 687+ messages in thread
* [PATCH 6.18 004/686] backing-file: always end a queued write
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 003/686] cxl/features: Ensure that count is set before access to ent[] __counted_by() Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 005/686] nvmet-rdma: fix out-of-bounds write in nvmet_rdma_map_sgl_inline() Greg Kroah-Hartman
` (681 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Amir Goldstein,
Christian Brauner (Amutable), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chris Mason <mason@kernel.org>
commit 627cdcbc2a2eceb0452078a0c14370f9f1f17a91 upstream.
Writes to a loop device with direct I/O on an overlay file make the
next freeze of the upper filesystem hang for ever.
Every kiocb_start_write() needs a kiocb_end_write(). For a write that
is queued, vfs_iocb_iter_write() leaves the end to the completion, and
backing_aio_rw_complete() only calls kiocb_end_write() when IOCB_WRITE
is set in the flags copied from the submitter. In-kernel submitters
such as loop do not set that flag, so each queued write keeps the
freeze protection of the backing filesystem.
Direct writes to a loop device with direct I/O backed by an overlay
file left fsfreeze of the ext4 upper filesystem, and a later touch
there, blocked in D state. It takes write access to the node of the
loop device, which root has by default, to attach the file and to write.
The fix used here is to mark a write in struct backing_aio and to call
kiocb_end_write() on completion of every marked write.
Reproduced under qemu without KVM, on v7.3-rc6-21-g602042bf29f6 with
earlier fixes of this series applied, with and without this change,
once each. The kernel was not changed for the run. With this change
fsfreeze finished in about a second. Not run: the nvmet and LIO file
backends, which do not set IOCB_WRITE either, FUSE passthrough, and an
xfs upper filesystem.
Fixes: 2406a307ac7d ("ovl: implement async IO routines")
Cc: stable@vger.kernel.org
Signed-off-by: Chris Mason <mason@kernel.org>
[amir: use aio->is_write to explicitly mark a write aio]
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Link: https://patch.msgid.link/20261029180319.2852090-1-amir73il@gmail.com
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/backing-file.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/fs/backing-file.c b/fs/backing-file.c
index bf526fa2e29df..ed8e793564c36 100644
--- a/fs/backing-file.c
+++ b/fs/backing-file.c
@@ -106,6 +106,7 @@ struct backing_aio {
refcount_t ref;
struct kiocb *orig_iocb;
/* used for aio completion */
+ bool is_write;
void (*end_write)(struct kiocb *iocb, ssize_t);
struct work_struct work;
long res;
@@ -146,7 +147,8 @@ static void backing_aio_rw_complete(struct kiocb *iocb, long res)
struct backing_aio *aio = container_of(iocb, struct backing_aio, iocb);
struct kiocb *orig_iocb = aio->orig_iocb;
- if (iocb->ki_flags & IOCB_WRITE)
+ /* Pairs with kiocb_start_write() in vfs_iocb_iter_write() */
+ if (aio->is_write)
kiocb_end_write(iocb);
backing_aio_cleanup(aio, res);
@@ -287,6 +289,7 @@ ssize_t backing_file_write_iter(struct file *file, struct iov_iter *iter,
goto out;
aio->orig_iocb = iocb;
+ aio->is_write = true;
aio->end_write = ctx->end_write;
kiocb_clone(&aio->iocb, iocb, get_file(file));
aio->iocb.ki_flags = flags;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 005/686] nvmet-rdma: fix out-of-bounds write in nvmet_rdma_map_sgl_inline()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 004/686] backing-file: always end a queued write Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 006/686] crypto: sa2ul - Fix HMAC key preparation Greg Kroah-Hartman
` (680 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bryam Vargas, Keith Busch,
Andrew Stellman, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Stellman <astellman@stellman-greene.com>
[ Upstream commit d1512773a0d539669440bd9f6d050b8e12923b5f ]
nvmet_rdma_map_sgl_inline() bounds the host-supplied in-capsule SGL
offset with "off + len > inline_data_size", evaluated in 64-bit
arithmetic. off is taken straight from the host SGL descriptor
(le64_to_cpu(sgl->addr)) and len is promoted to 64-bit, so the sum
wraps: an off within len of 2^64 makes it small and the check passes.
off is then used as page_idx = off / PAGE_SIZE to index the fixed-size
rsp->cmd->inline_sg[] array (NVMET_RDMA_MAX_INLINE_SGE entries), so a
crafted offset yields an out-of-bounds scatterlist index that is written
through in nvmet_rdma_use_inline_sg().
The mapping runs while handling a received capsule, before the command
executes, so a remote RDMA peer can reach it (the Connect capsule is a
write and takes this path on a queue that has no controller yet). The
host controls only the low bits of the resulting displacement, so the
expected impact is an out-of-bounds write that faults the target
(remote denial of service).
This wrap was reported, with a KASAN reproduction, on linux-nvme in May,
and the check below was suggested in that thread. The fix that was
applied, 48c0162f647b, reworked how the offset is mapped but kept the
original check, and its page index turns a wrapped offset into an
out-of-bounds index into inline_sg[].
Reject the offset before it can wrap.
Found independently by static analysis with AI assistance, not
reproduced at runtime.
Fixes: 0d5ee2b2ab4f ("nvmet-rdma: support max(16KB, PAGE_SIZE) inline data")
Fixes: 48c0162f647b ("nvmet-rdma: handle inline data with a nonzero offset")
Reported-by: Bryam Vargas <hexlabsecurity@proton.me>
Closes: https://lore.kernel.org/all/LM21QIR-1-qJb7PViyJKCnGBnUzizeiNJVWQ3wb7ZwGezodjgKg3f-iobqOyequ-sT1jFCKJImfqNO_BKU3KO80xFITnaI5GTV_GxLUNDDc=@proton.me/
Suggested-by: Keith Busch <kbusch@kernel.org>
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5
Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/rdma.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index a0ba6641c7ffb..ae44a0ff34d74 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -864,7 +864,8 @@ static u16 nvmet_rdma_map_sgl_inline(struct nvmet_rdma_rsp *rsp)
return NVME_SC_INVALID_FIELD | NVME_STATUS_DNR;
}
- if (off + len > rsp->queue->dev->inline_data_size) {
+ if (off > (u64)rsp->queue->dev->inline_data_size ||
+ len > (u64)rsp->queue->dev->inline_data_size - off) {
pr_err("invalid inline data offset!\n");
return NVME_SC_SGL_INVALID_OFFSET | NVME_STATUS_DNR;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 006/686] crypto: sa2ul - Fix HMAC key preparation
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 005/686] nvmet-rdma: fix out-of-bounds write in nvmet_rdma_map_sgl_inline() Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 007/686] fsverity: Tell LSMs about signature only after verity is enabled Greg Kroah-Hartman
` (679 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Eric Biggers, Herbert Xu,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit 780cd10c8e78f97ed768be229acff0ffd5483477 upstream.
sa_prepare_iopads() has multiple bugs, as discussed at
https://lore.kernel.org/linux-crypto/20260831055141.1632832-1-s-vadapalli@ti.com/T/#u
- Commit 3bf533787910 ("crypto: sha256 - Use the partial block API")
introduced a 1-byte buffer overflow in the SHA-256 case by making the
crypto_shash_export() write 1 more than sizeof(struct sha256_state).
- It never worked for HMAC keys longer than 64 bytes in the first place.
Fix both of these bugs by just using the crypto library to prepare the
key, like what the chelsio and qat drivers do. Also remove the
pointless use of an indirect call.
Fixes: 3bf533787910 ("crypto: sha256 - Use the partial block API")
Fixes: d2c8ac187fc9 ("crypto: sa2ul - Add AEAD algorithm support")
Cc: stable@vger.kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/crypto/sa2ul.c | 121 +++++++++--------------------------------
1 file changed, 27 insertions(+), 94 deletions(-)
diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c
index 4a766e4351970..563e0f0d574ad 100644
--- a/drivers/crypto/sa2ul.c
+++ b/drivers/crypto/sa2ul.c
@@ -125,9 +125,7 @@ struct sa_cmdl_cfg {
* @mci_enc: Mode Control Instruction for Encryption algorithm
* @mci_dec: Mode Control Instruction for Decryption
* @inv_key: Whether the encryption algorithm demands key inversion
- * @ctx: Pointer to the algorithm context
* @keyed_mac: Whether the authentication algorithm has key
- * @prep_iopad: Function pointer to generate intermediate ipad/opad
*/
struct algo_data {
struct sa_eng_info enc_eng;
@@ -141,10 +139,7 @@ struct algo_data {
u8 *mci_enc;
u8 *mci_dec;
bool inv_key;
- struct sa_tfm_ctx *ctx;
bool keyed_mac;
- void (*prep_iopad)(struct algo_data *algo, const u8 *key,
- u16 key_sz, __be32 *ipad, __be32 *opad);
};
/**
@@ -381,86 +376,36 @@ static void sa_swiz_128(u8 *in, u16 len)
}
}
-/* Prepare the ipad and opad from key as per SHA algorithm step 1*/
-static void prepare_kipad(u8 *k_ipad, const u8 *key, u16 key_sz)
+static void sa_prepare_iopads(struct algo_data *data, const u8 *key, u16 key_sz,
+ __be32 *ipad, __be32 *opad)
{
- int i;
-
- for (i = 0; i < key_sz; i++)
- k_ipad[i] = key[i] ^ 0x36;
-
- /* Instead of XOR with 0 */
- for (; i < SHA1_BLOCK_SIZE; i++)
- k_ipad[i] = 0x36;
-}
-
-static void prepare_kopad(u8 *k_opad, const u8 *key, u16 key_sz)
-{
- int i;
-
- for (i = 0; i < key_sz; i++)
- k_opad[i] = key[i] ^ 0x5c;
-
- /* Instead of XOR with 0 */
- for (; i < SHA1_BLOCK_SIZE; i++)
- k_opad[i] = 0x5c;
-}
-
-static void sa_export_shash(void *state, struct shash_desc *hash,
- int digest_size, __be32 *out)
-{
- struct sha1_state *sha1;
- struct sha256_state *sha256;
- u32 *result;
-
- switch (digest_size) {
- case SHA1_DIGEST_SIZE:
- sha1 = state;
- result = sha1->state;
+ union {
+ struct hmac_sha1_key sha1;
+ struct hmac_sha256_key sha256;
+ } k;
+
+ switch (data->aalg_id) {
+ case SA_AALG_ID_HMAC_SHA1:
+ hmac_sha1_preparekey(&k.sha1, key, key_sz);
+ cpu_to_be32_array(ipad, k.sha1.istate.h,
+ ARRAY_SIZE(k.sha1.istate.h));
+ cpu_to_be32_array(opad, k.sha1.ostate.h,
+ ARRAY_SIZE(k.sha1.ostate.h));
break;
- case SHA256_DIGEST_SIZE:
- sha256 = state;
- result = sha256->state;
+ case SA_AALG_ID_HMAC_SHA2_256:
+ hmac_sha256_preparekey(&k.sha256, key, key_sz);
+ cpu_to_be32_array(ipad, k.sha256.key.istate.h,
+ ARRAY_SIZE(k.sha256.key.istate.h));
+ cpu_to_be32_array(opad, k.sha256.key.ostate.h,
+ ARRAY_SIZE(k.sha256.key.ostate.h));
break;
default:
- dev_err(sa_k3_dev, "%s: bad digest_size=%d\n", __func__,
- digest_size);
+ dev_err(sa_k3_dev, "%s: bad aalg_id=%d\n", __func__,
+ data->aalg_id);
return;
}
- crypto_shash_export(hash, state);
-
- cpu_to_be32_array(out, result, digest_size / 4);
-}
-
-static void sa_prepare_iopads(struct algo_data *data, const u8 *key,
- u16 key_sz, __be32 *ipad, __be32 *opad)
-{
- SHASH_DESC_ON_STACK(shash, data->ctx->shash);
- int block_size = crypto_shash_blocksize(data->ctx->shash);
- int digest_size = crypto_shash_digestsize(data->ctx->shash);
- union {
- struct sha1_state sha1;
- struct sha256_state sha256;
- u8 k_pad[SHA1_BLOCK_SIZE];
- } sha;
-
- shash->tfm = data->ctx->shash;
-
- prepare_kipad(sha.k_pad, key, key_sz);
-
- crypto_shash_init(shash);
- crypto_shash_update(shash, sha.k_pad, block_size);
- sa_export_shash(&sha, shash, digest_size, ipad);
-
- prepare_kopad(sha.k_pad, key, key_sz);
-
- crypto_shash_init(shash);
- crypto_shash_update(shash, sha.k_pad, block_size);
-
- sa_export_shash(&sha, shash, digest_size, opad);
-
- memzero_explicit(&sha, sizeof(sha));
+ memzero_explicit(&k, sizeof(k));
}
/* Derive the inverse key used in AES-CBC decryption operation */
@@ -544,7 +489,7 @@ static void sa_set_sc_auth(struct algo_data *ad, const u8 *key, u16 key_sz,
/* Copy the keys or ipad/opad */
if (ad->keyed_mac)
- ad->prep_iopad(ad, key, key_sz, ipad, opad);
+ sa_prepare_iopads(ad, key, key_sz, ipad, opad);
else {
/* basic hash */
sc_buf[1] |= SA_BASIC_HASH;
@@ -1697,8 +1642,7 @@ static void sa_aead_dma_in_callback(void *data)
aead_request_complete(req, err);
}
-static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash,
- const char *fallback)
+static int sa_cra_init_aead(struct crypto_aead *tfm, const char *fallback)
{
struct sa_tfm_ctx *ctx = crypto_aead_ctx(tfm);
struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev);
@@ -1707,12 +1651,6 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash,
memzero_explicit(ctx, sizeof(*ctx));
ctx->dev_data = data;
- ctx->shash = crypto_alloc_shash(hash, 0, CRYPTO_ALG_NEED_FALLBACK);
- if (IS_ERR(ctx->shash)) {
- dev_err(sa_k3_dev, "base driver %s couldn't be loaded\n", hash);
- return PTR_ERR(ctx->shash);
- }
-
ctx->fallback.aead = crypto_alloc_aead(fallback, 0,
CRYPTO_ALG_NEED_FALLBACK);
@@ -1744,14 +1682,12 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash,
static int sa_cra_init_aead_sha1(struct crypto_aead *tfm)
{
- return sa_cra_init_aead(tfm, "sha1",
- "authenc(hmac(sha1),cbc(aes))");
+ return sa_cra_init_aead(tfm, "authenc(hmac(sha1),cbc(aes))");
}
static int sa_cra_init_aead_sha256(struct crypto_aead *tfm)
{
- return sa_cra_init_aead(tfm, "sha256",
- "authenc(hmac(sha256),cbc(aes))");
+ return sa_cra_init_aead(tfm, "authenc(hmac(sha256),cbc(aes))");
}
static void sa_exit_tfm_aead(struct crypto_aead *tfm)
@@ -1759,7 +1695,6 @@ static void sa_exit_tfm_aead(struct crypto_aead *tfm)
struct sa_tfm_ctx *ctx = crypto_aead_ctx(tfm);
struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev);
- crypto_free_shash(ctx->shash);
crypto_free_aead(ctx->fallback.aead);
sa_free_ctx_info(&ctx->enc, data);
@@ -1785,7 +1720,6 @@ static int sa_aead_setkey(struct crypto_aead *authenc,
if (key_idx >= 3)
return -EINVAL;
- ad->ctx = ctx;
ad->enc_eng.eng_id = SA_ENG_ID_EM1;
ad->enc_eng.sc_size = SA_CTX_ENC_TYPE1_SZ;
ad->auth_eng.eng_id = SA_ENG_ID_AM1;
@@ -1795,7 +1729,6 @@ static int sa_aead_setkey(struct crypto_aead *authenc,
ad->inv_key = true;
ad->keyed_mac = true;
ad->ealg_id = SA_EALG_ID_AES_CBC;
- ad->prep_iopad = sa_prepare_iopads;
memset(&cfg, 0, sizeof(cfg));
cfg.enc = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 007/686] fsverity: Tell LSMs about signature only after verity is enabled
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 006/686] crypto: sa2ul - Fix HMAC key preparation Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 008/686] Bluetooth: L2CAP: Reject signalling responses in invalid states Greg Kroah-Hartman
` (678 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Eric Biggers, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit 28d74059fddbd8ae83c7715056b303c402071f6f upstream.
FS_IOC_ENABLE_VERITY calls security_inode_setintegrity() before verity
has finished being enabled. That's broken because enabling verity can
still fail at that point, e.g. due to insufficient xattr space.
Afterwards, arbitrary contents can be written to the file, which doesn't
actually have verity enabled. The in-core inode stays the same, so the
LSM considers it to have verity enabled with a valid signature. (Or
rather, in the case of IPE, which is the only LSM that implements
security_inode_setintegrity(), it also checks IS_VERITY(), which can be
bypassed by enabling verity with no signature after the file writes.)
Fix this by moving the call to security_inode_setintegrity() out of
fsverity_verify_signature() and into a new function that is called from
the appropriate places.
Fixes: 7c373e4f1445 ("fsverity: expose verified fsverity built-in signatures to LSMs")
Cc: stable@vger.kernel.org
Reviewed-by: Fan Wu <wufan@kernel.org>
Tested-by: Fan Wu <wufan@kernel.org>
Link: https://patch.msgid.link/20261025204534.122506-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/verity/enable.c | 8 ++++++
fs/verity/fsverity_private.h | 8 ++++++
fs/verity/open.c | 9 ++++++
fs/verity/signature.c | 55 ++++++++++++++++++++++++++----------
4 files changed, 65 insertions(+), 15 deletions(-)
diff --git a/fs/verity/enable.c b/fs/verity/enable.c
index 95ec42b847972..05fbcae57e5db 100644
--- a/fs/verity/enable.c
+++ b/fs/verity/enable.c
@@ -287,6 +287,14 @@ static int enable_verity(struct file *filp,
* just after the filesystem has successfully enabled verity.
*/
fsverity_set_info(inode, vi);
+
+ /*
+ * Now that verity is enabled, report the signature (if any) to
+ * LSMs. We tolerate that a process racing with this ioctl can
+ * briefly see verity enabled with no signature reported yet.
+ */
+ fsverity_report_valid_sig(inode, desc->signature,
+ le32_to_cpu(desc->sig_size));
}
out:
kfree(params.hashstate);
diff --git a/fs/verity/fsverity_private.h b/fs/verity/fsverity_private.h
index dd20b138d452f..0a2ddca3c838d 100644
--- a/fs/verity/fsverity_private.h
+++ b/fs/verity/fsverity_private.h
@@ -142,6 +142,8 @@ void __init fsverity_init_info_cache(void);
extern int fsverity_require_signatures;
int fsverity_verify_signature(const struct fsverity_info *vi,
const u8 *signature, size_t sig_size);
+void fsverity_report_valid_sig(const struct inode *inode, const u8 *signature,
+ size_t sig_size);
void __init fsverity_init_signature(void);
#else /* !CONFIG_FS_VERITY_BUILTIN_SIGNATURES */
@@ -152,6 +154,12 @@ fsverity_verify_signature(const struct fsverity_info *vi,
return 0;
}
+static inline void fsverity_report_valid_sig(const struct inode *inode,
+ const u8 *signature,
+ size_t sig_size)
+{
+}
+
static inline void fsverity_init_signature(void)
{
}
diff --git a/fs/verity/open.c b/fs/verity/open.c
index 02e2c14ab3ffb..dbc2a25e9158e 100644
--- a/fs/verity/open.c
+++ b/fs/verity/open.c
@@ -369,6 +369,15 @@ static int ensure_verity_info(struct inode *inode)
goto out_free_desc;
}
+ /*
+ * Now that the signature (if any) has been verified, report it to LSMs.
+ * Do this before setting the fsverity_info, so that anyone who
+ * concurrently retrieves the fsverity_info for the same inode is
+ * guaranteed to see the LSM's signature status populated.
+ */
+ fsverity_report_valid_sig(inode, desc->signature,
+ le32_to_cpu(desc->sig_size));
+
fsverity_set_info(inode, vi);
err = 0;
out_free_desc:
diff --git a/fs/verity/signature.c b/fs/verity/signature.c
index 0302a4e506ec4..212e873c84998 100644
--- a/fs/verity/signature.c
+++ b/fs/verity/signature.c
@@ -42,13 +42,16 @@ static struct key *fsverity_keyring;
* @sig_size: size of signature in bytes, or 0 if no signature
*
* If the file includes a signature of its fs-verity file digest, verify it
- * against the certificates in the fs-verity keyring. Note that signatures
- * are verified regardless of the state of the 'fsverity_require_signatures'
- * variable and the LSM subsystem relies on this behavior to help enforce
- * file integrity policies. Please discuss changes with the LSM list
- * (thank you!).
+ * against the certificates in the fs-verity keyring.
*
- * Return: 0 on success (signature valid or not required); -errno on failure
+ * Note that signatures are verified regardless of the state of the
+ * 'fsverity_require_signatures' variable, and the LSM subsystem relies on this
+ * behavior to help enforce file integrity policies. (See
+ * fsverity_report_valid_sig(), which assumes that the signature, if present,
+ * was verified here.) Please discuss changes with the LSM list (thank you!).
+ *
+ * Return: 0 if the signature is present and valid, or absent and not required;
+ * -errno on failure
*/
int fsverity_verify_signature(const struct fsverity_info *vi,
const u8 *signature, size_t sig_size)
@@ -111,18 +114,40 @@ int fsverity_verify_signature(const struct fsverity_info *vi,
return err;
}
- err = security_inode_setintegrity(inode,
- LSM_INT_FSVERITY_BUILTINSIG_VALID,
- signature,
- sig_size);
+ return 0;
+}
- if (err) {
+/*
+ * If the signature exists, this tells the LSM that it was verified.
+ *
+ * fsverity_verify_signature() must have already been called with the same
+ * signature, *and* the inode must have verity enabled with the signature
+ * matching it. If called from FS_IOC_ENABLE_VERITY, the latter means that we
+ * must be past the point of no return, i.e. verity won't fail to be enabled at
+ * a later point. This is critical, since LSMs must be told about the signature
+ * only when the verity status is permanent in the in-core inode.
+ */
+void fsverity_report_valid_sig(const struct inode *inode, const u8 *signature,
+ size_t sig_size)
+{
+ int err;
+
+ if (WARN_ON_ONCE(!IS_VERITY(inode)))
+ return;
+
+ if (sig_size == 0)
+ return;
+
+ err = security_inode_setintegrity(
+ inode, LSM_INT_FSVERITY_BUILTINSIG_VALID, signature, sig_size);
+ if (err)
fsverity_err(inode, "Error %d exposing file signature to LSMs",
err);
- return err;
- }
-
- return 0;
+ /*
+ * Besides the logging above, ignore errors here. The LSM hook just
+ * records the signature and doesn't perform access control. And in the
+ * case of FS_IOC_ENABLE_VERITY verity was already enabled.
+ */
}
void __init fsverity_init_signature(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 008/686] Bluetooth: L2CAP: Reject signalling responses in invalid states
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 007/686] fsverity: Tell LSMs about signature only after verity is enabled Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 009/686] Bluetooth: L2CAP: Only accept connection responses to outstanding requests Greg Kroah-Hartman
` (677 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Siwei Zhang, Luiz Augusto von Dentz,
Sasha Levin
6.18-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 0ba7b1ea435cc..52ff1b8785d77 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4310,6 +4310,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)) {
@@ -4339,6 +4343,7 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn,
break;
}
+done:
l2cap_chan_unlock(chan);
l2cap_chan_put(chan);
@@ -4471,7 +4476,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);
@@ -4519,6 +4530,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);
@@ -4586,6 +4601,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] 687+ messages in thread
* [PATCH 6.18 009/686] Bluetooth: L2CAP: Only accept connection responses to outstanding requests
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 008/686] Bluetooth: L2CAP: Reject signalling responses in invalid states Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 010/686] Bluetooth: L2CAP: Ignore connection responses with wrong ident Greg Kroah-Hartman
` (676 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Siwei Zhang, Luiz Augusto von Dentz,
Sasha Levin
6.18-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 52ff1b8785d77..22bac1222fab7 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -161,6 +161,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)
{
@@ -4297,7 +4319,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;
}
@@ -4310,8 +4332,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] 687+ messages in thread
* [PATCH 6.18 010/686] Bluetooth: L2CAP: Ignore connection responses with wrong ident
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 009/686] Bluetooth: L2CAP: Only accept connection responses to outstanding requests Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 011/686] smb: client: Avoid leaking sensitive data to the heap in connect.c Greg Kroah-Hartman
` (675 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jinwang Li, Luiz Augusto von Dentz,
Siwei Zhang, Sasha Levin
6.18-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 22bac1222fab7..d648d57299541 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4332,11 +4332,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] 687+ messages in thread
* [PATCH 6.18 011/686] smb: client: Avoid leaking sensitive data to the heap in connect.c
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 010/686] Bluetooth: L2CAP: Ignore connection responses with wrong ident Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 012/686] smb: client: hold server info until cifsd exits Greg Kroah-Hartman
` (674 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Huth, Namjae Jeon,
Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Huth <thuth@redhat.com>
[ Upstream commit 111a2b8717efbd9729d36828308d5163fdc977c3 ]
TCP_Server_Info contains a preauth_sha_hash[] and a cryptkey[] array
that might contain sensitive data. Thus free its memory with
kfree_sensitive() to avoid that we are leaking this information to
the heap.
Signed-off-by: Thomas Huth <thuth@redhat.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Stable-dep-of: 482c117c6dbe ("smb: client: hold server info until cifsd exits")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/connect.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 2cbbbf0c93b80..fa7c2f70b6ed3 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1147,7 +1147,7 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
put_net(cifs_net_ns(server));
kfree(server->leaf_fullpath);
kfree(server->hostname);
- kfree(server);
+ kfree_sensitive(server);
length = atomic_dec_return(&tcpSesAllocCount);
if (length > 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 012/686] smb: client: hold server info until cifsd exits
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 011/686] smb: client: Avoid leaking sensitive data to the heap in connect.c Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 013/686] smb: move smb_sockaddr_in and smb_sockaddr_in6 to common/smb2pdu.h Greg Kroah-Hartman
` (673 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+5c3ed2a0de3270efc921,
syzbot+c2ec61adfbcb24e5ec20, Eduard Zateev,
Michail Andreas Michalopoulos, Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zateev <hackerowskiy@gmail.com>
[ Upstream commit 482c117c6dbeee382790168af10959810450ab09 ]
The last session reference can be dropped while the cifsd demultiplex
thread is still running clean_demultiplex_info(). That thread frees
TCP_Server_Info there, racing with cifs_put_tcp_session() as it releases
the server crypto state. syzbot reported a KASAN use-after-free in
cifs_crypto_secmech_release().
Keep an object reference for the cifsd thread. Defer final crypto,
session-key, network namespace, string, and structure cleanup until both
the last session reference and the thread reference are dropped. Drop the
thread reference after clean_demultiplex_info() has finished using the
server.
Build-tested with ARCH=arm64 and W=1 for
fs/smb/client/connect.o. The KASAN reproducer was not run on the patched
kernel.
Fixes: a5c3e1c725af ("Revert "cifs: No need to send SIGKILL to demux_thread during umount"")
Reported-by: syzbot+5c3ed2a0de3270efc921@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=5c3ed2a0de3270efc921
Reported-by: syzbot+c2ec61adfbcb24e5ec20@syzkaller.appspotmail.com
Closes: https://syzbot.org/bug?extid=c2ec61adfbcb24e5ec20
Assisted-by: LLM OpenAI Codex
Signed-off-by: Eduard Zateev <hackerowskiy@gmail.com>
Cc: stable@vger.kernel.org
Tested-by: Michail Andreas Michalopoulos <mike.michalo@gmail.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsglob.h | 2 ++
fs/smb/client/connect.c | 33 +++++++++++++++++++++------------
2 files changed, 23 insertions(+), 12 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index 8d751026dd4a2..d529446e4984b 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -16,6 +16,7 @@
#include <linux/scatterlist.h>
#include <linux/mm.h>
#include <linux/mempool.h>
+#include <linux/refcount.h>
#include <linux/workqueue.h>
#include <linux/utsname.h>
#include <linux/sched/mm.h>
@@ -678,6 +679,7 @@ struct TCP_Server_Info {
spinlock_t srv_lock; /* protect anything here that is not protected */
__u64 conn_id; /* connection identifier (useful for debugging) */
int srv_count; /* reference counter */
+ refcount_t obj_refs; /* struct lifetime: srv_count users + cifsd */
int rfc1001_sessinit; /* whether to estasblish netbios session */
bool with_rfc1001; /* if netbios session is used */
/* 15 character server name + 0x20 16th byte indicating type = srv */
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index fa7c2f70b6ed3..0a60c411aba67 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1059,6 +1059,19 @@ cifs_enable_signing(struct TCP_Server_Info *server, bool mnt_sign_required)
return 0;
}
+static void cifs_tcp_server_put(struct TCP_Server_Info *server)
+{
+ if (!refcount_dec_and_test(&server->obj_refs))
+ return;
+
+ cifs_crypto_secmech_release(server);
+ kfree_sensitive(server->session_key.response);
+ put_net(cifs_net_ns(server));
+ kfree(server->leaf_fullpath);
+ kfree(server->hostname);
+ kfree_sensitive(server);
+}
+
static noinline_for_stack void
clean_demultiplex_info(struct TCP_Server_Info *server)
{
@@ -1144,14 +1157,11 @@ clean_demultiplex_info(struct TCP_Server_Info *server)
*/
}
- put_net(cifs_net_ns(server));
- kfree(server->leaf_fullpath);
- kfree(server->hostname);
- kfree_sensitive(server);
-
length = atomic_dec_return(&tcpSesAllocCount);
if (length > 0)
mempool_resize(cifs_req_poolp, length + cifs_min_rcv);
+
+ cifs_tcp_server_put(server);
}
static int
@@ -1730,7 +1740,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
else
cancel_delayed_work_sync(&server->reconnect);
- /* For secondary channels, we pick up ref-count on the primary server */
+ /* For secondary channels, drop the reference on the primary server */
if (SERVER_IS_CHAN(server))
cifs_put_tcp_session(server->primary_server, from_reconnect);
@@ -1738,15 +1748,11 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
server->tcpStatus = CifsExiting;
spin_unlock(&server->srv_lock);
- cifs_crypto_secmech_release(server);
-
- kfree_sensitive(server->session_key.response);
- server->session_key.response = NULL;
- server->session_key.len = 0;
-
task = xchg(&server->tsk, NULL);
if (task)
send_sig(SIGKILL, task, 1);
+
+ cifs_tcp_server_put(server);
}
struct TCP_Server_Info *
@@ -1768,6 +1774,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
rc = -ENOMEM;
goto out_err;
}
+ refcount_set(&tcp_ses->obj_refs, 1);
tcp_ses->hostname = kstrdup(ctx->server_hostname, GFP_KERNEL);
if (!tcp_ses->hostname) {
@@ -1906,6 +1913,8 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
module_put(THIS_MODULE);
goto out_err_crypto_release;
}
+ /* Keep the server alive until the demultiplex thread has exited */
+ refcount_inc(&tcp_ses->obj_refs);
/* thread created, put it on the list */
spin_lock(&cifs_tcp_ses_lock);
list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 013/686] smb: move smb_sockaddr_in and smb_sockaddr_in6 to common/smb2pdu.h
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 012/686] smb: client: hold server info until cifsd exits Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 014/686] smb: move create_durable_req_v2 " Greg Kroah-Hartman
` (672 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, ZhangGuoDong,
Namjae Jeon, Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZhangGuoDong <zhangguodong@kylinos.cn>
[ Upstream commit 7844d50ca239f0788e732608820f7026cb0cc8fb ]
Rename 4 places:
- iface_info_ipv4 -> smb_sockaddr_in
- iface_info_ipv6 -> smb_sockaddr_in6
- IPv4address -> IPv4Address
- IPv6address -> IPv6Address
Then move duplicate definitions to common header file.
Co-developed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f8171804a39e ("smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 8 ++++----
fs/smb/client/smb2pdu.h | 13 -------------
fs/smb/common/smb2pdu.h | 15 +++++++++++++++
fs/smb/server/smb2pdu.c | 4 ++--
fs/smb/server/smb2pdu.h | 13 -------------
5 files changed, 21 insertions(+), 32 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 7cf6419df037d..71cf42981ab04 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -635,8 +635,8 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
struct network_interface_info_ioctl_rsp *p;
struct sockaddr_in *addr4;
struct sockaddr_in6 *addr6;
- struct iface_info_ipv4 *p4;
- struct iface_info_ipv6 *p6;
+ struct smb_sockaddr_in *p4;
+ struct smb_sockaddr_in6 *p6;
struct cifs_server_iface *info = NULL, *iface = NULL, *niface = NULL;
struct cifs_server_iface tmp_iface;
__be16 port;
@@ -698,7 +698,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
*/
case INTERNETWORK:
addr4 = (struct sockaddr_in *)&tmp_iface.sockaddr;
- p4 = (struct iface_info_ipv4 *)p->Buffer;
+ p4 = (struct smb_sockaddr_in *)p->Buffer;
addr4->sin_family = AF_INET;
memcpy(&addr4->sin_addr, &p4->IPv4Address, 4);
@@ -710,7 +710,7 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
break;
case INTERNETWORKV6:
addr6 = (struct sockaddr_in6 *)&tmp_iface.sockaddr;
- p6 = (struct iface_info_ipv6 *)p->Buffer;
+ p6 = (struct smb_sockaddr_in6 *)p->Buffer;
addr6->sin6_family = AF_INET6;
memcpy(&addr6->sin6_addr, &p6->IPv6Address, 16);
diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index cdf7c588cc00d..de2d83c6463c9 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -255,19 +255,6 @@ struct network_interface_info_ioctl_rsp {
__u8 Buffer[126];
} __packed;
-struct iface_info_ipv4 {
- __be16 Port;
- __be32 IPv4Address;
- __be64 Reserved;
-} __packed;
-
-struct iface_info_ipv6 {
- __be16 Port;
- __be32 FlowInfo;
- __u8 IPv6Address[16];
- __be32 ScopeId;
-} __packed;
-
#define NO_FILE_ID 0xFFFFFFFFFFFFFFFFULL /* general ioctls to srv not to file */
struct compress_ioctl {
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index 528ba77247e80..1bd5835c56e45 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -1433,6 +1433,21 @@ struct smb2_ioctl_rsp {
__u8 Buffer[];
} __packed;
+/* See MS-SMB2 2.2.32.5.1.1 */
+struct smb_sockaddr_in {
+ __be16 Port;
+ __be32 IPv4Address;
+ __u8 Reserved[8];
+} __packed;
+
+/* See MS-SMB2 2.2.32.5.1.2 */
+struct smb_sockaddr_in6 {
+ __be16 Port;
+ __be32 FlowInfo;
+ __u8 IPv6Address[16];
+ __be32 ScopeId;
+} __packed;
+
/* this goes in the ioctl buffer when doing FSCTL_SET_ZERO_DATA */
struct file_zero_data_information {
__le64 FileOffset;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index a8a42fde4ca02..55d634b5d2e2f 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -8297,7 +8297,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
idev = __in_dev_get_rtnl(netdev);
if (!idev)
continue;
- sockaddr_storage->addr4.IPv4address =
+ sockaddr_storage->addr4.IPv4Address =
idev_ipv4_address(idev);
nbytes += sizeof(struct network_interface_info_ioctl_rsp);
ipv4_set = true;
@@ -8305,7 +8305,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
} else {
struct inet6_dev *idev6;
struct inet6_ifaddr *ifa;
- __u8 *ipv6_addr = sockaddr_storage->addr6.IPv6address;
+ __u8 *ipv6_addr = sockaddr_storage->addr6.IPv6Address;
sockaddr_storage->Family = cpu_to_le16(INTERNETWORKV6);
sockaddr_storage->addr6.Port = 0;
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 23abb70ea5d3d..48026edb7314b 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -138,19 +138,6 @@ struct create_posix_rsp {
#define SMB2_0_IOCTL_IS_FSCTL 0x00000001
-struct smb_sockaddr_in {
- __be16 Port;
- __be32 IPv4address;
- __u8 Reserved[8];
-} __packed;
-
-struct smb_sockaddr_in6 {
- __be16 Port;
- __be32 FlowInfo;
- __u8 IPv6address[16];
- __be32 ScopeId;
-} __packed;
-
#define INTERNETWORK 0x0002
#define INTERNETWORKV6 0x0017
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 014/686] smb: move create_durable_req_v2 to common/smb2pdu.h
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 013/686] smb: move smb_sockaddr_in and smb_sockaddr_in6 to common/smb2pdu.h Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 015/686] smb: move create_durable_handle_reconnect_v2 " Greg Kroah-Hartman
` (671 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, Namjae Jeon,
Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 833a75fc9ecc3856a52223d8c245e52703e0a9f1 ]
Modify the following places:
- some fields in "struct create_durable_req_v2" ->
struct durable_context_v2
- durable_context_v2 -> durable_context_v2_req
- create_durable_v2 -> create_durable_req_v2
Then move duplicate definitions to common header file.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f8171804a39e ("smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2pdu.c | 14 +++++++-------
fs/smb/client/smb2pdu.h | 12 ------------
fs/smb/common/smb2pdu.h | 14 ++++++++++++++
fs/smb/server/smb2pdu.c | 8 ++++----
fs/smb/server/smb2pdu.h | 9 ---------
5 files changed, 25 insertions(+), 32 deletions(-)
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index 5185f8cc8bcc8..d8c97c1c63b5f 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -2456,21 +2456,21 @@ add_lease_context(struct TCP_Server_Info *server,
return 0;
}
-static struct create_durable_v2 *
+static struct create_durable_req_v2 *
create_durable_v2_buf(struct cifs_open_parms *oparms)
{
struct cifs_fid *pfid = oparms->fid;
- struct create_durable_v2 *buf;
+ struct create_durable_req_v2 *buf;
- buf = kzalloc(sizeof(struct create_durable_v2), GFP_KERNEL);
+ buf = kzalloc(sizeof(struct create_durable_req_v2), GFP_KERNEL);
if (!buf)
return NULL;
buf->ccontext.DataOffset = cpu_to_le16(offsetof
- (struct create_durable_v2, dcontext));
- buf->ccontext.DataLength = cpu_to_le32(sizeof(struct durable_context_v2));
+ (struct create_durable_req_v2, dcontext));
+ buf->ccontext.DataLength = cpu_to_le32(sizeof(struct durable_context_v2_req));
buf->ccontext.NameOffset = cpu_to_le16(offsetof
- (struct create_durable_v2, Name));
+ (struct create_durable_req_v2, Name));
buf->ccontext.NameLength = cpu_to_le16(4);
/*
@@ -2540,7 +2540,7 @@ add_durable_v2_context(struct kvec *iov, unsigned int *num_iovec,
iov[num].iov_base = create_durable_v2_buf(oparms);
if (iov[num].iov_base == NULL)
return -ENOMEM;
- iov[num].iov_len = sizeof(struct create_durable_v2);
+ iov[num].iov_len = sizeof(struct create_durable_req_v2);
*num_iovec = num + 1;
return 0;
}
diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index de2d83c6463c9..472553e499830 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -137,18 +137,6 @@ struct share_redirect_error_context_rsp {
/* See MS-SMB2 2.2.13.2.11 */
/* Flags */
#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
-struct durable_context_v2 {
- __le32 Timeout;
- __le32 Flags;
- __u64 Reserved;
- __u8 CreateGuid[16];
-} __packed;
-
-struct create_durable_v2 {
- struct create_context_hdr ccontext;
- __u8 Name[8];
- struct durable_context_v2 dcontext;
-} __packed;
/* See MS-SMB2 2.2.13.2.12 */
struct durable_reconnect_context_v2 {
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index 1bd5835c56e45..ca47c54afd324 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -1290,6 +1290,20 @@ struct create_mxac_req {
__le64 Timestamp;
} __packed;
+/* See MS-SMB2 2.2.13.2.11 */
+struct durable_context_v2_req {
+ __le32 Timeout;
+ __le32 Flags; /* see SMB2_DHANDLE_FLAG_PERSISTENT */
+ __u64 Reserved;
+ __u8 CreateGuid[16];
+} __packed;
+
+struct create_durable_req_v2 {
+ struct create_context_hdr ccontext;
+ __u8 Name[8];
+ struct durable_context_v2_req dcontext;
+} __packed;
+
/* See MS-SMB2 2.2.14.2.5 */
struct create_mxac_rsp {
struct create_context_hdr ccontext;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 55d634b5d2e2f..9e54b4301106b 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -2908,7 +2908,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
durable_v2_blob =
(struct create_durable_req_v2 *)context;
ksmbd_debug(SMB, "Request for durable v2 open\n");
- dh_info->fp = ksmbd_lookup_fd_cguid(durable_v2_blob->CreateGuid);
+ dh_info->fp = ksmbd_lookup_fd_cguid(durable_v2_blob->dcontext.CreateGuid);
if (dh_info->fp) {
if (!memcmp(conn->ClientGUID, dh_info->fp->client_guid,
SMB2_CLIENT_GUID_SIZE)) {
@@ -2933,11 +2933,11 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
if ((lc && (lc->req_state & SMB2_LEASE_HANDLE_CACHING_LE)) ||
req_op_level == SMB2_OPLOCK_LEVEL_BATCH) {
dh_info->CreateGuid =
- durable_v2_blob->CreateGuid;
+ durable_v2_blob->dcontext.CreateGuid;
dh_info->persistent =
- le32_to_cpu(durable_v2_blob->Flags);
+ le32_to_cpu(durable_v2_blob->dcontext.Flags);
dh_info->timeout =
- le32_to_cpu(durable_v2_blob->Timeout);
+ le32_to_cpu(durable_v2_blob->dcontext.Timeout);
dh_info->type = dh_idx;
}
break;
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 48026edb7314b..189e0d955b4a5 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -66,15 +66,6 @@ struct preauth_integrity_info {
/* Apple Defined Contexts */
#define SMB2_CREATE_AAPL "AAPL"
-struct create_durable_req_v2 {
- struct create_context_hdr ccontext;
- __u8 Name[8];
- __le32 Timeout;
- __le32 Flags;
- __u8 Reserved[8];
- __u8 CreateGuid[16];
-} __packed;
-
#define DURABLE_HANDLE_MAX_TIMEOUT 300000
struct create_durable_reconn_req {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 015/686] smb: move create_durable_handle_reconnect_v2 to common/smb2pdu.h
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (13 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 014/686] smb: move create_durable_req_v2 " Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 016/686] smb: move create_durable_rsp_v2 " Greg Kroah-Hartman
` (670 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, Namjae Jeon,
Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 81a45de432c6c7d82821fb09cb9fc1cf58629f3a ]
Modify the following places:
- some fields in "struct create_durable_reconn_v2_req" ->
struct durable_reconnect_context_v2
- create_durable_reconn_v2_req -> create_durable_handle_reconnect_v2
Then move duplicate definitions to common header file.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f8171804a39e ("smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2pdu.h | 17 -----------------
fs/smb/common/smb2pdu.h | 16 ++++++++++++++++
fs/smb/server/smb2pdu.c | 10 +++++-----
fs/smb/server/smb2pdu.h | 11 -----------
4 files changed, 21 insertions(+), 33 deletions(-)
diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index 472553e499830..a75cde061a67d 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -138,29 +138,12 @@ struct share_redirect_error_context_rsp {
/* Flags */
#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
-/* See MS-SMB2 2.2.13.2.12 */
-struct durable_reconnect_context_v2 {
- struct {
- __u64 PersistentFileId;
- __u64 VolatileFileId;
- } Fid;
- __u8 CreateGuid[16];
- __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
-} __packed;
-
/* See MS-SMB2 2.2.14.2.12 */
struct durable_reconnect_context_v2_rsp {
__le32 Timeout;
__le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
} __packed;
-struct create_durable_handle_reconnect_v2 {
- struct create_context_hdr ccontext;
- __u8 Name[8];
- struct durable_reconnect_context_v2 dcontext;
- __u8 Pad[4];
-} __packed;
-
/* See MS-SMB2 2.2.13.2.5 */
struct crt_twarp_ctxt {
struct create_context_hdr ccontext;
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index ca47c54afd324..7899e7706318f 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -1304,6 +1304,22 @@ struct create_durable_req_v2 {
struct durable_context_v2_req dcontext;
} __packed;
+/* See MS-SMB2 2.2.13.2.12 */
+struct durable_reconnect_context_v2 {
+ struct {
+ __u64 PersistentFileId;
+ __u64 VolatileFileId;
+ } Fid;
+ __u8 CreateGuid[16];
+ __le32 Flags; /* see SMB2_DHANDLE_FLAG_PERSISTENT */
+} __packed;
+
+struct create_durable_handle_reconnect_v2 {
+ struct create_context_hdr ccontext;
+ __u8 Name[8];
+ struct durable_reconnect_context_v2 dcontext;
+} __packed;
+
/* See MS-SMB2 2.2.14.2.5 */
struct create_mxac_rsp {
struct create_context_hdr ccontext;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 9e54b4301106b..d16df43f7c772 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -2818,7 +2818,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
switch (dh_idx) {
case DURABLE_RECONN_V2:
{
- struct create_durable_reconn_v2_req *recon_v2;
+ struct create_durable_handle_reconnect_v2 *recon_v2;
if (dh_info->type == DURABLE_RECONN ||
dh_info->type == DURABLE_REQ_V2) {
@@ -2828,13 +2828,13 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
if (le16_to_cpu(context->DataOffset) +
le32_to_cpu(context->DataLength) <
- sizeof(struct create_durable_reconn_v2_req)) {
+ sizeof(struct create_durable_handle_reconnect_v2)) {
err = -EINVAL;
goto out;
}
- recon_v2 = (struct create_durable_reconn_v2_req *)context;
- persistent_id = recon_v2->Fid.PersistentFileId;
+ recon_v2 = (struct create_durable_handle_reconnect_v2 *)context;
+ persistent_id = recon_v2->dcontext.Fid.PersistentFileId;
dh_info->fp = ksmbd_lookup_durable_fd(persistent_id);
if (!dh_info->fp) {
ksmbd_debug(SMB, "Failed to get durable handle state\n");
@@ -2842,7 +2842,7 @@ static int parse_durable_handle_context(struct ksmbd_work *work,
goto out;
}
- if (memcmp(dh_info->fp->create_guid, recon_v2->CreateGuid,
+ if (memcmp(dh_info->fp->create_guid, recon_v2->dcontext.CreateGuid,
SMB2_CREATE_GUID_SIZE)) {
err = -EBADF;
ksmbd_put_durable_fd(dh_info->fp);
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 189e0d955b4a5..8ef681f7075ad 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -80,17 +80,6 @@ struct create_durable_reconn_req {
} Data;
} __packed;
-struct create_durable_reconn_v2_req {
- struct create_context_hdr ccontext;
- __u8 Name[8];
- struct {
- __u64 PersistentFileId;
- __u64 VolatileFileId;
- } Fid;
- __u8 CreateGuid[16];
- __le32 Flags;
-} __packed;
-
struct create_alloc_size_req {
struct create_context_hdr ccontext;
__u8 Name[8];
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 016/686] smb: move create_durable_rsp_v2 to common/smb2pdu.h
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (14 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 015/686] smb: move create_durable_handle_reconnect_v2 " Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 017/686] smb: move some duplicate definitions " Greg Kroah-Hartman
` (669 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, Namjae Jeon,
Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 96721fd292264d712b7b9a51752ab87de5035db4 ]
Modify the following places:
- some fields in "struct create_durable_v2_rsp" ->
struct durable_context_v2_rsp
- durable_reconnect_context_v2_rsp -> durable_context_v2_rsp
- create_durable_v2_rsp -> create_durable_rsp_v2
Then move them to common header file.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f8171804a39e ("smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2pdu.h | 6 ------
fs/smb/common/smb2pdu.h | 12 ++++++++++++
fs/smb/server/oplock.c | 8 ++++----
fs/smb/server/smb2ops.c | 6 +++---
fs/smb/server/smb2pdu.h | 6 ------
5 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index a75cde061a67d..be0a4f5b26c2e 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -138,12 +138,6 @@ struct share_redirect_error_context_rsp {
/* Flags */
#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
-/* See MS-SMB2 2.2.14.2.12 */
-struct durable_reconnect_context_v2_rsp {
- __le32 Timeout;
- __le32 Flags; /* see above DHANDLE_FLAG_PERSISTENT */
-} __packed;
-
/* See MS-SMB2 2.2.13.2.5 */
struct crt_twarp_ctxt {
struct create_context_hdr ccontext;
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index 7899e7706318f..52250409efc8e 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -1320,6 +1320,18 @@ struct create_durable_handle_reconnect_v2 {
struct durable_reconnect_context_v2 dcontext;
} __packed;
+/* See MS-SMB2 2.2.14.2.12 */
+struct durable_context_v2_rsp {
+ __le32 Timeout;
+ __le32 Flags; /* see SMB2_DHANDLE_FLAG_PERSISTENT */
+} __packed;
+
+struct create_durable_rsp_v2 {
+ struct create_context_hdr ccontext;
+ __u8 Name[8];
+ struct durable_context_v2_rsp dcontext;
+} __packed;
+
/* See MS-SMB2 2.2.14.2.5 */
struct create_mxac_rsp {
struct create_context_hdr ccontext;
diff --git a/fs/smb/server/oplock.c b/fs/smb/server/oplock.c
index 90cd8c962f785..c6a6c1181be66 100644
--- a/fs/smb/server/oplock.c
+++ b/fs/smb/server/oplock.c
@@ -1858,9 +1858,9 @@ void create_durable_rsp_buf(char *cc)
*/
void create_durable_v2_rsp_buf(char *cc, struct ksmbd_file *fp)
{
- struct create_durable_v2_rsp *buf;
+ struct create_durable_rsp_v2 *buf;
- buf = (struct create_durable_v2_rsp *)cc;
+ buf = (struct create_durable_rsp_v2 *)cc;
memset(buf, 0, sizeof(struct create_durable_rsp));
buf->ccontext.DataOffset = cpu_to_le16(offsetof
(struct create_durable_rsp, Data));
@@ -1874,9 +1874,9 @@ void create_durable_v2_rsp_buf(char *cc, struct ksmbd_file *fp)
buf->Name[2] = '2';
buf->Name[3] = 'Q';
- buf->Timeout = cpu_to_le32(fp->durable_timeout);
+ buf->dcontext.Timeout = cpu_to_le32(fp->durable_timeout);
if (fp->is_persistent)
- buf->Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
+ buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
}
/**
diff --git a/fs/smb/server/smb2ops.c b/fs/smb/server/smb2ops.c
index 4c50b7f57f763..5aa8e63f31902 100644
--- a/fs/smb/server/smb2ops.c
+++ b/fs/smb/server/smb2ops.c
@@ -59,7 +59,7 @@ static struct smb_version_values smb30_server_values = {
.cap_large_files = SMB2_LARGE_FILES,
.create_lease_size = sizeof(struct create_lease_v2),
.create_durable_size = sizeof(struct create_durable_rsp),
- .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
+ .create_durable_v2_size = sizeof(struct create_durable_rsp_v2),
.create_mxac_size = sizeof(struct create_mxac_rsp),
.create_disk_id_size = sizeof(struct create_disk_id_rsp),
.create_posix_size = sizeof(struct create_posix_rsp),
@@ -86,7 +86,7 @@ static struct smb_version_values smb302_server_values = {
.cap_large_files = SMB2_LARGE_FILES,
.create_lease_size = sizeof(struct create_lease_v2),
.create_durable_size = sizeof(struct create_durable_rsp),
- .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
+ .create_durable_v2_size = sizeof(struct create_durable_rsp_v2),
.create_mxac_size = sizeof(struct create_mxac_rsp),
.create_disk_id_size = sizeof(struct create_disk_id_rsp),
.create_posix_size = sizeof(struct create_posix_rsp),
@@ -113,7 +113,7 @@ static struct smb_version_values smb311_server_values = {
.cap_large_files = SMB2_LARGE_FILES,
.create_lease_size = sizeof(struct create_lease_v2),
.create_durable_size = sizeof(struct create_durable_rsp),
- .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
+ .create_durable_v2_size = sizeof(struct create_durable_rsp_v2),
.create_mxac_size = sizeof(struct create_mxac_rsp),
.create_disk_id_size = sizeof(struct create_disk_id_rsp),
.create_posix_size = sizeof(struct create_posix_rsp),
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 8ef681f7075ad..02fbae7531cfd 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -98,12 +98,6 @@ struct create_durable_rsp {
/* See MS-SMB2 2.2.13.2.11 */
/* Flags */
#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
-struct create_durable_v2_rsp {
- struct create_context_hdr ccontext;
- __u8 Name[8];
- __le32 Timeout;
- __le32 Flags;
-} __packed;
/* equivalent of the contents of SMB3.1.1 POSIX open context response */
struct create_posix_rsp {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 017/686] smb: move some duplicate definitions to common/smb2pdu.h
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (15 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 016/686] smb: move create_durable_rsp_v2 " Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 018/686] smb: move list of FileSystemAttributes to common/fscc.h Greg Kroah-Hartman
` (668 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, ZhangGuoDong,
Namjae Jeon, Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: ZhangGuoDong <zhangguodong@kylinos.cn>
[ Upstream commit 1172d8598499a006d172bb24bebaa3fdc99064a8 ]
In order to maintain the code more easily, move duplicate definitions to
common header file.
There are only 4 different definitions, the client uses cpu_to_le16()
but the server does not:
- RSS_CAPABLE
- RDMA_CAPABLE
- INTERNETWORK
- INTERNETWORKV6
The other definitions are exactly the same on both client and server.
The struct smb_hdr is defined in MS-CIFS and MS-SMB, but it's also used by
SMB2 and SMB3, so move it to the common smb2pdu.h.
Co-developed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: ZhangGuoDong <zhangguodong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f8171804a39e ("smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifspdu.h | 135 +----------------------------
fs/smb/client/smb2pdu.h | 21 -----
fs/smb/common/smb2pdu.h | 172 +++++++++++++++++++++++++++++++++++--
fs/smb/server/smb2pdu.c | 8 +-
fs/smb/server/smb2pdu.h | 19 ----
fs/smb/server/smb_common.h | 75 +---------------
6 files changed, 173 insertions(+), 257 deletions(-)
diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
index c86a329e58221..212cd57357ce2 100644
--- a/fs/smb/client/cifspdu.h
+++ b/fs/smb/client/cifspdu.h
@@ -12,6 +12,7 @@
#include <net/sock.h>
#include <linux/unaligned.h>
#include "../common/smbfsctl.h"
+#include "../common/smb2pdu.h"
#define CIFS_PROT 0
#define POSIX_PROT (CIFS_PROT+1)
@@ -180,98 +181,7 @@
#define SMBFLG2_ERR_STATUS cpu_to_le16(0x4000)
#define SMBFLG2_UNICODE cpu_to_le16(0x8000)
-/*
- * These are the file access permission bits defined in CIFS for the
- * NTCreateAndX as well as the level 0x107
- * TRANS2_QUERY_PATH_INFORMATION API. The level 0x107, SMB_QUERY_FILE_ALL_INFO
- * responds with the AccessFlags.
- * The AccessFlags specifies the access permissions a caller has to the
- * file and can have any suitable combination of the following values:
- */
-
-#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
- /* or directory child entries can */
- /* be listed together with the */
- /* associated child attributes */
- /* (so the FILE_READ_ATTRIBUTES on */
- /* the child entry is not needed) */
-#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
- /* or new file can be created in */
- /* the directory */
-#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
- /* (for non-local files over SMB it */
- /* is same as FILE_WRITE_DATA) */
- /* or new subdirectory can be */
- /* created in the directory */
-#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
- /* with the file can be read */
-#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
- /* with the file can be written */
-#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
- /* the file using system paging I/O */
- /* for executing the file / script */
- /* or right to traverse directory */
- /* (but by default all users have */
- /* directory bypass traverse */
- /* privilege and do not need this */
- /* permission on directories at all)*/
-#define FILE_DELETE_CHILD 0x00000040 /* Child entry can be deleted from */
- /* the directory (so the DELETE on */
- /* the child entry is not needed) */
-#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
- /* file or directory can be read */
-#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
- /* file or directory can be written */
-#define DELETE 0x00010000 /* The file or dir can be deleted */
-#define READ_CONTROL 0x00020000 /* The discretionary access control */
- /* list and ownership associated */
- /* with the file or dir can be read */
-#define WRITE_DAC 0x00040000 /* The discretionary access control */
- /* list associated with the file or */
- /* directory can be written */
-#define WRITE_OWNER 0x00080000 /* Ownership information associated */
- /* with the file/dir can be written */
-#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
- /* synchronize with the completion */
- /* of an input/output request */
-#define SYSTEM_SECURITY 0x01000000 /* The system access control list */
- /* associated with the file or */
- /* directory can be read or written */
- /* (cannot be in DACL, can in SACL) */
-#define MAXIMUM_ALLOWED 0x02000000 /* Maximal subset of GENERIC_ALL */
- /* permissions which can be granted */
- /* (cannot be in DACL nor SACL) */
-#define GENERIC_ALL 0x10000000 /* Same as: GENERIC_EXECUTE | */
- /* GENERIC_WRITE | */
- /* GENERIC_READ | */
- /* FILE_DELETE_CHILD | */
- /* DELETE | */
- /* WRITE_DAC | */
- /* WRITE_OWNER */
- /* So GENERIC_ALL contains all bits */
- /* mentioned above except these two */
- /* SYSTEM_SECURITY MAXIMUM_ALLOWED */
-#define GENERIC_EXECUTE 0x20000000 /* Same as: FILE_EXECUTE | */
- /* FILE_READ_ATTRIBUTES | */
- /* READ_CONTROL | */
- /* SYNCHRONIZE */
-#define GENERIC_WRITE 0x40000000 /* Same as: FILE_WRITE_DATA | */
- /* FILE_APPEND_DATA | */
- /* FILE_WRITE_EA | */
- /* FILE_WRITE_ATTRIBUTES | */
- /* READ_CONTROL | */
- /* SYNCHRONIZE */
-#define GENERIC_READ 0x80000000 /* Same as: FILE_READ_DATA | */
- /* FILE_READ_EA | */
- /* FILE_READ_ATTRIBUTES | */
- /* READ_CONTROL | */
- /* SYNCHRONIZE */
-
-#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES)
-#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
- | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
-#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
-
+/* Combinations of file access permission bits */
#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \
| FILE_READ_ATTRIBUTES \
| FILE_WRITE_ATTRIBUTES \
@@ -283,15 +193,6 @@
| FILE_WRITE_ATTRIBUTES \
| DELETE | READ_CONTROL | WRITE_DAC \
| WRITE_OWNER | SYNCHRONIZE)
-#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
- | FILE_READ_ATTRIBUTES \
- | FILE_WRITE_ATTRIBUTES \
- | DELETE | READ_CONTROL | WRITE_DAC \
- | WRITE_OWNER | SYNCHRONIZE)
-
-#define SET_MINIMUM_RIGHTS (FILE_READ_EA | FILE_READ_ATTRIBUTES \
- | READ_CONTROL | SYNCHRONIZE)
-
/*
* Invalid readdir handle
@@ -417,38 +318,6 @@
#define GETU16(var) (*((__u16 *)var)) /* BB check for endian issues */
#define GETU32(var) (*((__u32 *)var)) /* BB check for endian issues */
-struct smb_hdr {
- __be32 smb_buf_length; /* BB length is only two (rarely three) bytes,
- with one or two byte "type" preceding it that will be
- zero - we could mask the type byte off */
- __u8 Protocol[4];
- __u8 Command;
- union {
- struct {
- __u8 ErrorClass;
- __u8 Reserved;
- __le16 Error;
- } __attribute__((packed)) DosError;
- __le32 CifsError;
- } __attribute__((packed)) Status;
- __u8 Flags;
- __le16 Flags2; /* note: le */
- __le16 PidHigh;
- union {
- struct {
- __le32 SequenceNumber; /* le */
- __u32 Reserved; /* zero */
- } __attribute__((packed)) Sequence;
- __u8 SecuritySignature[8]; /* le */
- } __attribute__((packed)) Signature;
- __u8 pad[2];
- __u16 Tid;
- __le16 Pid;
- __u16 Uid;
- __le16 Mid;
- __u8 WordCount;
-} __attribute__((packed));
-
/* given a pointer to an smb_hdr, retrieve a void pointer to the ByteCount */
static inline void *
BCC(struct smb_hdr *smb)
diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index be0a4f5b26c2e..311758398b436 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -133,11 +133,6 @@ struct share_redirect_error_context_rsp {
#define SMB2_LEASE_HANDLE_CACHING_HE 0x02
#define SMB2_LEASE_WRITE_CACHING_HE 0x04
-
-/* See MS-SMB2 2.2.13.2.11 */
-/* Flags */
-#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
-
/* See MS-SMB2 2.2.13.2.5 */
struct crt_twarp_ctxt {
struct create_context_hdr ccontext;
@@ -204,22 +199,6 @@ struct network_resiliency_req {
} __packed;
/* There is no buffer for the response ie no struct network_resiliency_rsp */
-#define RSS_CAPABLE cpu_to_le32(0x00000001)
-#define RDMA_CAPABLE cpu_to_le32(0x00000002)
-
-#define INTERNETWORK cpu_to_le16(0x0002)
-#define INTERNETWORKV6 cpu_to_le16(0x0017)
-
-struct network_interface_info_ioctl_rsp {
- __le32 Next; /* next interface. zero if this is last one */
- __le32 IfIndex;
- __le32 Capability; /* RSS or RDMA Capable */
- __le32 Reserved;
- __le64 LinkSpeed;
- __le16 Family;
- __u8 Buffer[126];
-} __packed;
-
#define NO_FILE_ID 0xFFFFFFFFFFFFFFFFULL /* general ioctls to srv not to file */
struct compress_ioctl {
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index 52250409efc8e..7377b5a9f8a55 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -1149,12 +1149,6 @@ struct smb2_server_client_notification {
#define FILE_OVERWRITE_IF_LE cpu_to_le32(0x00000005)
#define FILE_CREATE_MASK_LE cpu_to_le32(0x00000007)
-#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA \
- | FILE_READ_ATTRIBUTES)
-#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
- | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
-#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
-
/* CreateOptions Flags */
#define FILE_DIRECTORY_FILE_LE cpu_to_le32(0x00000001)
/* same as #define CREATE_NOT_FILE_LE cpu_to_le32(0x00000001) */
@@ -1290,6 +1284,14 @@ struct create_mxac_req {
__le64 Timestamp;
} __packed;
+/*
+ * Flags
+ * See MS-SMB2 2.2.13.2.11
+ * MS-SMB2 2.2.13.2.12
+ * MS-SMB2 2.2.14.2.12
+ */
+#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
+
/* See MS-SMB2 2.2.13.2.11 */
struct durable_context_v2_req {
__le32 Timeout;
@@ -1490,6 +1492,26 @@ struct smb_sockaddr_in6 {
__be32 ScopeId;
} __packed;
+/* See MS-SMB2 2.2.32.5 and MS-SMB2 2.2.32.5.1 */
+#define RSS_CAPABLE cpu_to_le32(0x00000001)
+#define RDMA_CAPABLE cpu_to_le32(0x00000002)
+#define INTERNETWORK cpu_to_le16(0x0002)
+#define INTERNETWORKV6 cpu_to_le16(0x0017)
+struct network_interface_info_ioctl_rsp {
+ __le32 Next; /* next interface. zero if this is last one */
+ __le32 IfIndex;
+ __le32 Capability; /* RSS or RDMA Capable */
+ __le32 Reserved;
+ __le64 LinkSpeed;
+ union {
+ char SockAddr_Storage[128];
+ struct {
+ __le16 Family;
+ __u8 Buffer[126];
+ };
+ };
+} __packed;
+
/* this goes in the ioctl buffer when doing FSCTL_SET_ZERO_DATA */
struct file_zero_data_information {
__le64 FileOffset;
@@ -1979,6 +2001,144 @@ struct smb2_lease_ack {
__le64 LeaseDuration;
} __packed;
+/*
+ * See MS-CIFS 2.2.3.1
+ * MS-SMB 2.2.3.1
+ */
+struct smb_hdr {
+ __be32 smb_buf_length; /* BB length is only two (rarely three) bytes,
+ with one or two byte "type" preceding it that will be
+ zero - we could mask the type byte off */
+ __u8 Protocol[4];
+ __u8 Command;
+ union {
+ struct {
+ __u8 ErrorClass;
+ __u8 Reserved;
+ __le16 Error;
+ } __packed DosError;
+ __le32 CifsError;
+ } __packed Status;
+ __u8 Flags;
+ __le16 Flags2; /* note: le */
+ __le16 PidHigh;
+ union {
+ struct {
+ __le32 SequenceNumber; /* le */
+ __u32 Reserved; /* zero */
+ } __packed Sequence;
+ __u8 SecuritySignature[8]; /* le */
+ } __packed Signature;
+ __u8 pad[2];
+ __u16 Tid;
+ __le16 Pid;
+ __u16 Uid;
+ __le16 Mid;
+ __u8 WordCount;
+} __packed;
+
#define OP_BREAK_STRUCT_SIZE_20 24
#define OP_BREAK_STRUCT_SIZE_21 36
+
+/*
+ * See MS-SMB2 2.2.13.1.1
+ * MS-SMB 2.2.1.4.1
+ * These are the file access permission bits defined in CIFS for the
+ * NTCreateAndX as well as the level 0x107
+ * TRANS2_QUERY_PATH_INFORMATION API. The level 0x107, SMB_QUERY_FILE_ALL_INFO
+ * responds with the AccessFlags.
+ * The AccessFlags specifies the access permissions a caller has to the
+ * file and can have any suitable combination of the following values:
+ */
+#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
+ /* or directory child entries can */
+ /* be listed together with the */
+ /* associated child attributes */
+ /* (so the FILE_READ_ATTRIBUTES on */
+ /* the child entry is not needed) */
+#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
+ /* or new file can be created in */
+ /* the directory */
+#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
+ /* (for non-local files over SMB it */
+ /* is same as FILE_WRITE_DATA) */
+ /* or new subdirectory can be */
+ /* created in the directory */
+#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
+ /* with the file can be read */
+#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
+ /* with the file can be written */
+#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
+ /* the file using system paging I/O */
+ /* for executing the file / script */
+ /* or right to traverse directory */
+ /* (but by default all users have */
+ /* directory bypass traverse */
+ /* privilege and do not need this */
+ /* permission on directories at all)*/
+#define FILE_DELETE_CHILD 0x00000040 /* Child entry can be deleted from */
+ /* the directory (so the DELETE on */
+ /* the child entry is not needed) */
+#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
+ /* file or directory can be read */
+#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
+ /* file or directory can be written */
+#define DELETE 0x00010000 /* The file or dir can be deleted */
+#define READ_CONTROL 0x00020000 /* The discretionary access control */
+ /* list and ownership associated */
+ /* with the file or dir can be read */
+#define WRITE_DAC 0x00040000 /* The discretionary access control */
+ /* list associated with the file or */
+ /* directory can be written */
+#define WRITE_OWNER 0x00080000 /* Ownership information associated */
+ /* with the file/dir can be written */
+#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
+ /* synchronize with the completion */
+ /* of an input/output request */
+#define SYSTEM_SECURITY 0x01000000 /* The system access control list */
+ /* associated with the file or */
+ /* directory can be read or written */
+ /* (cannot be in DACL, can in SACL) */
+#define MAXIMUM_ALLOWED 0x02000000 /* Maximal subset of GENERIC_ALL */
+ /* permissions which can be granted */
+ /* (cannot be in DACL nor SACL) */
+#define GENERIC_ALL 0x10000000 /* Same as: GENERIC_EXECUTE | */
+ /* GENERIC_WRITE | */
+ /* GENERIC_READ | */
+ /* FILE_DELETE_CHILD | */
+ /* DELETE | */
+ /* WRITE_DAC | */
+ /* WRITE_OWNER */
+ /* So GENERIC_ALL contains all bits */
+ /* mentioned above except these two */
+ /* SYSTEM_SECURITY MAXIMUM_ALLOWED */
+#define GENERIC_EXECUTE 0x20000000 /* Same as: FILE_EXECUTE | */
+ /* FILE_READ_ATTRIBUTES | */
+ /* READ_CONTROL | */
+ /* SYNCHRONIZE */
+#define GENERIC_WRITE 0x40000000 /* Same as: FILE_WRITE_DATA | */
+ /* FILE_APPEND_DATA | */
+ /* FILE_WRITE_EA | */
+ /* FILE_WRITE_ATTRIBUTES | */
+ /* READ_CONTROL | */
+ /* SYNCHRONIZE */
+#define GENERIC_READ 0x80000000 /* Same as: FILE_READ_DATA | */
+ /* FILE_READ_EA | */
+ /* FILE_READ_ATTRIBUTES | */
+ /* READ_CONTROL | */
+ /* SYNCHRONIZE */
+
+/* Combinations of file access permission bits */
+#define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES)
+#define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
+ | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
+#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
+#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
+ | FILE_READ_ATTRIBUTES \
+ | FILE_WRITE_ATTRIBUTES \
+ | DELETE | READ_CONTROL | WRITE_DAC \
+ | WRITE_OWNER | SYNCHRONIZE)
+#define SET_MINIMUM_RIGHTS (FILE_READ_EA | FILE_READ_ATTRIBUTES \
+ | READ_CONTROL | SYNCHRONIZE)
+
#endif /* _COMMON_SMB2PDU_H */
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index d16df43f7c772..33b4708cc214c 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -8263,9 +8263,9 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
nii_rsp->Capability = 0;
if (netdev->real_num_tx_queues > 1)
- nii_rsp->Capability |= cpu_to_le32(RSS_CAPABLE);
+ nii_rsp->Capability |= RSS_CAPABLE;
if (ksmbd_rdma_capable_netdev(netdev))
- nii_rsp->Capability |= cpu_to_le32(RDMA_CAPABLE);
+ nii_rsp->Capability |= RDMA_CAPABLE;
nii_rsp->Next = cpu_to_le32(152);
nii_rsp->Reserved = 0;
@@ -8291,7 +8291,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
if (!ipv4_set) {
struct in_device *idev;
- sockaddr_storage->Family = cpu_to_le16(INTERNETWORK);
+ sockaddr_storage->Family = INTERNETWORK;
sockaddr_storage->addr4.Port = 0;
idev = __in_dev_get_rtnl(netdev);
@@ -8307,7 +8307,7 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn,
struct inet6_ifaddr *ifa;
__u8 *ipv6_addr = sockaddr_storage->addr6.IPv6Address;
- sockaddr_storage->Family = cpu_to_le16(INTERNETWORKV6);
+ sockaddr_storage->Family = INTERNETWORKV6;
sockaddr_storage->addr6.Port = 0;
sockaddr_storage->addr6.FlowInfo = 0;
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 02fbae7531cfd..0a294378c73d3 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -95,10 +95,6 @@ struct create_durable_rsp {
} Data;
} __packed;
-/* See MS-SMB2 2.2.13.2.11 */
-/* Flags */
-#define SMB2_DHANDLE_FLAG_PERSISTENT 0x00000002
-
/* equivalent of the contents of SMB3.1.1 POSIX open context response */
struct create_posix_rsp {
struct create_context_hdr ccontext;
@@ -112,9 +108,6 @@ struct create_posix_rsp {
#define SMB2_0_IOCTL_IS_FSCTL 0x00000001
-#define INTERNETWORK 0x0002
-#define INTERNETWORKV6 0x0017
-
struct sockaddr_storage_rsp {
__le16 Family;
union {
@@ -123,18 +116,6 @@ struct sockaddr_storage_rsp {
};
} __packed;
-#define RSS_CAPABLE 0x00000001
-#define RDMA_CAPABLE 0x00000002
-
-struct network_interface_info_ioctl_rsp {
- __le32 Next; /* next interface. zero if this is last one */
- __le32 IfIndex;
- __le32 Capability; /* RSS or RDMA Capable */
- __le32 Reserved;
- __le64 LinkSpeed;
- char SockAddr_Storage[128];
-} __packed;
-
struct file_object_buf_type1_ioctl_rsp {
__u8 ObjectId[16];
__u8 BirthVolumeId[16];
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 95062e922de93..4568896273bec 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -77,42 +77,7 @@
#define FILE_CASE_PRESERVED_NAMES 0x00000002
#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
-#define FILE_READ_DATA 0x00000001 /* Data can be read from the file */
-#define FILE_WRITE_DATA 0x00000002 /* Data can be written to the file */
-#define FILE_APPEND_DATA 0x00000004 /* Data can be appended to the file */
-#define FILE_READ_EA 0x00000008 /* Extended attributes associated */
-/* with the file can be read */
-#define FILE_WRITE_EA 0x00000010 /* Extended attributes associated */
-/* with the file can be written */
-#define FILE_EXECUTE 0x00000020 /*Data can be read into memory from */
-/* the file using system paging I/O */
-#define FILE_DELETE_CHILD 0x00000040
-#define FILE_READ_ATTRIBUTES 0x00000080 /* Attributes associated with the */
-/* file can be read */
-#define FILE_WRITE_ATTRIBUTES 0x00000100 /* Attributes associated with the */
-/* file can be written */
-#define DELETE 0x00010000 /* The file can be deleted */
-#define READ_CONTROL 0x00020000 /* The access control list and */
-/* ownership associated with the */
-/* file can be read */
-#define WRITE_DAC 0x00040000 /* The access control list and */
-/* ownership associated with the */
-/* file can be written. */
-#define WRITE_OWNER 0x00080000 /* Ownership information associated */
-/* with the file can be written */
-#define SYNCHRONIZE 0x00100000 /* The file handle can waited on to */
-/* synchronize with the completion */
-/* of an input/output request */
-#define GENERIC_ALL 0x10000000
-#define GENERIC_EXECUTE 0x20000000
-#define GENERIC_WRITE 0x40000000
-#define GENERIC_READ 0x80000000
-/* In summary - Relevant file */
-/* access flags from CIFS are */
-/* file_read_data, file_write_data */
-/* file_execute, file_read_attributes*/
-/* write_dac, and delete. */
-
+/* Combinations of file access permission bits */
#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA \
| FILE_READ_ATTRIBUTES \
| DELETE | READ_CONTROL | WRITE_DAC \
@@ -123,14 +88,6 @@
| FILE_WRITE_ATTRIBUTES \
| DELETE | READ_CONTROL | WRITE_DAC \
| WRITE_OWNER | SYNCHRONIZE)
-#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
- | FILE_READ_ATTRIBUTES \
- | FILE_WRITE_ATTRIBUTES \
- | DELETE | READ_CONTROL | WRITE_DAC \
- | WRITE_OWNER | SYNCHRONIZE)
-
-#define SET_MINIMUM_RIGHTS (FILE_READ_EA | FILE_READ_ATTRIBUTES \
- | READ_CONTROL | SYNCHRONIZE)
/* generic flags for file open */
#define GENERIC_READ_FLAGS (READ_CONTROL | FILE_READ_DATA | \
@@ -162,36 +119,6 @@
#define SMBFLG2_ERR_STATUS cpu_to_le16(0x4000)
#define SMBFLG2_UNICODE cpu_to_le16(0x8000)
-struct smb_hdr {
- __be32 smb_buf_length;
- __u8 Protocol[4];
- __u8 Command;
- union {
- struct {
- __u8 ErrorClass;
- __u8 Reserved;
- __le16 Error;
- } __packed DosError;
- __le32 CifsError;
- } __packed Status;
- __u8 Flags;
- __le16 Flags2; /* note: le */
- __le16 PidHigh;
- union {
- struct {
- __le32 SequenceNumber; /* le */
- __u32 Reserved; /* zero */
- } __packed Sequence;
- __u8 SecuritySignature[8]; /* le */
- } __packed Signature;
- __u8 pad[2];
- __le16 Tid;
- __le16 Pid;
- __le16 Uid;
- __le16 Mid;
- __u8 WordCount;
-} __packed;
-
struct smb_negotiate_req {
struct smb_hdr hdr; /* wct = 0 */
__le16 ByteCount;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 018/686] smb: move list of FileSystemAttributes to common/fscc.h
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (16 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 017/686] smb: move some duplicate definitions " Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 019/686] smb: move some duplicate struct definitions " Greg Kroah-Hartman
` (667 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, Namjae Jeon,
Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 84d8d4cf8873b4a9da0d76e9ba9d94ec88311cfd ]
These definitions are exactly the same on both client and server,
so move them to new common header file.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f8171804a39e ("smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsglob.h | 1 +
fs/smb/client/cifspdu.h | 27 ------------------------
fs/smb/common/fscc.h | 42 ++++++++++++++++++++++++++++++++++++++
fs/smb/server/smb_common.h | 28 +------------------------
4 files changed, 44 insertions(+), 54 deletions(-)
create mode 100644 fs/smb/common/fscc.h
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h
index d529446e4984b..2d5a4a26c931e 100644
--- a/fs/smb/client/cifsglob.h
+++ b/fs/smb/client/cifsglob.h
@@ -28,6 +28,7 @@
#include <uapi/linux/cifs/cifs_mount.h>
#include "../common/cifsglob.h"
#include "../common/smb2pdu.h"
+#include "../common/fscc.h"
#include "smb2pdu.h"
#include <linux/filelock.h>
diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
index 212cd57357ce2..3ea8aa2a8d2db 100644
--- a/fs/smb/client/cifspdu.h
+++ b/fs/smb/client/cifspdu.h
@@ -2100,33 +2100,6 @@ typedef struct {
/* minimum includes first three fields, and empty FS Name */
#define MIN_FS_ATTR_INFO_SIZE 12
-
-/* List of FileSystemAttributes - see 2.5.1 of MS-FSCC */
-#define FILE_SUPPORTS_SPARSE_VDL 0x10000000 /* faster nonsparse extend */
-#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 /* allow ioctl dup extents */
-#define FILE_SUPPORT_INTEGRITY_STREAMS 0x04000000
-#define FILE_SUPPORTS_USN_JOURNAL 0x02000000
-#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
-#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000
-#define FILE_SUPPORTS_HARD_LINKS 0x00400000
-#define FILE_SUPPORTS_TRANSACTIONS 0x00200000
-#define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000
-#define FILE_READ_ONLY_VOLUME 0x00080000
-#define FILE_NAMED_STREAMS 0x00040000
-#define FILE_SUPPORTS_ENCRYPTION 0x00020000
-#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
-#define FILE_VOLUME_IS_COMPRESSED 0x00008000
-#define FILE_SUPPORTS_POSIX_UNLINK_RENAME 0x00000400
-#define FILE_RETURNS_CLEANUP_RESULT_INFO 0x00000200
-#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
-#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
-#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
-#define FILE_VOLUME_QUOTAS 0x00000020
-#define FILE_FILE_COMPRESSION 0x00000010
-#define FILE_PERSISTENT_ACLS 0x00000008
-#define FILE_UNICODE_ON_DISK 0x00000004
-#define FILE_CASE_PRESERVED_NAMES 0x00000002
-#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
typedef struct {
__le32 Attributes;
__le32 MaxPathNameComponentLength;
diff --git a/fs/smb/common/fscc.h b/fs/smb/common/fscc.h
new file mode 100644
index 0000000000000..c8bfb87232ac0
--- /dev/null
+++ b/fs/smb/common/fscc.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: LGPL-2.1 */
+/*
+ *
+ * Copyright (c) International Business Machines Corp., 2009, 2013
+ * Etersoft, 2012
+ * 2018 Samsung Electronics Co., Ltd.
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ * Pavel Shilovsky (pshilovsky@samba.org) 2012
+ * Namjae Jeon (linkinjeon@kernel.org)
+ *
+ */
+#ifndef _COMMON_SMB_FSCC_H
+#define _COMMON_SMB_FSCC_H
+
+/* List of FileSystemAttributes - see MS-FSCC 2.5.1 */
+#define FILE_SUPPORTS_SPARSE_VDL 0x10000000 /* faster nonsparse extend */
+#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 /* allow ioctl dup extents */
+#define FILE_SUPPORT_INTEGRITY_STREAMS 0x04000000
+#define FILE_SUPPORTS_USN_JOURNAL 0x02000000
+#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
+#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000
+#define FILE_SUPPORTS_HARD_LINKS 0x00400000
+#define FILE_SUPPORTS_TRANSACTIONS 0x00200000
+#define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000
+#define FILE_READ_ONLY_VOLUME 0x00080000
+#define FILE_NAMED_STREAMS 0x00040000
+#define FILE_SUPPORTS_ENCRYPTION 0x00020000
+#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
+#define FILE_VOLUME_IS_COMPRESSED 0x00008000
+#define FILE_SUPPORTS_POSIX_UNLINK_RENAME 0x00000400
+#define FILE_RETURNS_CLEANUP_RESULT_INFO 0x00000200
+#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
+#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
+#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
+#define FILE_VOLUME_QUOTAS 0x00000020
+#define FILE_FILE_COMPRESSION 0x00000010
+#define FILE_PERSISTENT_ACLS 0x00000008
+#define FILE_UNICODE_ON_DISK 0x00000004
+#define FILE_CASE_PRESERVED_NAMES 0x00000002
+#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
+
+#endif /* _COMMON_SMB_FSCC_H */
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index 4568896273bec..bea0a250169c3 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -12,6 +12,7 @@
#include "nterr.h"
#include "../common/cifsglob.h"
#include "../common/smb2pdu.h"
+#include "../common/fscc.h"
#include "smb2pdu.h"
/* ksmbd's Specific ERRNO */
@@ -50,33 +51,6 @@
#define ATTR_NO_BUFFERING 0x20000000
#define ATTR_WRITE_THROUGH 0x80000000
-/* List of FileSystemAttributes - see 2.5.1 of MS-FSCC */
-#define FILE_SUPPORTS_SPARSE_VDL 0x10000000 /* faster nonsparse extend */
-#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 /* allow ioctl dup extents */
-#define FILE_SUPPORT_INTEGRITY_STREAMS 0x04000000
-#define FILE_SUPPORTS_USN_JOURNAL 0x02000000
-#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
-#define FILE_SUPPORTS_EXTENDED_ATTRIBUTES 0x00800000
-#define FILE_SUPPORTS_HARD_LINKS 0x00400000
-#define FILE_SUPPORTS_TRANSACTIONS 0x00200000
-#define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000
-#define FILE_READ_ONLY_VOLUME 0x00080000
-#define FILE_NAMED_STREAMS 0x00040000
-#define FILE_SUPPORTS_ENCRYPTION 0x00020000
-#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
-#define FILE_VOLUME_IS_COMPRESSED 0x00008000
-#define FILE_SUPPORTS_POSIX_UNLINK_RENAME 0x00000400
-#define FILE_RETURNS_CLEANUP_RESULT_INFO 0x00000200
-#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
-#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
-#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
-#define FILE_VOLUME_QUOTAS 0x00000020
-#define FILE_FILE_COMPRESSION 0x00000010
-#define FILE_PERSISTENT_ACLS 0x00000008
-#define FILE_UNICODE_ON_DISK 0x00000004
-#define FILE_CASE_PRESERVED_NAMES 0x00000002
-#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
-
/* Combinations of file access permission bits */
#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA \
| FILE_READ_ATTRIBUTES \
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 019/686] smb: move some duplicate struct definitions to common/fscc.h
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (17 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 018/686] smb: move list of FileSystemAttributes to common/fscc.h Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 020/686] smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2 Greg Kroah-Hartman
` (666 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChenXiaoSong, Namjae Jeon,
Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit d7edd3892d97e6746e30f36f4f13f887ec4d80ed ]
Modify the following places:
- smb2_file_ntwrk_info -> smb2_file_network_open_info
- struct filesystem_device_info -> FILE_SYSTEM_DEVICE_INFO
- struct file_directory_info -> FILE_DIRECTORY_INFO
- struct file_full_directory_info -> FILE_FULL_DIRECTORY_INFO
- struct file_both_directory_info -> FILE_BOTH_DIRECTORY_INFO
- struct file_id_full_dir_info -> FILE_ID_FULL_DIR_INFO
- struct filesystem_posix_info -> FILE_SYSTEM_POSIX_INFO
The fields of these structures are exactly the same on both client and
server, so move duplicate definitions to common header file.
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Stable-dep-of: f8171804a39e ("smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifspdu.h | 91 -----------------------------
fs/smb/client/inode.c | 4 +-
fs/smb/client/readdir.c | 2 +-
fs/smb/client/smb2pdu.c | 2 +-
fs/smb/client/smb2pdu.h | 13 -----
fs/smb/common/fscc.h | 115 +++++++++++++++++++++++++++++++++++++
fs/smb/server/smb2pdu.c | 72 +++++++++++------------
fs/smb/server/smb2pdu.h | 11 ----
fs/smb/server/smb_common.h | 92 -----------------------------
fs/smb/server/vfs.c | 2 +-
10 files changed, 156 insertions(+), 248 deletions(-)
diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h
index 3ea8aa2a8d2db..c5c890cf3605a 100644
--- a/fs/smb/client/cifspdu.h
+++ b/fs/smb/client/cifspdu.h
@@ -2036,28 +2036,6 @@ typedef struct {
#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */
-typedef struct {
- /* For undefined recommended transfer size return -1 in that field */
- __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
- __le32 BlockSize;
- /* The next three fields are in terms of the block size.
- (above). If block size is unknown, 4096 would be a
- reasonable block size for a server to report.
- Note that returning the blocks/blocksavail removes need
- to make a second call (to QFSInfo level 0x103 to get this info.
- UserBlockAvail is typically less than or equal to BlocksAvail,
- if no distinction is made return the same value in each */
- __le64 TotalBlocks;
- __le64 BlocksAvail; /* bfree */
- __le64 UserBlocksAvail; /* bavail */
- /* For undefined Node fields or FSID return -1 */
- __le64 TotalFileNodes;
- __le64 FreeFileNodes;
- __le64 FileSysIdentifier; /* fsid */
- /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */
- /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */
-} __attribute__((packed)) FILE_SYSTEM_POSIX_INFO;
-
/* DeviceType Flags */
#define FILE_DEVICE_CD_ROM 0x00000002
#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
@@ -2092,11 +2070,6 @@ typedef struct {
#define FILE_PORTABLE_DEVICE 0x00004000
#define FILE_DEVICE_ALLOW_APPCONTAINER_TRAVERSAL 0x00020000
-typedef struct {
- __le32 DeviceType;
- __le32 DeviceCharacteristics;
-} __attribute__((packed)) FILE_SYSTEM_DEVICE_INFO; /* device info level 0x104 */
-
/* minimum includes first three fields, and empty FS Name */
#define MIN_FS_ATTR_INFO_SIZE 12
@@ -2332,70 +2305,6 @@ typedef struct {
};
} __attribute__((packed)) FILE_UNIX_INFO; /* level 0x202 */
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- char FileName[];
-} __attribute__((packed)) FILE_DIRECTORY_INFO; /* level 0x101 FF resp data */
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* length of the xattrs */
- char FileName[];
-} __attribute__((packed)) FILE_FULL_DIRECTORY_INFO; /* level 0x102 rsp data */
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* EA size */
- __le32 Reserved;
- __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
- char FileName[];
-} __attribute__((packed)) SEARCH_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */
-
-typedef struct {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* length of the xattrs */
- __u8 ShortNameLength;
- __u8 Reserved;
- __u8 ShortName[24];
- char FileName[];
-} __attribute__((packed)) FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FFrsp data */
-
typedef struct {
__u32 ResumeKey;
__le16 CreationDate; /* SMB Date */
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 7c638b8d5490f..d9c502efe84bc 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -1348,7 +1348,7 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
/* for easier reading */
FILE_ALL_INFO *fi;
FILE_DIRECTORY_INFO *fdi;
- SEARCH_ID_FULL_DIR_INFO *si;
+ FILE_ID_FULL_DIR_INFO *si;
rc = cifs_backup_query_path_info(xid, tcon, sb,
full_path,
@@ -1359,7 +1359,7 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
move_cifs_info_to_smb2(&data->fi, fi);
fdi = (FILE_DIRECTORY_INFO *)fi;
- si = (SEARCH_ID_FULL_DIR_INFO *)fi;
+ si = (FILE_ID_FULL_DIR_INFO *)fi;
cifs_dir_info_to_fattr(fattr, fdi, cifs_sb);
fattr->cf_uniqueid = le64_to_cpu(si->UniqueId);
diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
index b19c36f6a78b4..cf6b440f757b6 100644
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -559,7 +559,7 @@ static void cifs_fill_dirent_full(struct cifs_dirent *de,
}
static void cifs_fill_dirent_search(struct cifs_dirent *de,
- const SEARCH_ID_FULL_DIR_INFO *info)
+ const FILE_ID_FULL_DIR_INFO *info)
{
de->name = &info->FileName[0];
de->namelen = le32_to_cpu(info->FileNameLength);
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index d8c97c1c63b5f..d0c56caed1626 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -5576,7 +5576,7 @@ smb2_parse_query_directory(struct cifs_tcon *tcon,
info_buf_size = sizeof(FILE_DIRECTORY_INFO);
break;
case SMB_FIND_FILE_ID_FULL_DIR_INFO:
- info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO);
+ info_buf_size = sizeof(FILE_ID_FULL_DIR_INFO);
break;
case SMB_FIND_FILE_POSIX_INFO:
/* note that posix payload are variable size */
diff --git a/fs/smb/client/smb2pdu.h b/fs/smb/client/smb2pdu.h
index 311758398b436..2a2f52be7d6f1 100644
--- a/fs/smb/client/smb2pdu.h
+++ b/fs/smb/client/smb2pdu.h
@@ -230,19 +230,6 @@ struct smb2_file_reparse_point_info {
__le32 Tag;
} __packed;
-struct smb2_file_network_open_info {
- struct_group_attr(network_open_info, __packed,
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 AllocationSize;
- __le64 EndOfFile;
- __le32 Attributes;
- );
- __le32 Reserved;
-} __packed; /* level 34 Query also similar returned in close rsp and open rsp */
-
/* See MS-FSCC 2.4.21 */
struct smb2_file_id_information {
__le64 VolumeSerialNumber;
diff --git a/fs/smb/common/fscc.h b/fs/smb/common/fscc.h
index c8bfb87232ac0..6fa7c65d304b5 100644
--- a/fs/smb/common/fscc.h
+++ b/fs/smb/common/fscc.h
@@ -12,6 +12,88 @@
#ifndef _COMMON_SMB_FSCC_H
#define _COMMON_SMB_FSCC_H
+/* See MS-FSCC 2.4.8 */
+typedef struct {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize; /* length of the xattrs */
+ __u8 ShortNameLength;
+ __u8 Reserved;
+ __u8 ShortName[24];
+ char FileName[];
+} __packed FILE_BOTH_DIRECTORY_INFO; /* level 0x104 FFrsp data */
+
+/* See MS-FSCC 2.4.10 */
+typedef struct {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ char FileName[];
+} __packed FILE_DIRECTORY_INFO; /* level 0x101 FF resp data */
+
+/* See MS-FSCC 2.4.14 */
+typedef struct {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize; /* length of the xattrs */
+ char FileName[];
+} __packed FILE_FULL_DIRECTORY_INFO; /* level 0x102 rsp data */
+
+/* See MS-FSCC 2.4.24 */
+typedef struct {
+ __le32 NextEntryOffset;
+ __u32 FileIndex;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 EndOfFile;
+ __le64 AllocationSize;
+ __le32 ExtFileAttributes;
+ __le32 FileNameLength;
+ __le32 EaSize; /* EA size */
+ __le32 Reserved;
+ __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
+ char FileName[];
+} __packed FILE_ID_FULL_DIR_INFO; /* level 0x105 FF rsp data */
+
+/* See MS-FSCC 2.4.34 */
+struct smb2_file_network_open_info {
+ struct_group_attr(network_open_info, __packed,
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 AllocationSize;
+ __le64 EndOfFile;
+ __le32 Attributes;
+ );
+ __le32 Reserved;
+} __packed; /* level 34 Query also similar returned in close rsp and open rsp */
+
/* List of FileSystemAttributes - see MS-FSCC 2.5.1 */
#define FILE_SUPPORTS_SPARSE_VDL 0x10000000 /* faster nonsparse extend */
#define FILE_SUPPORTS_BLOCK_REFCOUNTING 0x08000000 /* allow ioctl dup extents */
@@ -39,4 +121,37 @@
#define FILE_CASE_PRESERVED_NAMES 0x00000002
#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
+/* See MS-FSCC 2.5.10 */
+typedef struct {
+ __le32 DeviceType;
+ __le32 DeviceCharacteristics;
+} __packed FILE_SYSTEM_DEVICE_INFO; /* device info level 0x104 */
+
+/*
+ * See POSIX Extensions to MS-FSCC 2.3.2.1
+ * Link: https://gitlab.com/samba-team/smb3-posix-spec/-/blob/master/fscc_posix_extensions.md
+ */
+typedef struct {
+ /* For undefined recommended transfer size return -1 in that field */
+ __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
+ __le32 BlockSize;
+ /* The next three fields are in terms of the block size.
+ * (above). If block size is unknown, 4096 would be a
+ * reasonable block size for a server to report.
+ * Note that returning the blocks/blocksavail removes need
+ * to make a second call (to QFSInfo level 0x103 to get this info.
+ * UserBlockAvail is typically less than or equal to BlocksAvail,
+ * if no distinction is made return the same value in each
+ */
+ __le64 TotalBlocks;
+ __le64 BlocksAvail; /* bfree */
+ __le64 UserBlocksAvail; /* bavail */
+ /* For undefined Node fields or FSID return -1 */
+ __le64 TotalFileNodes;
+ __le64 FreeFileNodes;
+ __le64 FileSysIdentifier; /* fsid */
+ /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */
+ /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */
+} __packed FILE_SYSTEM_POSIX_INFO;
+
#endif /* _COMMON_SMB_FSCC_H */
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 33b4708cc214c..c784aa6d9b6ad 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3965,15 +3965,15 @@ static int readdir_info_level_struct_sz(int info_level)
{
switch (info_level) {
case FILE_FULL_DIRECTORY_INFORMATION:
- return sizeof(struct file_full_directory_info);
+ return sizeof(FILE_FULL_DIRECTORY_INFO);
case FILE_BOTH_DIRECTORY_INFORMATION:
- return sizeof(struct file_both_directory_info);
+ return sizeof(FILE_BOTH_DIRECTORY_INFO);
case FILE_DIRECTORY_INFORMATION:
- return sizeof(struct file_directory_info);
+ return sizeof(FILE_DIRECTORY_INFO);
case FILE_NAMES_INFORMATION:
return sizeof(struct file_names_info);
case FILEID_FULL_DIRECTORY_INFORMATION:
- return sizeof(struct file_id_full_dir_info);
+ return sizeof(FILE_ID_FULL_DIR_INFO);
case FILEID_BOTH_DIRECTORY_INFORMATION:
return sizeof(struct file_id_both_directory_info);
case SMB_FIND_FILE_POSIX_INFO:
@@ -3988,9 +3988,9 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
switch (info_level) {
case FILE_FULL_DIRECTORY_INFORMATION:
{
- struct file_full_directory_info *ffdinfo;
+ FILE_FULL_DIRECTORY_INFO *ffdinfo;
- ffdinfo = (struct file_full_directory_info *)d_info->rptr;
+ ffdinfo = (FILE_FULL_DIRECTORY_INFO *)d_info->rptr;
d_info->rptr += le32_to_cpu(ffdinfo->NextEntryOffset);
d_info->name = ffdinfo->FileName;
d_info->name_len = le32_to_cpu(ffdinfo->FileNameLength);
@@ -3998,9 +3998,9 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
}
case FILE_BOTH_DIRECTORY_INFORMATION:
{
- struct file_both_directory_info *fbdinfo;
+ FILE_BOTH_DIRECTORY_INFO *fbdinfo;
- fbdinfo = (struct file_both_directory_info *)d_info->rptr;
+ fbdinfo = (FILE_BOTH_DIRECTORY_INFO *)d_info->rptr;
d_info->rptr += le32_to_cpu(fbdinfo->NextEntryOffset);
d_info->name = fbdinfo->FileName;
d_info->name_len = le32_to_cpu(fbdinfo->FileNameLength);
@@ -4008,9 +4008,9 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
}
case FILE_DIRECTORY_INFORMATION:
{
- struct file_directory_info *fdinfo;
+ FILE_DIRECTORY_INFO *fdinfo;
- fdinfo = (struct file_directory_info *)d_info->rptr;
+ fdinfo = (FILE_DIRECTORY_INFO *)d_info->rptr;
d_info->rptr += le32_to_cpu(fdinfo->NextEntryOffset);
d_info->name = fdinfo->FileName;
d_info->name_len = le32_to_cpu(fdinfo->FileNameLength);
@@ -4028,9 +4028,9 @@ static int dentry_name(struct ksmbd_dir_info *d_info, int info_level)
}
case FILEID_FULL_DIRECTORY_INFORMATION:
{
- struct file_id_full_dir_info *dinfo;
+ FILE_ID_FULL_DIR_INFO *dinfo;
- dinfo = (struct file_id_full_dir_info *)d_info->rptr;
+ dinfo = (FILE_ID_FULL_DIR_INFO *)d_info->rptr;
d_info->rptr += le32_to_cpu(dinfo->NextEntryOffset);
d_info->name = dinfo->FileName;
d_info->name_len = le32_to_cpu(dinfo->FileNameLength);
@@ -4113,9 +4113,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
switch (info_level) {
case FILE_FULL_DIRECTORY_INFORMATION:
{
- struct file_full_directory_info *ffdinfo;
+ FILE_FULL_DIRECTORY_INFO *ffdinfo;
- ffdinfo = (struct file_full_directory_info *)kstat;
+ ffdinfo = (FILE_FULL_DIRECTORY_INFO *)kstat;
ffdinfo->FileNameLength = cpu_to_le32(conv_len);
ffdinfo->EaSize =
smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
@@ -4129,9 +4129,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
}
case FILE_BOTH_DIRECTORY_INFORMATION:
{
- struct file_both_directory_info *fbdinfo;
+ FILE_BOTH_DIRECTORY_INFO *fbdinfo;
- fbdinfo = (struct file_both_directory_info *)kstat;
+ fbdinfo = (FILE_BOTH_DIRECTORY_INFO *)kstat;
fbdinfo->FileNameLength = cpu_to_le32(conv_len);
fbdinfo->EaSize =
smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
@@ -4147,9 +4147,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
}
case FILE_DIRECTORY_INFORMATION:
{
- struct file_directory_info *fdinfo;
+ FILE_DIRECTORY_INFO *fdinfo;
- fdinfo = (struct file_directory_info *)kstat;
+ fdinfo = (FILE_DIRECTORY_INFO *)kstat;
fdinfo->FileNameLength = cpu_to_le32(conv_len);
if (d_info->hide_dot_file && d_info->name[0] == '.')
fdinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE;
@@ -4169,9 +4169,9 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level,
}
case FILEID_FULL_DIRECTORY_INFORMATION:
{
- struct file_id_full_dir_info *dinfo;
+ FILE_ID_FULL_DIR_INFO *dinfo;
- dinfo = (struct file_id_full_dir_info *)kstat;
+ dinfo = (FILE_ID_FULL_DIR_INFO *)kstat;
dinfo->FileNameLength = cpu_to_le32(conv_len);
dinfo->EaSize =
smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode);
@@ -4375,9 +4375,9 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
switch (info_level) {
case FILE_FULL_DIRECTORY_INFORMATION:
{
- struct file_full_directory_info *ffdinfo;
+ FILE_FULL_DIRECTORY_INFO *ffdinfo;
- ffdinfo = (struct file_full_directory_info *)d_info->wptr;
+ ffdinfo = (FILE_FULL_DIRECTORY_INFO *)d_info->wptr;
memcpy(ffdinfo->FileName, d_info->name, d_info->name_len);
ffdinfo->FileName[d_info->name_len] = 0x00;
ffdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
@@ -4386,9 +4386,9 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
}
case FILE_BOTH_DIRECTORY_INFORMATION:
{
- struct file_both_directory_info *fbdinfo;
+ FILE_BOTH_DIRECTORY_INFO *fbdinfo;
- fbdinfo = (struct file_both_directory_info *)d_info->wptr;
+ fbdinfo = (FILE_BOTH_DIRECTORY_INFO *)d_info->wptr;
memcpy(fbdinfo->FileName, d_info->name, d_info->name_len);
fbdinfo->FileName[d_info->name_len] = 0x00;
fbdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
@@ -4397,9 +4397,9 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
}
case FILE_DIRECTORY_INFORMATION:
{
- struct file_directory_info *fdinfo;
+ FILE_DIRECTORY_INFO *fdinfo;
- fdinfo = (struct file_directory_info *)d_info->wptr;
+ fdinfo = (FILE_DIRECTORY_INFO *)d_info->wptr;
memcpy(fdinfo->FileName, d_info->name, d_info->name_len);
fdinfo->FileName[d_info->name_len] = 0x00;
fdinfo->FileNameLength = cpu_to_le32(d_info->name_len);
@@ -4419,9 +4419,9 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info,
}
case FILEID_FULL_DIRECTORY_INFORMATION:
{
- struct file_id_full_dir_info *dinfo;
+ FILE_ID_FULL_DIR_INFO *dinfo;
- dinfo = (struct file_id_full_dir_info *)d_info->wptr;
+ dinfo = (FILE_ID_FULL_DIR_INFO *)d_info->wptr;
memcpy(dinfo->FileName, d_info->name, d_info->name_len);
dinfo->FileName[d_info->name_len] = 0x00;
dinfo->FileNameLength = cpu_to_le32(d_info->name_len);
@@ -4686,7 +4686,7 @@ int smb2_query_dir(struct ksmbd_work *work)
goto err_out;
} else {
no_buf_len:
- ((struct file_directory_info *)
+ ((FILE_DIRECTORY_INFO *)
((char *)rsp->Buffer + d_info.last_entry_offset))
->NextEntryOffset = 0;
if (d_info.data_count >= d_info.last_entry_off_align)
@@ -5341,7 +5341,7 @@ static int get_file_internal_info(struct smb2_query_info_rsp *rsp,
static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
struct ksmbd_file *fp, void *rsp_org)
{
- struct smb2_file_ntwrk_info *file_info;
+ struct smb2_file_network_open_info *file_info;
struct kstat stat;
u64 time;
int ret;
@@ -5357,7 +5357,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
if (ret)
return ret;
- file_info = (struct smb2_file_ntwrk_info *)rsp->Buffer;
+ file_info = (struct smb2_file_network_open_info *)rsp->Buffer;
file_info->CreationTime = cpu_to_le64(fp->create_time);
time = ksmbd_UnixTimeToNT(stat.atime);
@@ -5376,7 +5376,7 @@ static int get_file_network_open_info(struct smb2_query_info_rsp *rsp,
}
file_info->Reserved = cpu_to_le32(0);
rsp->OutputBufferLength =
- cpu_to_le32(sizeof(struct smb2_file_ntwrk_info));
+ cpu_to_le32(sizeof(struct smb2_file_network_open_info));
return 0;
}
@@ -5714,9 +5714,9 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
switch (fsinfoclass) {
case FS_DEVICE_INFORMATION:
{
- struct filesystem_device_info *info;
+ FILE_SYSTEM_DEVICE_INFO *info;
- info = (struct filesystem_device_info *)rsp->Buffer;
+ info = (FILE_SYSTEM_DEVICE_INFO *)rsp->Buffer;
info->DeviceType = cpu_to_le32(FILE_DEVICE_DISK);
info->DeviceCharacteristics =
@@ -5882,14 +5882,14 @@ static int smb2_get_info_filesystem(struct ksmbd_work *work,
}
case FS_POSIX_INFORMATION:
{
- struct filesystem_posix_info *info;
+ FILE_SYSTEM_POSIX_INFO *info;
if (!work->tcon->posix_extensions) {
pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
path_put(&path);
return -EOPNOTSUPP;
} else {
- info = (struct filesystem_posix_info *)(rsp->Buffer);
+ info = (FILE_SYSTEM_POSIX_INFO *)(rsp->Buffer);
info->OptimalTransferSize = cpu_to_le32(stfs.f_bsize);
info->BlockSize = cpu_to_le32(stfs.f_bsize);
info->TotalBlocks = cpu_to_le64(stfs.f_blocks);
diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h
index 0a294378c73d3..ea07c5552f41e 100644
--- a/fs/smb/server/smb2pdu.h
+++ b/fs/smb/server/smb2pdu.h
@@ -224,17 +224,6 @@ struct smb2_file_stream_info {
char StreamName[];
} __packed;
-struct smb2_file_ntwrk_info {
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 AllocationSize;
- __le64 EndOfFile;
- __le32 Attributes;
- __le32 Reserved;
-} __packed;
-
struct smb2_file_standard_info {
__le64 AllocationSize;
__le64 EndOfFile;
diff --git a/fs/smb/server/smb_common.h b/fs/smb/server/smb_common.h
index bea0a250169c3..d6f72195482f9 100644
--- a/fs/smb/server/smb_common.h
+++ b/fs/smb/server/smb_common.h
@@ -112,11 +112,6 @@ struct filesystem_attribute_info {
__le16 FileSystemName[]; /* do not have to save this - get subset? */
} __packed;
-struct filesystem_device_info {
- __le32 DeviceType;
- __le32 DeviceCharacteristics;
-} __packed; /* device info level 0x104 */
-
struct filesystem_vol_info {
__le64 VolumeCreationTime;
__le32 SerialNumber;
@@ -148,20 +143,6 @@ struct object_id_info {
struct fs_extended_info extended_info;
} __packed;
-struct file_directory_info {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- char FileName[];
-} __packed; /* level 0x101 FF resp data */
-
struct file_names_info {
__le32 NextEntryOffset;
__u32 FileIndex;
@@ -169,39 +150,6 @@ struct file_names_info {
char FileName[];
} __packed; /* level 0xc FF resp data */
-struct file_full_directory_info {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize;
- char FileName[];
-} __packed; /* level 0x102 FF resp */
-
-struct file_both_directory_info {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* length of the xattrs */
- __u8 ShortNameLength;
- __u8 Reserved;
- __u8 ShortName[24];
- char FileName[];
-} __packed; /* level 0x104 FFrsp data */
-
struct file_id_both_directory_info {
__le32 NextEntryOffset;
__u32 FileIndex;
@@ -222,46 +170,6 @@ struct file_id_both_directory_info {
char FileName[];
} __packed;
-struct file_id_full_dir_info {
- __le32 NextEntryOffset;
- __u32 FileIndex;
- __le64 CreationTime;
- __le64 LastAccessTime;
- __le64 LastWriteTime;
- __le64 ChangeTime;
- __le64 EndOfFile;
- __le64 AllocationSize;
- __le32 ExtFileAttributes;
- __le32 FileNameLength;
- __le32 EaSize; /* EA size */
- __le32 Reserved;
- __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
- char FileName[];
-} __packed; /* level 0x105 FF rsp data */
-
-struct filesystem_posix_info {
- /* For undefined recommended transfer size return -1 in that field */
- __le32 OptimalTransferSize; /* bsize on some os, iosize on other os */
- __le32 BlockSize;
- /* The next three fields are in terms of the block size.
- * (above). If block size is unknown, 4096 would be a
- * reasonable block size for a server to report.
- * Note that returning the blocks/blocksavail removes need
- * to make a second call (to QFSInfo level 0x103 to get this info.
- * UserBlockAvail is typically less than or equal to BlocksAvail,
- * if no distinction is made return the same value in each
- */
- __le64 TotalBlocks;
- __le64 BlocksAvail; /* bfree */
- __le64 UserBlocksAvail; /* bavail */
- /* For undefined Node fields or FSID return -1 */
- __le64 TotalFileNodes;
- __le64 FreeFileNodes;
- __le64 FileSysIdentifier; /* fsid */
- /* NB Namelen comes from FILE_SYSTEM_ATTRIBUTE_INFO call */
- /* NB flags can come from FILE_SYSTEM_DEVICE_INFO call */
-} __packed;
-
struct smb_version_ops {
u16 (*get_cmd_val)(struct ksmbd_work *swork);
int (*init_rsp_hdr)(struct ksmbd_work *swork);
diff --git a/fs/smb/server/vfs.c b/fs/smb/server/vfs.c
index 130dd0a4001f2..c470d419e7ce8 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -1798,7 +1798,7 @@ int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
*/
void *ksmbd_vfs_init_kstat(char **p, struct ksmbd_kstat *ksmbd_kstat)
{
- struct file_directory_info *info = (struct file_directory_info *)(*p);
+ FILE_DIRECTORY_INFO *info = (FILE_DIRECTORY_INFO *)(*p);
struct kstat *kstat = ksmbd_kstat->kstat;
u64 time;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 020/686] smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (18 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 019/686] smb: move some duplicate struct definitions " Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 021/686] smb: client: fix OOB read in the SMB_FIND_FILE_UNIX name scan Greg Kroah-Hartman
` (665 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diego Oliva, David Howells,
Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diego Oliva <diego@bynar.io>
[ Upstream commit f8171804a39ee89a11cd462f67862899de9c6b10 ]
cifs_fill_dirent() reads the fixed part of a directory entry and the
name length it holds, or for SMB_FIND_FILE_UNIX scans the name for its
terminating NUL, without knowing where the response ends.
cifs_save_resume_key() calls it for the entry at the LastNameOffset the
server chose, after every FindNext and after the FindFirst of a search
rewind, and records the name it returns as the resume name of the
search without bounding it; the next CIFSFindNext() copies up to
PATH_MAX - 1 bytes from that name into its request and sends them to
the server. cifs_filldir() bounds
the name against the end of the response since
commit f8cf09a53a0d ("smb: client: bound dirent name against end of
SMB response in cifs_filldir"), but only after cifs_fill_dirent() has
read the entry, and nxt_dir_entry() checks the entries it walks only
against sizeof(FILE_DIRECTORY_INFO), for every level but
SMB_FIND_FILE_INFO_STANDARD, and never sees the first entry of a
response.
Bounding where last_entry starts, as the preceding patch does, does
not bound the read. A last entry that starts within the final bytes of
the response still has its fixed part read past the end of the
received data, and the name length it declares, a __le32 for every
level but SMB_FIND_FILE_INFO_STANDARD and SMB_FIND_FILE_UNIX, is
recorded without being checked against anything. CIFSFindNext()
rejects only a length of PATH_MAX or more, then copies the name, up to
4095 bytes, into its request and sends it, and as the report below
shows that copy can run past the end of the cifs_request allocation
that holds the response. For SMB_FIND_FILE_UNIX the name is in
addition scanned for its terminating NUL over up to PATH_MAX + 1
UTF-16 units, or PATH_MAX bytes, before any check. The FindNext that
carries the name is only sent by the SMB1 dialect, which is not
negotiated by default; reaching it requires an explicit vers=1.0
mount.
With KASAN enabled, a response whose last entry declares a name
longer than the bytes that follow it gives:
==================================================================
BUG: KASAN: slab-out-of-bounds in CIFSFindNext+0x8ca/0x14c0
Read of size 4080 at addr ffff88807c823f98 by task ls/83
CPU: 0 UID: 0 PID: 83 Comm: ls Not tainted 7.3.0-rc4-00457-gf14572c203d5 #69 PREEMPT(lazy)
Call Trace:
<TASK>
kasan_report+0xdf/0x1a0
kasan_check_range+0x10f/0x1e0
__asan_memcpy+0x23/0x60
CIFSFindNext+0x8ca/0x14c0
cifs_readdir+0xf51/0x29c0
iterate_dir+0x1c0/0x570
__x64_sys_getdents64+0x133/0x270
do_syscall_64+0x109/0x5d0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
Allocated by task 83 on cpu 1 at 13.497119s:
cifs_buf_get+0x36/0x90
smb_init+0x4f/0x110
CIFSFindNext+0xf7/0x14c0
cifs_readdir+0xf51/0x29c0
The buggy address belongs to the object at ffff88807c820000
which belongs to the cache cifs_request of size 16588
The buggy address is located 16280 bytes inside of
allocated 16588-byte region [ffff88807c820000, ffff88807c8240cc)
==================================================================
The read is the memcpy() that copies the recorded name into the next
request, so those bytes go to the server.
Pass the end of the response to cifs_fill_dirent() and have it reject
an entry whose fixed part does not fit or whose name extends past the
end, before either is used, so that both callers are covered;
cifs_save_resume_key() computes the end the same way cifs_readdir()
does. The name bound compares the bytes left between the name and the
end with the name length rather than adding the length to the name
pointer, since the length is a 32-bit value taken from the entry and
the sum could wrap on 32-bit systems. cifs_fill_dirent() is also used
on the SMB2 readdir path; there smb2_parse_query_directory() has
already checked every entry against the end of the response, so a
valid SMB2 response is not rejected by the new checks. The check
cifs_filldir() applies after the parse is left in place. The NUL scan
for SMB_FIND_FILE_UNIX names is capped by a separate patch.
An entry and its name lie inside the data area of the response, so a
server that points LastNameOffset at the entry is not affected. One
that points it at the file name, as MS-CIFS 2.2.6.2.2 describes, has
its last entry rejected here; the listing is unaffected, because
cifs_readdir() records the resume name from an entry it emitted, and
before this series such a response could instead end the listing early,
since a name length read from the wrong place is usually PATH_MAX or
more, which CIFSFindNext() rejects with -EINVAL.
On trees before v6.19 the type for the level 0x105 fixed part is
spelled SEARCH_ID_FULL_DIR_INFO; adjust when backporting.
Fixes: 0752f1522a91 ("[CIFS] make sure we have the right resume info before calling CIFSFindNext")
Cc: stable@vger.kernel.org # 6.1.x: f8cf09a53a0d: smb: client: bound dirent name against end of SMB response in cifs_filldir
Assisted-by: Bynario AI
Signed-off-by: Diego Oliva <diego@bynar.io>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/readdir.c | 39 ++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
index cf6b440f757b6..69eb0feb7bed1 100644
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -585,30 +585,46 @@ static void cifs_fill_dirent_std(struct cifs_dirent *de,
}
static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
- u16 level, bool is_unicode)
+ const char *end, u16 level, bool is_unicode)
{
+ size_t len = end > (const char *)info ? end - (const char *)info : 0;
+
memset(de, 0, sizeof(*de));
switch (level) {
case SMB_FIND_FILE_POSIX_INFO:
+ if (len < sizeof(struct smb2_posix_info))
+ goto too_short;
cifs_fill_dirent_posix(de, info);
break;
case SMB_FIND_FILE_UNIX:
+ if (len < offsetof(FILE_UNIX_INFO, FileName))
+ goto too_short;
cifs_fill_dirent_unix(de, info, is_unicode);
break;
case SMB_FIND_FILE_DIRECTORY_INFO:
+ if (len < offsetof(FILE_DIRECTORY_INFO, FileName))
+ goto too_short;
cifs_fill_dirent_dir(de, info);
break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
+ if (len < offsetof(FILE_FULL_DIRECTORY_INFO, FileName))
+ goto too_short;
cifs_fill_dirent_full(de, info);
break;
case SMB_FIND_FILE_ID_FULL_DIR_INFO:
+ if (len < offsetof(FILE_ID_FULL_DIR_INFO, FileName))
+ goto too_short;
cifs_fill_dirent_search(de, info);
break;
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
+ if (len < offsetof(FILE_BOTH_DIRECTORY_INFO, FileName))
+ goto too_short;
cifs_fill_dirent_both(de, info);
break;
case SMB_FIND_FILE_INFO_STANDARD:
+ if (len < offsetof(FIND_FILE_STANDARD_INFO, FileName))
+ goto too_short;
cifs_fill_dirent_std(de, info);
break;
default:
@@ -616,7 +632,19 @@ static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
return -EINVAL;
}
+ if (de->name &&
+ (end < de->name || (size_t)(end - de->name) < de->namelen)) {
+ cifs_dbg(VFS, "%s: search entry name extends past end of SMB\n",
+ __func__);
+ return -EINVAL;
+ }
+
return 0;
+
+too_short:
+ cifs_dbg(VFS, "%s: search entry extends past end of SMB\n",
+ __func__);
+ return -EINVAL;
}
#define UNICODE_DOT cpu_to_le16(0x2e)
@@ -671,10 +699,14 @@ static int is_dir_changed(struct file *file)
static int cifs_save_resume_key(const char *current_entry,
struct cifsFileInfo *file_info)
{
+ struct TCP_Server_Info *server = tlink_tcon(file_info->tlink)->ses->server;
+ char *buf = file_info->srch_inf.ntwrk_buf_start;
+ const char *end = buf + server->ops->calc_smb_size(buf);
struct cifs_dirent de;
int rc;
- rc = cifs_fill_dirent(&de, current_entry, file_info->srch_inf.info_level,
+ rc = cifs_fill_dirent(&de, current_entry, end,
+ file_info->srch_inf.info_level,
file_info->srch_inf.unicode);
if (!rc) {
file_info->srch_inf.presume_name = de.name;
@@ -973,7 +1005,8 @@ static int cifs_filldir(char *find_entry, struct file *file,
struct qstr name;
int rc = 0;
- rc = cifs_fill_dirent(&de, find_entry, file_info->srch_inf.info_level,
+ rc = cifs_fill_dirent(&de, find_entry, end_of_smb,
+ file_info->srch_inf.info_level,
file_info->srch_inf.unicode);
if (rc)
return rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 021/686] smb: client: fix OOB read in the SMB_FIND_FILE_UNIX name scan
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (19 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 020/686] smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2 Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 022/686] smb: client: reject short SESSION_SETUP responses Greg Kroah-Hartman
` (664 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diego Oliva, David Howells,
Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diego Oliva <diego@bynar.io>
[ Upstream commit fa0c2f082946917c3f07d2475c8ce73a8c96d0e2 ]
cifs_fill_dirent_unix() finds the length of an SMB_FIND_FILE_UNIX
entry name by scanning for its terminating NUL, over up to PATH_MAX + 1
UTF-16 units in cifs_unicode_bytelen() or PATH_MAX bytes in strnlen().
Neither scan knows where the response ends. cifs_fill_dirent() only
requires the fixed part of the entry to fit, so the name can start
exactly at the end of the received data, and a name that holds no
terminator is then scanned for 8194 bytes, or 4096 bytes without
unicode, past the end of the received data. SendReceive() copies at
most 16468 bytes into the 16588-byte cifs_request allocation, so for a
response of that length up to 8074 of the bytes scanned lie past the
end of the allocation. Before the preceding patches bounded where the
entry starts, the entry itself could start up to 820 bytes past the
end of the allocation at the default CIFSMaxBufSize, and its name 928
bytes past it, so all 8194 scanned bytes would lie outside.
cifs_fill_dirent() rejects the name afterwards because it extends past
the end of the response, so nothing of what was read is used, but the
out-of-bounds read itself remains.
SMB_FIND_FILE_UNIX is only used with SMB1 servers that offer the Unix
extensions; SMB1 is not negotiated by default and requires an explicit
vers=1.0 mount.
Before the preceding patches, an entry placed past the buffer left the
scan out of bounds from its first read. They bound where the entry
starts, but nothing bounds the scan, so a name that holds no
terminator still runs off the end of the allocation. Reproduced on
the unpatched tree with KASAN enabled, for an entry that starts
inside the response, which is the case the preceding patches leave
open:
==================================================================
BUG: KASAN: slab-out-of-bounds in cifs_save_resume_key.isra.0+0x75c/0x7f0
Read of size 2 at addr ffff88807ee640cc by task ls/84
CPU: 0 UID: 0 PID: 84 Comm: ls Not tainted 7.3.0-rc4-00457-gf14572c203d5 #69 PREEMPT(lazy)
Call Trace:
<TASK>
kasan_report+0xdf/0x1a0
cifs_save_resume_key.isra.0+0x75c/0x7f0
cifs_readdir+0x1ed6/0x29c0
iterate_dir+0x1c0/0x570
__x64_sys_getdents64+0x133/0x270
do_syscall_64+0x109/0x5d0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
Allocated by task 84 on cpu 1 at 15.751078s:
cifs_buf_get+0x36/0x90
smb_init+0x4f/0x110
CIFSFindNext+0xf7/0x14c0
cifs_readdir+0xf51/0x29c0
The buggy address belongs to the object at ffff88807ee60000
which belongs to the cache cifs_request of size 16588
The buggy address is located 0 bytes to the right of
allocated 16588-byte region [ffff88807ee60000, ffff88807ee640cc)
==================================================================
The two bytes read there are one UTF-16 unit of the scan, at the first
byte past the end of the object. The scan carries on from there,
reported again 2, 4 and 6 bytes to the right.
Pass the number of bytes that follow the fixed part of the entry to
cifs_fill_dirent_unix() and stop both scans there. A scan that reaches
the end of the response without finding a terminator now fails: it
returns a name that ends exactly at the end of the response and would
otherwise pass the bound, so cifs_fill_dirent() requires the position
of the terminator of an SMB_FIND_FILE_UNIX name to lie inside the
response as well. Accepting such a name truncated at the end of the
response would turn a malformed entry into a directory entry, or a
resume name, that no server sent. A name longer than the PATH_MAX cap
of the scans is still truncated there, as before, when the response
extends past the cap. The message cifs_unicode_bytelen() logs when it
finds no terminator now covers both limits.
This patch depends on "smb: client: fix OOB read of the resume name
sent in TRANS2_FIND_NEXT2", which adds the end argument of
cifs_fill_dirent() and the length it derives from it; the backport
note in that patch applies to this one as well.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Bynario AI
Signed-off-by: Diego Oliva <diego@bynar.io>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/readdir.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/fs/smb/client/readdir.c b/fs/smb/client/readdir.c
index 69eb0feb7bed1..00c3b7a82f4c1 100644
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -455,17 +455,20 @@ initiate_cifs_search(const unsigned int xid, struct file *file,
}
/* return length of unicode string in bytes */
-static int cifs_unicode_bytelen(const char *str)
+static size_t cifs_unicode_bytelen(const char *str, size_t maxlen)
{
- int len;
const __le16 *ustr = (const __le16 *)str;
+ size_t len;
- for (len = 0; len <= PATH_MAX; len++) {
+ maxlen = umin(PATH_MAX + 1, maxlen / sizeof(__le16));
+ for (len = 0; len < maxlen; len++) {
if (ustr[len] == 0)
- return len << 1;
+ return len * sizeof(__le16);
}
- cifs_dbg(FYI, "Unicode string longer than PATH_MAX found\n");
- return len << 1;
+ len *= sizeof(__le16);
+ cifs_dbg(FYI, "%s: Unicode string not terminated within %zu bytes\n",
+ __func__, len);
+ return len;
}
static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)
@@ -531,13 +534,13 @@ static void cifs_fill_dirent_posix(struct cifs_dirent *de,
}
static void cifs_fill_dirent_unix(struct cifs_dirent *de,
- const FILE_UNIX_INFO *info, bool is_unicode)
+ const FILE_UNIX_INFO *info, bool is_unicode, size_t maxlen)
{
de->name = &info->FileName[0];
if (is_unicode)
- de->namelen = cifs_unicode_bytelen(de->name);
+ de->namelen = cifs_unicode_bytelen(de->name, maxlen);
else
- de->namelen = strnlen(de->name, PATH_MAX);
+ de->namelen = strnlen(de->name, min_t(size_t, maxlen, PATH_MAX));
de->resume_key = info->ResumeKey;
de->ino = le64_to_cpu(info->basic.UniqueId);
}
@@ -588,6 +591,7 @@ static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
const char *end, u16 level, bool is_unicode)
{
size_t len = end > (const char *)info ? end - (const char *)info : 0;
+ size_t nul_len = 0;
memset(de, 0, sizeof(*de));
@@ -600,7 +604,9 @@ static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
case SMB_FIND_FILE_UNIX:
if (len < offsetof(FILE_UNIX_INFO, FileName))
goto too_short;
- cifs_fill_dirent_unix(de, info, is_unicode);
+ cifs_fill_dirent_unix(de, info, is_unicode,
+ len - offsetof(FILE_UNIX_INFO, FileName));
+ nul_len = is_unicode ? sizeof(__le16) : sizeof(__u8);
break;
case SMB_FIND_FILE_DIRECTORY_INFO:
if (len < offsetof(FILE_DIRECTORY_INFO, FileName))
@@ -633,7 +639,8 @@ static int cifs_fill_dirent(struct cifs_dirent *de, const void *info,
}
if (de->name &&
- (end < de->name || (size_t)(end - de->name) < de->namelen)) {
+ (end < de->name ||
+ (size_t)(end - de->name) < de->namelen + nul_len)) {
cifs_dbg(VFS, "%s: search entry name extends past end of SMB\n",
__func__);
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 022/686] smb: client: reject short SESSION_SETUP responses
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (20 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 021/686] smb: client: fix OOB read in the SMB_FIND_FILE_UNIX name scan Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 023/686] smb: client: require stable pages for SMB compression Greg Kroah-Hartman
` (663 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Abdifatah Suruur, Namjae Jeon,
Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdifatah Suruur <suruurism@gmail.com>
[ Upstream commit 4d8930afa3446041358a7db33e7b23a0bb9459b5 ]
smb2_check_message() accepts frames shorter than struct smb2_pdu when
the SMB2 status is non-zero, before the minimum-PDU check added by
b4694f269e66d. A 64-byte STATUS_MORE_PROCESSING_REQUIRED SESSION_SETUP
response is therefore accepted even though it cannot contain the
SecurityBufferOffset and SecurityBufferLength fields.
The parser then reads those fields from stale bytes left in the reused
receive buffer by an earlier frame. With a long stale
SecurityBufferLength, decode_ntlmssp_challenge() copies up to about
64 KB from beyond the receive object and sends the data back to the
server in the NTLMv2 AUTHENTICATE target info.
Reject short MPR SESSION_SETUP responses before the short-error path,
and validate SecurityBufferOffset + SecurityBufferLength against the
received response length before decoding the challenge.
The ordering bypass is not new: the short-error early return predates
b4694f269e66d, and the unvalidated SecurityBufferLength read predates
the 2016 raw NTLMSSP split in 166cea4dc3a4, so all supported stable
trees are affected. Reproduced on 6.6.87.2; the path is unchanged on
mainline.
Fixes: 5478f9ba9a34 ("CIFS: Add session setup/logoff capability for SMB2")
Cc: stable@vger.kernel.org
Signed-off-by: Abdifatah Suruur <suruurism@gmail.com>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ sashal: Replaced the unavailable smb2_min_pdu_len lookup with sizeof(struct smb2_sess_setup_rsp). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2misc.c | 15 +++++++++++++++
fs/smb/client/smb2pdu.c | 18 ++++++++++++------
2 files changed, 27 insertions(+), 6 deletions(-)
diff --git a/fs/smb/client/smb2misc.c b/fs/smb/client/smb2misc.c
index 34d2401c6c665..46c98d024f068 100644
--- a/fs/smb/client/smb2misc.c
+++ b/fs/smb/client/smb2misc.c
@@ -194,6 +194,21 @@ smb2_check_message(char *buf, unsigned int len, struct TCP_Server_Info *server)
return 1;
}
+ /*
+ * A SESSION_SETUP response that asks for more processing carries a
+ * security blob and is parsed as a normal reply. Do not let the
+ * short-error path below accept a frame that cannot hold the fixed
+ * response fields.
+ */
+ if (command == SMB2_SESSION_SETUP_HE &&
+ shdr->Status == STATUS_MORE_PROCESSING_REQUIRED &&
+ len < sizeof(struct smb2_sess_setup_rsp)) {
+ cifs_server_dbg(VFS,
+ "%s: session setup response too short: %u < %zu\n",
+ __func__, len, sizeof(struct smb2_sess_setup_rsp));
+ return 1;
+ }
+
if (len < pdu_size) {
if ((len >= hdr_size)
&& (shdr->Status != 0)) {
diff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c
index d0c56caed1626..3302923f98893 100644
--- a/fs/smb/client/smb2pdu.c
+++ b/fs/smb/client/smb2pdu.c
@@ -1757,15 +1757,21 @@ SMB2_sess_auth_rawntlmssp_negotiate(struct SMB2_sess_data *sess_data)
if (rc)
goto out;
- if (offsetof(struct smb2_sess_setup_rsp, Buffer) !=
- le16_to_cpu(rsp->SecurityBufferOffset)) {
- cifs_dbg(VFS, "Invalid security buffer offset %d\n",
- le16_to_cpu(rsp->SecurityBufferOffset));
+ u16 boff = le16_to_cpu(rsp->SecurityBufferOffset);
+ u16 blen = le16_to_cpu(rsp->SecurityBufferLength);
+
+ if (offsetof(struct smb2_sess_setup_rsp, Buffer) != boff) {
+ cifs_dbg(VFS, "Invalid security buffer offset %d\n", boff);
rc = -EIO;
goto out;
}
- rc = decode_ntlmssp_challenge(rsp->Buffer,
- le16_to_cpu(rsp->SecurityBufferLength), ses);
+ if ((u32)boff + blen > sess_data->iov[0].iov_len) {
+ cifs_dbg(VFS, "%s: invalid security buffer length: %u\n",
+ __func__, blen);
+ rc = -EINVAL;
+ goto out;
+ }
+ rc = decode_ntlmssp_challenge(rsp->Buffer, blen, ses);
if (rc)
goto out;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 023/686] smb: client: require stable pages for SMB compression
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (21 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 022/686] smb: client: reject short SESSION_SETUP responses Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 024/686] mm: remove !root_reclaim checking in should_abort_scan() Greg Kroah-Hartman
` (662 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
Namjae Jeon, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
Bharath SM, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
[ Upstream commit 8667061cf99394526dd9c0ea2662e6bbc7ae7848 ]
Like signing, SMB compression builds the write payload from the pagecache
folios: should_compress() lets a write request through and smb_compress()
compresses those folios on the way to the socket. If a buffered write
mutates a folio while a write subrequest is still in flight, the compressed
bytes no longer correspond to a consistent view of the data, and the server
silently stores corrupted contents - worse than the signed case, which at
least fails loudly with STATUS_ACCESS_DENIED.
Mark the mapping for stable writes when a write may be compressed, i.e. the
same condition should_compress() tests (compression negotiated and the share
allows compressed data), so netfs_perform_write() waits for writeback to
complete before modifying an in-flight folio.
Fixes: f046d71e84e1 ("smb: client: insert compression check/call on write requests")
Suggested-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Reviewed-by: David Howells <dhowells@redhat.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
[ sashal: Replaced tcon references with direct cifs_sb_master_tcon(cifs_sb) lookups because the local variable is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/inode.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index d9c502efe84bc..b8f9dd47a56e7 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -87,7 +87,9 @@ static void cifs_set_ops(struct inode *inode)
else
inode->i_data.a_ops = &cifs_addr_ops;
mapping_set_large_folios(inode->i_mapping);
- if (cifs_sb_master_tcon(cifs_sb)->ses->server->sign)
+ if (cifs_sb_master_tcon(cifs_sb)->ses->server->sign ||
+ (cifs_sb_master_tcon(cifs_sb)->ses->server->compression.enabled &&
+ (cifs_sb_master_tcon(cifs_sb)->share_flags & SMB2_SHAREFLAG_COMPRESS_DATA)))
mapping_set_stable_writes(inode->i_mapping);
break;
case S_IFDIR:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 024/686] mm: remove !root_reclaim checking in should_abort_scan()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (22 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 023/686] smb: client: require stable pages for SMB compression Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 025/686] smb: client: validate SMB1 EA list bounds before parsing Greg Kroah-Hartman
` (661 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhaoyang Huang, T.J.Mercier,
Shakeel Butt, Qi Zheng, Barry Song, Kairui Song, Johannes Weiner,
Michal Hocko, Rik van Riel, Roman Gushchin, Yu Zhao,
Axel Rasmussen, Yuanchu Xie, Wei Xu, Andrew Morton, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
[ Upstream commit 19999e479c2a38672789e66b4830f43c645ca1f2 ]
Android systems usually use memory.reclaim interface to implement user
space memory management which expects that the requested reclaim target
and actually reclaimed amount memory are not diverging by too much. With
the current MGRLU implementation there is, however, no bail out when the
reclaim target is reached and this could lead to an excessive reclaim
that scales with the reclaim hierarchy size.For example, we can get a
nr_reclaimed=394/nr_to_reclaim=32 proactive reclaim under a common 1-N
cgroup hierarchy.
This defect arose from the goal of keeping fairness among memcgs that is,
for try_to_free_mem_cgroup_pages -> shrink_node_memcgs -> shrink_lruvec ->
lru_gen_shrink_lruvec -> try_to_shrink_lruvec, the !root_reclaim(sc) check
was there for reclaim fairness, which was necessary before commit
b82b530740b9 ("mm: vmscan: restore incremental cgroup iteration") because
the fairness depended on attempted proportional reclaim from every memcg
under the target memcg. However after commit b82b530740b9 there is no
longer a need to visit every memcg to ensure fairness. Let's have
try_to_shrink_lruvec bail out when the nr_reclaimed achieved.
Link: https://lore.kernel.org/20260318011558.1696310-1-zhaoyang.huang@unisoc.com
Link: https://lore.kernel.org/20260212032111.408865-1-zhaoyang.huang@unisoc.com
Signed-off-by: Zhaoyang Huang <zhaoyang.huang@unisoc.com>
Suggested-by: T.J.Mercier <tjmercier@google.com>
Reviewed-by: T.J. Mercier <tjmercier@google.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Acked-by: Qi Zheng <qi.zheng@linux.dev>
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Kairui Song <kasong@tencent.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Yu Zhao <yuzhao@google.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Wei Xu <weixugc@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: T.J. Mercier <tjmercier@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vmscan.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/mm/vmscan.c b/mm/vmscan.c
index e72d50bab730a..e640d1ec59749 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4844,10 +4844,6 @@ static bool should_abort_scan(struct lruvec *lruvec, struct scan_control *sc)
int i;
enum zone_watermarks mark;
- /* don't abort memcg reclaim to ensure fairness */
- if (!root_reclaim(sc))
- return false;
-
if (sc->nr_reclaimed >= max(sc->nr_to_reclaim, compact_gap(sc->order)))
return true;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 025/686] smb: client: validate SMB1 EA list bounds before parsing
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (23 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 024/686] mm: remove !root_reclaim checking in should_abort_scan() Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 026/686] xfs: break out xattr entry checks into separate functions Greg Kroah-Hartman
` (660 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ratnaker Gautam, Paulo Alcantara,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
[ Upstream commit ddc7a7e1eeb116ccaf010a6f1fb6ab927f3f888d ]
CIFSSMBQAllEAs() checks the server-provided EA list length by adding it
to the response pointer. On 32-bit systems, a positive length can wrap
the pointer and pass the comparison. The parser then walks outside the
received response while reading the next FEA header.
A response with a list length of 0x40000000 reproduces this as a native
i386 page fault and kernel panic from listxattr() against an SMB1
server.
Check that the EA list starts within the SMB byte area before reading
its header. Keep its length unsigned and compare it with the bytes left
in the response without pointer addition.
SMB1 is not negotiated by default and requires an explicit vers=1.0
mount.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ sashal: adjusted the CIFSSMBQAllEAs() hunk for plain -EIO where upstream already used smb_EIO2() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifssmb.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 6e4b845a4078c..14d5c1924ae2b 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -6082,9 +6082,11 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
int rc = 0;
int bytes_returned;
int list_len;
+ u32 ea_list_len;
struct fealist *ea_response_data;
struct fea *temp_fea;
char *temp_ptr;
+ char *byte_area;
char *end_of_smb;
__u16 params, byte_count, data_offset;
unsigned int ea_name_len = ea_name ? strlen(ea_name) : 0;
@@ -6161,9 +6163,19 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
ea_response_data = (struct fealist *)
(((char *) &pSMBr->hdr.Protocol) + data_offset);
- list_len = le32_to_cpu(ea_response_data->list_len);
- cifs_dbg(FYI, "ea length %d\n", list_len);
- if (list_len <= 8) {
+ byte_area = pByteArea(&pSMBr->hdr);
+ end_of_smb = byte_area + get_bcc(&pSMBr->hdr);
+ if ((char *)ea_response_data < byte_area ||
+ (char *)ea_response_data >
+ end_of_smb - sizeof(ea_response_data->list_len)) {
+ rc = smb_EIO2(smb_eio_trace_qalleas_overlong,
+ data_offset, get_bcc(&pSMBr->hdr));
+ goto QAllEAsOut;
+ }
+
+ ea_list_len = le32_to_cpu(ea_response_data->list_len);
+ cifs_dbg(FYI, "%s: ea length: %u\n", __func__, ea_list_len);
+ if (ea_list_len <= 8) {
cifs_dbg(FYI, "empty EA list returned from server\n");
/* didn't find the named attribute */
if (ea_name)
@@ -6172,12 +6184,14 @@ CIFSSMBQAllEAs(const unsigned int xid, struct cifs_tcon *tcon,
}
/* make sure list_len doesn't go past end of SMB */
- end_of_smb = (char *)pByteArea(&pSMBr->hdr) + get_bcc(&pSMBr->hdr);
- if ((char *)ea_response_data + list_len > end_of_smb) {
+ if (ea_list_len > end_of_smb - (char *)ea_response_data) {
cifs_dbg(FYI, "EA list appears to go beyond SMB\n");
- rc = -EIO;
+ rc = smb_EIO2(smb_eio_trace_qalleas_overlong,
+ ea_list_len,
+ end_of_smb - (char *)ea_response_data);
goto QAllEAsOut;
}
+ list_len = ea_list_len;
/* account for ea list len */
list_len -= 4;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 026/686] xfs: break out xattr entry checks into separate functions
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (24 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 025/686] smb: client: validate SMB1 EA list bounds before parsing Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 027/686] xfs: check for buffer overruns when examining local/remote xattr entries Greg Kroah-Hartman
` (659 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-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 7315d0cb1e2e7..84507c80cf945 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] 687+ messages in thread
* [PATCH 6.18 027/686] xfs: check for buffer overruns when examining local/remote xattr entries
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (25 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 026/686] xfs: break out xattr entry checks into separate functions Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 028/686] xfs: refactor directory data block walking loops in scrub Greg Kroah-Hartman
` (658 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-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 84507c80cf945..68d9666ab201a 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 ab5bd7a4d4abb..2c573897c0c6a 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] 687+ messages in thread
* [PATCH 6.18 028/686] xfs: refactor directory data block walking loops in scrub
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (26 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 027/686] xfs: check for buffer overruns when examining local/remote xattr entries Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 029/686] xfs: improve dirent bounds checking in scrub and repair Greg Kroah-Hartman
` (657 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-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 7b0a9d2aea3ec..2f73baee0f0b4 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 9aafe5c31cbe3..f8e88b638c43d 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] 687+ messages in thread
* [PATCH 6.18 029/686] xfs: improve dirent bounds checking in scrub and repair
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (27 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 028/686] xfs: refactor directory data block walking loops in scrub Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 030/686] NFSv4/pnfs: bound the CB_NOTIFY_DEVICEID array count before allocating Greg Kroah-Hartman
` (656 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-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 2f73baee0f0b4..495fdf3b519ae 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 f8e88b638c43d..c7fd39fd83a48 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] 687+ messages in thread
* [PATCH 6.18 030/686] NFSv4/pnfs: bound the CB_NOTIFY_DEVICEID array count before allocating
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (28 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 029/686] xfs: improve dirent bounds checking in scrub and repair Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 031/686] smb: client: bound POSIX lock data area by response length Greg Kroah-Hartman
` (655 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benjamin Coddington, Anna Schumaker,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Coddington <ben.coddington@hammerspace.com>
[ Upstream commit 32f0967ea296d447925465c98e7eec71d4e2f755 ]
decode_devicenotify_args() hands the server's notification count
straight to kmalloc_objs() as the array length, without checking it
against the message that carried it. Bound it the way nfs4xdr.c bounds
an attribute length, against xdr_stream_remaining().
Fixes: 1be5683b03a7 ("pnfs: CB_NOTIFY_DEVICEID")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5
Signed-off-by: Benjamin Coddington <bcodding@hammerspace.com>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
[ sashal: Adjusted context to retain the existing kmalloc_array() allocation instead of kmalloc_objs(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/callback_xdr.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index 1aa6a6e14b057..34fa00f1a1c20 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -275,6 +275,13 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp,
if (n == 0)
goto out;
+ /* sanity check the count against the remaining stream */
+ if (n > xdr_stream_remaining(xdr) /
+ ((4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE)) {
+ status = htonl(NFS4ERR_BADXDR);
+ goto out;
+ }
+
args->devs = kmalloc_array(n, sizeof(*args->devs), GFP_KERNEL);
if (!args->devs) {
status = htonl(NFS4ERR_DELAY);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 031/686] smb: client: bound POSIX lock data area by response length
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (29 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 030/686] NFSv4/pnfs: bound the CB_NOTIFY_DEVICEID array count before allocating Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 032/686] smb: align durable reconnect v2 context to 8 byte boundary Greg Kroah-Hartman
` (654 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ratnaker Gautam, Namjae Jeon,
Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
[ Upstream commit 8fc9af68c57156ff64769f30e831553cd03b3000 ]
CIFSSMBPosixLock() receives a TRANS2 response whose server-provided
DataOffset and DataCount are not required by validate_t2() to describe an
interval inside the response. A server can therefore make the client read a
cifs_posix_lock beyond the response buffer and return those kernel bytes
through F_GETLK.
Use smbCalcSize() to obtain the full response length after any multipart
TRANS2 reassembly, then reject data areas that extend past it before
dereferencing them.
Fixes: fc94cdb94462 ("[CIFS] Fix new POSIX Locking for setting lock_type correctly on unlock")
Reported-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Cc: stable@vger.kernel.org
Signed-off-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifssmb.c | 8 ++++++++
fs/smb/client/trace.h | 1 +
2 files changed, 9 insertions(+)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 14d5c1924ae2b..1049a64241bc0 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -2338,6 +2338,7 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
cifs_dbg(FYI, "Send error in Posix Lock = %d\n", rc);
} else if (pLockData) {
/* lock structure can be returned on get */
+ unsigned int rsp_len;
__u16 data_offset;
__u16 data_count;
rc = validate_t2((struct smb_t2_rsp *)pSMBr);
@@ -2348,10 +2349,17 @@ CIFSSMBPosixLock(const unsigned int xid, struct cifs_tcon *tcon,
}
data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
data_count = le16_to_cpu(pSMBr->t2.DataCount);
+ rsp_len = smbCalcSize(&pSMBr->hdr);
if (data_count < sizeof(struct cifs_posix_lock)) {
rc = -EIO;
goto plk_err_exit;
}
+ if (data_offset > rsp_len ||
+ data_count > rsp_len - data_offset) {
+ rc = smb_EIO2(smb_eio_trace_lock_data_area,
+ data_offset, data_count);
+ goto plk_err_exit;
+ }
parm_data = (struct cifs_posix_lock *)
((char *)&pSMBr->hdr.Protocol + data_offset);
if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK))
diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
index a56fbacf28d14..670612d1a4497 100644
--- a/fs/smb/client/trace.h
+++ b/fs/smb/client/trace.h
@@ -42,6 +42,7 @@
EM(smb_eio_trace_ioctl_no_rsp, "ioctl_no_rsp") \
EM(smb_eio_trace_ioctl_out_off, "ioctl_out_off") \
EM(smb_eio_trace_lock_bcc_too_small, "lock_bcc_too_small") \
+ EM(smb_eio_trace_lock_data_area, "lock_data_area") \
EM(smb_eio_trace_lock_data_too_small, "lock_data_too_small") \
EM(smb_eio_trace_malformed_ksid_key, "malformed_ksid_key") \
EM(smb_eio_trace_malformed_sid_key, "malformed_sid_key") \
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 032/686] smb: align durable reconnect v2 context to 8 byte boundary
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (30 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 031/686] smb: client: bound POSIX lock data area by response length Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 033/686] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags" Greg Kroah-Hartman
` (653 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bharath SM,
Paulo Alcantara (Red Hat), Steve French, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bharath SM <bharathsm@microsoft.com>
[ Upstream commit 05f5e355cf783b30bd6eb3dec17ed1a8b3cfa95c ]
Add a 4-byte Pad to create_durable_handle_reconnect_v2 so the DH2C
create context is 8 byte aligned.
This avoids malformed CREATE contexts on reconnect.
Recent change removed this Padding, adding it back.
Fixes: 81a45de432c6 ("smb: move create_durable_handle_reconnect_v2 to common/smb2pdu.h")
Signed-off-by: Bharath SM <bharathsm@microsoft.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/common/smb2pdu.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/smb/common/smb2pdu.h b/fs/smb/common/smb2pdu.h
index 7377b5a9f8a55..4b8ed28a72c61 100644
--- a/fs/smb/common/smb2pdu.h
+++ b/fs/smb/common/smb2pdu.h
@@ -1320,6 +1320,7 @@ struct create_durable_handle_reconnect_v2 {
struct create_context_hdr ccontext;
__u8 Name[8];
struct durable_reconnect_context_v2 dcontext;
+ __u8 Pad[4];
} __packed;
/* See MS-SMB2 2.2.14.2.12 */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 033/686] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags"
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (31 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 032/686] smb: align durable reconnect v2 context to 8 byte boundary Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 034/686] NFSD: Move version-specific ACCESS maps into per-version code Greg Kroah-Hartman
` (652 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chuck Lever, Sasha Levin
6.18-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 fbf573c317193..b71c869aaea7c 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 ef4971d71ac4b..067ae1c8aaa5a 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 1bf4a84d6a19c..161208b972be2 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -68,6 +68,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,
@@ -1302,7 +1316,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);
@@ -1826,7 +1840,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 2fe4767dca5b5..7b243d9d71733 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1458,7 +1458,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 c561d7014b49f..aab68a65ad563 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 53b55ee4e00ee..a126da5c3e8e3 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1185,7 +1185,7 @@ static int wait_for_concurrent_writes(struct file *file)
* @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.
@@ -1197,7 +1197,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;
@@ -1234,21 +1234,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) {
@@ -1284,7 +1274,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);
@@ -1375,7 +1365,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.
@@ -1385,8 +1375,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;
@@ -1398,7 +1388,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 1dd3ae3ceb3a8..2f589c4f0248c 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -131,11 +131,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 522067b7fd755..7b5e3e3bac006 100644
--- a/fs/nfsd/xdr3.h
+++ b/fs/nfsd/xdr3.h
@@ -38,7 +38,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 e947af6a3684a..7c5ab7ae7b532 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -390,6 +390,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] 687+ messages in thread
* [PATCH 6.18 034/686] NFSD: Move version-specific ACCESS maps into per-version code
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (32 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 033/686] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags" Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 035/686] NFSD: map fh_verify() status codes for NFS_ACLv2 replies Greg Kroah-Hartman
` (651 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.18-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 2998640f259de..537097ce8c767 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 b71c869aaea7c..87c5e766133c8 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 161208b972be2..6c33eebd1a144 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -68,6 +68,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) {
@@ -764,10 +801,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 a126da5c3e8e3..7094902ca93a8 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -753,64 +753,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;
@@ -824,12 +781,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++) {
@@ -839,7 +795,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 2f589c4f0248c..7f6b90b6272d1 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -38,6 +38,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;
/*
@@ -96,7 +107,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] 687+ messages in thread
* [PATCH 6.18 035/686] NFSD: map fh_verify() status codes for NFS_ACLv2 replies
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (33 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 034/686] NFSD: Move version-specific ACCESS maps into per-version code Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 036/686] NFSD/blocklayout: Extract extent mapping from proc_layoutget Greg Kroah-Hartman
` (650 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.18-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 537097ce8c767..87269be93d0f6 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] 687+ messages in thread
* [PATCH 6.18 036/686] NFSD/blocklayout: Extract extent mapping from proc_layoutget
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (34 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 035/686] NFSD: map fh_verify() status codes for NFS_ACLv2 replies Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 037/686] exportfs: Complete kernel-doc for struct export_operations Greg Kroah-Hartman
` (649 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sergey Bashirov, Christoph Hellwig,
Chuck Lever, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Bashirov <sergeybashirov@gmail.com>
[ Upstream commit a1dce715c64d4376321b5534366ae48fd7d14bcc ]
No changes in functionality. Split the proc_layoutget function to
create a helper function that maps single extent to the requested
range. This helper function is then used to implement support for
multiple extents per LAYOUTGET.
Signed-off-by: Sergey Bashirov <sergeybashirov@gmail.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/blocklayout.c | 115 ++++++++++++++++++++++++------------------
1 file changed, 66 insertions(+), 49 deletions(-)
diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index e9512c34c9dcf..8f6478d88ea22 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -17,68 +17,44 @@
#define NFSDDBG_FACILITY NFSDDBG_PNFS
+/*
+ * Get an extent from the file system that starts at offset or below
+ * and may be shorter than the requested length.
+ */
static __be32
-nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
- const struct svc_fh *fhp, struct nfsd4_layoutget *args)
+nfsd4_block_map_extent(struct inode *inode, const struct svc_fh *fhp,
+ u64 offset, u64 length, u32 iomode, u64 minlength,
+ struct pnfs_block_extent *bex)
{
- struct nfsd4_layout_seg *seg = &args->lg_seg;
struct super_block *sb = inode->i_sb;
- u64 length;
- u32 block_size = i_blocksize(inode);
- struct pnfs_block_extent *bex;
struct iomap iomap;
u32 device_generation = 0;
int error;
- if (locks_in_grace(SVC_NET(rqstp)))
- return nfserr_grace;
-
- if (seg->offset & (block_size - 1)) {
- dprintk("pnfsd: I/O misaligned\n");
- goto out_layoutunavailable;
- }
-
- /*
- * Some clients barf on non-zero block numbers for NONE or INVALID
- * layouts, so make sure to zero the whole structure.
- */
- error = -ENOMEM;
- bex = kzalloc(sizeof(*bex), GFP_KERNEL);
- if (!bex)
- goto out_error;
- args->lg_content = bex;
-
- error = sb->s_export_op->map_blocks(inode, seg->offset, seg->length,
- &iomap, seg->iomode != IOMODE_READ,
- &device_generation);
+ error = sb->s_export_op->map_blocks(inode, offset, length, &iomap,
+ iomode != IOMODE_READ, &device_generation);
if (error) {
if (error == -ENXIO)
- goto out_layoutunavailable;
- goto out_error;
- }
-
- length = iomap.offset + iomap.length - seg->offset;
- if (length < args->lg_minlength) {
- dprintk("pnfsd: extent smaller than minlength\n");
- goto out_layoutunavailable;
+ return nfserr_layoutunavailable;
+ return nfserrno(error);
}
switch (iomap.type) {
case IOMAP_MAPPED:
- if (seg->iomode == IOMODE_READ)
+ if (iomode == IOMODE_READ)
bex->es = PNFS_BLOCK_READ_DATA;
else
bex->es = PNFS_BLOCK_READWRITE_DATA;
bex->soff = iomap.addr;
break;
case IOMAP_UNWRITTEN:
- if (seg->iomode & IOMODE_RW) {
+ if (iomode & IOMODE_RW) {
/*
* Crack monkey special case from section 2.3.1.
*/
- if (args->lg_minlength == 0) {
+ if (minlength == 0) {
dprintk("pnfsd: no soup for you!\n");
- goto out_layoutunavailable;
+ return nfserr_layoutunavailable;
}
bex->es = PNFS_BLOCK_INVALID_DATA;
@@ -87,7 +63,7 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
}
fallthrough;
case IOMAP_HOLE:
- if (seg->iomode == IOMODE_READ) {
+ if (iomode == IOMODE_READ) {
bex->es = PNFS_BLOCK_NONE_DATA;
break;
}
@@ -95,27 +71,68 @@ nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
case IOMAP_DELALLOC:
default:
WARN(1, "pnfsd: filesystem returned %d extent\n", iomap.type);
- goto out_layoutunavailable;
+ return nfserr_layoutunavailable;
}
error = nfsd4_set_deviceid(&bex->vol_id, fhp, device_generation);
if (error)
- goto out_error;
+ return nfserrno(error);
+
bex->foff = iomap.offset;
bex->len = iomap.length;
+ return nfs_ok;
+}
+
+static __be32
+nfsd4_block_proc_layoutget(struct svc_rqst *rqstp, struct inode *inode,
+ const struct svc_fh *fhp, struct nfsd4_layoutget *args)
+{
+ struct nfsd4_layout_seg *seg = &args->lg_seg;
+ struct pnfs_block_extent *bex;
+ u64 length;
+ u32 block_size = i_blocksize(inode);
+ __be32 nfserr;
+
+ if (locks_in_grace(SVC_NET(rqstp)))
+ return nfserr_grace;
- seg->offset = iomap.offset;
- seg->length = iomap.length;
+ nfserr = nfserr_layoutunavailable;
+ if (seg->offset & (block_size - 1)) {
+ dprintk("pnfsd: I/O misaligned\n");
+ goto out_error;
+ }
+
+ /*
+ * Some clients barf on non-zero block numbers for NONE or INVALID
+ * layouts, so make sure to zero the whole structure.
+ */
+ nfserr = nfserrno(-ENOMEM);
+ bex = kzalloc(sizeof(*bex), GFP_KERNEL);
+ if (!bex)
+ goto out_error;
+ args->lg_content = bex;
+
+ nfserr = nfsd4_block_map_extent(inode, fhp, seg->offset, seg->length,
+ seg->iomode, args->lg_minlength, bex);
+ if (nfserr != nfs_ok)
+ goto out_error;
+
+ nfserr = nfserr_layoutunavailable;
+ length = bex->foff + bex->len - seg->offset;
+ if (length < args->lg_minlength) {
+ dprintk("pnfsd: extent smaller than minlength\n");
+ goto out_error;
+ }
+
+ seg->offset = bex->foff;
+ seg->length = bex->len;
dprintk("GET: 0x%llx:0x%llx %d\n", bex->foff, bex->len, bex->es);
- return 0;
+ return nfs_ok;
out_error:
seg->length = 0;
- return nfserrno(error);
-out_layoutunavailable:
- seg->length = 0;
- return nfserr_layoutunavailable;
+ return nfserr;
}
static __be32
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 037/686] exportfs: Complete kernel-doc for struct export_operations
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (35 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 036/686] NFSD/blocklayout: Extract extent mapping from proc_layoutget Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 038/686] exportfs: split out the ops for layout-based block device access Greg Kroah-Hartman
` (648 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, André Almeida, Chuck Lever,
Christian Brauner, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Almeida <andrealmeid@igalia.com>
[ Upstream commit 7a6f811e2c06d656996776771f0498df129a0cc2 ]
Write down the missing members definitions for struct export_operations,
using as a reference the commit messages that created the members.
Signed-off-by: André Almeida <andrealmeid@igalia.com>
Link: https://patch.msgid.link/20260112-tonyk-fs_uuid-v1-3-acc1889de772@igalia.com
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/exportfs.h | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index f0cf2714ec52d..0dc1bae9e1654 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -201,7 +201,7 @@ struct handle_to_path_ctx {
* @commit_metadata: commit metadata changes to stable storage
*
* See Documentation/filesystems/nfs/exporting.rst for details on how to use
- * this interface correctly.
+ * this interface correctly and the definition of the flags.
*
* encode_fh:
* @encode_fh should store in the file handle fragment @fh (using at most
@@ -252,6 +252,19 @@ struct handle_to_path_ctx {
* commit_metadata:
* @commit_metadata should commit metadata changes to stable storage.
*
+ * @get_uuid:
+ * Get a filesystem unique signature exposed to clients.
+ *
+ * @map_blocks:
+ * Map and, if necessary, allocate blocks for a layout.
+ *
+ * @commit_blocks:
+ * Commit blocks in a layout once the client is done with them.
+ *
+ * @flags:
+ * Allows the filesystem to communicate to nfsd that it may want to do things
+ * differently when dealing with it.
+ *
* Locking rules:
* get_parent is called with child->d_inode->i_rwsem down
* get_name is not (which is possibly inconsistent)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 038/686] exportfs: split out the ops for layout-based block device access
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (36 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 037/686] exportfs: Complete kernel-doc for struct export_operations Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 039/686] exportfs,nfsd: rework checking for layout-based block device access support Greg Kroah-Hartman
` (647 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Jeff Layton,
Chuck Lever, Christian Brauner, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit d5758c31a81bcd9d5ac8a7456549b05df3579068 ]
The support to grant layouts for direct block device access works
at a very different layer than the rest of exports. Split the methods
for it into a separate struct, and move that into a separate header
to better split things out. The pointer to the new operation vector
is kept in export_operations to avoid bloating the super_block.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Link: https://patch.msgid.link/20260423181854.743150-3-cel@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
MAINTAINERS | 2 +-
fs/nfsd/blocklayout.c | 14 ++++++------
fs/nfsd/nfs4layouts.c | 9 ++++----
fs/xfs/xfs_export.c | 4 +---
fs/xfs/xfs_pnfs.c | 12 ++++++++---
fs/xfs/xfs_pnfs.h | 11 +++++-----
include/linux/exportfs.h | 25 +++++++---------------
include/linux/exportfs_block.h | 39 ++++++++++++++++++++++++++++++++++
8 files changed, 74 insertions(+), 42 deletions(-)
create mode 100644 include/linux/exportfs_block.h
diff --git a/MAINTAINERS b/MAINTAINERS
index f5ea8588244c9..5821d97ae3304 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9606,7 +9606,7 @@ S: Supported
F: Documentation/filesystems/nfs/exporting.rst
F: fs/exportfs/
F: fs/fhandle.c
-F: include/linux/exportfs.h
+F: include/linux/exportfs*.h
FILESYSTEMS [IDMAPPED MOUNTS]
M: Christian Brauner <brauner@kernel.org>
diff --git a/fs/nfsd/blocklayout.c b/fs/nfsd/blocklayout.c
index 8f6478d88ea22..ac1312fd1c457 100644
--- a/fs/nfsd/blocklayout.c
+++ b/fs/nfsd/blocklayout.c
@@ -2,7 +2,7 @@
/*
* Copyright (c) 2014-2016 Christoph Hellwig.
*/
-#include <linux/exportfs.h>
+#include <linux/exportfs_block.h>
#include <linux/iomap.h>
#include <linux/slab.h>
#include <linux/pr.h>
@@ -31,8 +31,8 @@ nfsd4_block_map_extent(struct inode *inode, const struct svc_fh *fhp,
u32 device_generation = 0;
int error;
- error = sb->s_export_op->map_blocks(inode, offset, length, &iomap,
- iomode != IOMODE_READ, &device_generation);
+ error = sb->s_export_op->block_ops->map_blocks(inode, offset, length,
+ &iomap, iomode != IOMODE_READ, &device_generation);
if (error) {
if (error == -ENXIO)
return nfserr_layoutunavailable;
@@ -154,8 +154,8 @@ nfsd4_block_commit_blocks(struct inode *inode, struct nfsd4_layoutcommit *lcp,
iattr.ia_size = lcp->lc_newsize;
}
- error = inode->i_sb->s_export_op->commit_blocks(inode, iomaps,
- nr_iomaps, &iattr);
+ error = inode->i_sb->s_export_op->block_ops->commit_blocks(inode,
+ iomaps, nr_iomaps, &iattr);
kfree(iomaps);
return nfserrno(error);
}
@@ -178,8 +178,8 @@ nfsd4_block_get_device_info_simple(struct super_block *sb,
b->type = PNFS_BLOCK_VOLUME_SIMPLE;
b->simple.sig_len = PNFS_BLOCK_UUID_LEN;
- return sb->s_export_op->get_uuid(sb, b->simple.sig, &b->simple.sig_len,
- &b->simple.offset);
+ return sb->s_export_op->block_ops->get_uuid(sb, b->simple.sig,
+ &b->simple.sig_len, &b->simple.offset);
}
static __be32
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 2121ef26e7a98..6b6f55ae0472d 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -3,6 +3,7 @@
* Copyright (c) 2014 Christoph Hellwig.
*/
#include <linux/blkdev.h>
+#include <linux/exportfs_block.h>
#include <linux/kmod.h>
#include <linux/file.h>
#include <linux/jhash.h>
@@ -127,6 +128,7 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
{
#if defined(CONFIG_NFSD_BLOCKLAYOUT) || defined(CONFIG_NFSD_SCSILAYOUT)
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
+ const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
#endif
if (!(exp->ex_flags & NFSEXP_PNFS))
@@ -136,14 +138,11 @@ void nfsd4_setup_layout_type(struct svc_export *exp)
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
#endif
#ifdef CONFIG_NFSD_BLOCKLAYOUT
- if (sb->s_export_op->get_uuid &&
- sb->s_export_op->map_blocks &&
- sb->s_export_op->commit_blocks)
+ if (bops && bops->get_uuid && bops->map_blocks && bops->commit_blocks)
exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
#endif
#ifdef CONFIG_NFSD_SCSILAYOUT
- if (sb->s_export_op->map_blocks &&
- sb->s_export_op->commit_blocks &&
+ if (bops && bops->map_blocks && bops->commit_blocks &&
sb->s_bdev &&
sb->s_bdev->bd_disk->fops->pr_ops &&
sb->s_bdev->bd_disk->fops->get_unique_id)
diff --git a/fs/xfs/xfs_export.c b/fs/xfs/xfs_export.c
index 201489d3de089..f64e035cacb55 100644
--- a/fs/xfs/xfs_export.c
+++ b/fs/xfs/xfs_export.c
@@ -244,8 +244,6 @@ const struct export_operations xfs_export_operations = {
.get_parent = xfs_fs_get_parent,
.commit_metadata = xfs_fs_nfs_commit_metadata,
#ifdef CONFIG_EXPORTFS_BLOCK_OPS
- .get_uuid = xfs_fs_get_uuid,
- .map_blocks = xfs_fs_map_blocks,
- .commit_blocks = xfs_fs_commit_blocks,
+ .block_ops = &xfs_export_block_ops,
#endif
};
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index afe7497012d4c..c685995b69d7e 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -49,7 +49,7 @@ xfs_break_leased_layouts(
* Get a unique ID including its location so that the client can identify
* the exported device.
*/
-int
+static int
xfs_fs_get_uuid(
struct super_block *sb,
u8 *buf,
@@ -104,7 +104,7 @@ xfs_fs_map_update_inode(
/*
* Get a layout for the pNFS client.
*/
-int
+static int
xfs_fs_map_blocks(
struct inode *inode,
loff_t offset,
@@ -252,7 +252,7 @@ xfs_pnfs_validate_isize(
* to manually flush the cache here similar to what the fsync code path does
* for datasyncs on files that have no dirty metadata.
*/
-int
+static int
xfs_fs_commit_blocks(
struct inode *inode,
struct iomap *maps,
@@ -332,3 +332,9 @@ xfs_fs_commit_blocks(
xfs_iunlock(ip, XFS_IOLOCK_EXCL);
return error;
}
+
+const struct exportfs_block_ops xfs_export_block_ops = {
+ .get_uuid = xfs_fs_get_uuid,
+ .map_blocks = xfs_fs_map_blocks,
+ .commit_blocks = xfs_fs_commit_blocks,
+};
diff --git a/fs/xfs/xfs_pnfs.h b/fs/xfs/xfs_pnfs.h
index 940c6c2ad88c5..bf43b2009e4cc 100644
--- a/fs/xfs/xfs_pnfs.h
+++ b/fs/xfs/xfs_pnfs.h
@@ -2,13 +2,9 @@
#ifndef _XFS_PNFS_H
#define _XFS_PNFS_H 1
-#ifdef CONFIG_EXPORTFS_BLOCK_OPS
-int xfs_fs_get_uuid(struct super_block *sb, u8 *buf, u32 *len, u64 *offset);
-int xfs_fs_map_blocks(struct inode *inode, loff_t offset, u64 length,
- struct iomap *iomap, bool write, u32 *device_generation);
-int xfs_fs_commit_blocks(struct inode *inode, struct iomap *maps, int nr_maps,
- struct iattr *iattr);
+#include <linux/exportfs_block.h>
+#ifdef CONFIG_EXPORTFS_BLOCK_OPS
int xfs_break_leased_layouts(struct inode *inode, uint *iolock,
bool *did_unlock);
#else
@@ -18,4 +14,7 @@ xfs_break_leased_layouts(struct inode *inode, uint *iolock, bool *did_unlock)
return 0;
}
#endif /* CONFIG_EXPORTFS_BLOCK_OPS */
+
+extern const struct exportfs_block_ops xfs_export_block_ops;
+
#endif /* _XFS_PNFS_H */
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h
index 0dc1bae9e1654..dfeadad435a60 100644
--- a/include/linux/exportfs.h
+++ b/include/linux/exportfs.h
@@ -6,9 +6,8 @@
#include <linux/path.h>
struct dentry;
-struct iattr;
+struct exportfs_block_ops;
struct inode;
-struct iomap;
struct super_block;
struct vfsmount;
@@ -252,19 +251,13 @@ struct handle_to_path_ctx {
* commit_metadata:
* @commit_metadata should commit metadata changes to stable storage.
*
- * @get_uuid:
- * Get a filesystem unique signature exposed to clients.
- *
- * @map_blocks:
- * Map and, if necessary, allocate blocks for a layout.
- *
- * @commit_blocks:
- * Commit blocks in a layout once the client is done with them.
- *
* @flags:
* Allows the filesystem to communicate to nfsd that it may want to do things
* differently when dealing with it.
*
+ * @block_ops:
+ * Operations for layout grants to block on the underlying device.
+ *
* Locking rules:
* get_parent is called with child->d_inode->i_rwsem down
* get_name is not (which is possibly inconsistent)
@@ -282,12 +275,6 @@ struct export_operations {
struct dentry * (*get_parent)(struct dentry *child);
int (*commit_metadata)(struct inode *inode);
- int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset);
- int (*map_blocks)(struct inode *inode, loff_t offset,
- u64 len, struct iomap *iomap,
- bool write, u32 *device_generation);
- int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
- int nr_iomaps, struct iattr *iattr);
int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags);
struct file * (*open)(const struct path *path, unsigned int oflags);
#define EXPORT_OP_NOWCC (0x1) /* don't collect v3 wcc data */
@@ -300,6 +287,10 @@ struct export_operations {
#define EXPORT_OP_FLUSH_ON_CLOSE (0x20) /* fs flushes file data on close */
#define EXPORT_OP_NOLOCKS (0x40) /* no file locking support */
unsigned long flags;
+
+#ifdef CONFIG_EXPORTFS_BLOCK_OPS
+ const struct exportfs_block_ops *block_ops;
+#endif
};
/**
diff --git a/include/linux/exportfs_block.h b/include/linux/exportfs_block.h
new file mode 100644
index 0000000000000..1f52fea8e4dce
--- /dev/null
+++ b/include/linux/exportfs_block.h
@@ -0,0 +1,39 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2014-2026 Christoph Hellwig.
+ *
+ * Support for exportfs-based layout grants for direct block device access.
+ */
+#ifndef LINUX_EXPORTFS_BLOCK_H
+#define LINUX_EXPORTFS_BLOCK_H 1
+
+#include <linux/types.h>
+
+struct iattr;
+struct inode;
+struct iomap;
+struct super_block;
+
+struct exportfs_block_ops {
+ /*
+ * Get the in-band device unique signature exposed to clients.
+ */
+ int (*get_uuid)(struct super_block *sb, u8 *buf, u32 *len, u64 *offset);
+
+ /*
+ * Map blocks for direct block access.
+ * If @write is %true, also allocate the blocks for the range if needed.
+ */
+ int (*map_blocks)(struct inode *inode, loff_t offset, u64 len,
+ struct iomap *iomap, bool write,
+ u32 *device_generation);
+
+ /*
+ * Commit blocks previously handed out by ->map_blocks and written to by
+ * the client.
+ */
+ int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,
+ int nr_iomaps, struct iattr *iattr);
+};
+
+#endif /* LINUX_EXPORTFS_BLOCK_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 039/686] exportfs,nfsd: rework checking for layout-based block device access support
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (37 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 038/686] exportfs: split out the ops for layout-based block device access Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 040/686] nfsd: dont offer flexfiles layouts when NFSv3 isnt being served Greg Kroah-Hartman
` (646 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Jeff Layton,
Chuck Lever, Christian Brauner, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig <hch@lst.de>
[ Upstream commit da9baa5470dcb077a7c9806f0925c60b530c470b ]
Currently NFSD hard codes checking support for block-style layouts.
Lift the checks into a file system-helper and provide a exportfs-level
helper to implement the typical checks.
This prepares for supporting block layout export of multiple devices
per file system.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Link: https://patch.msgid.link/20260423181854.743150-5-cel@kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 5d28b2c920d9 ("nfsd: don't offer flexfiles layouts when NFSv3 isn't being served")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/export.c | 3 +-
fs/nfsd/nfs4layouts.c | 26 +++++------------
fs/xfs/xfs_pnfs.c | 13 +++++++++
include/linux/exportfs_block.h | 52 +++++++++++++++++++++++++++++++++-
4 files changed, 73 insertions(+), 21 deletions(-)
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 2a1499f2ad196..e33843a937dd6 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -722,7 +722,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
goto out4;
err = 0;
- nfsd4_setup_layout_type(&exp);
+ if (exp.ex_flags & NFSEXP_PNFS)
+ nfsd4_setup_layout_type(&exp);
}
expp = svc_export_lookup(&exp);
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index 6b6f55ae0472d..c2d435c99bf5e 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -2,7 +2,6 @@
/*
* Copyright (c) 2014 Christoph Hellwig.
*/
-#include <linux/blkdev.h>
#include <linux/exportfs_block.h>
#include <linux/kmod.h>
#include <linux/file.h>
@@ -126,28 +125,17 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
void nfsd4_setup_layout_type(struct svc_export *exp)
{
-#if defined(CONFIG_NFSD_BLOCKLAYOUT) || defined(CONFIG_NFSD_SCSILAYOUT)
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
- const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
-#endif
-
- if (!(exp->ex_flags & NFSEXP_PNFS))
- return;
+ expfs_block_layouts_t block_supported = exportfs_layouts_supported(sb);
-#ifdef CONFIG_NFSD_FLEXFILELAYOUT
- exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
-#endif
-#ifdef CONFIG_NFSD_BLOCKLAYOUT
- if (bops && bops->get_uuid && bops->map_blocks && bops->commit_blocks)
+ if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT))
+ exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
+ if (IS_ENABLED(CONFIG_NFSD_BLOCKLAYOUT) &&
+ (block_supported & EXPFS_BLOCK_IN_BAND_ID))
exp->ex_layout_types |= 1 << LAYOUT_BLOCK_VOLUME;
-#endif
-#ifdef CONFIG_NFSD_SCSILAYOUT
- if (bops && bops->map_blocks && bops->commit_blocks &&
- sb->s_bdev &&
- sb->s_bdev->bd_disk->fops->pr_ops &&
- sb->s_bdev->bd_disk->fops->get_unique_id)
+ if (IS_ENABLED(CONFIG_NFSD_SCSILAYOUT) &&
+ (block_supported & EXPFS_BLOCK_OUT_OF_BAND_ID))
exp->ex_layout_types |= 1 << LAYOUT_SCSI;
-#endif
}
void nfsd4_close_layout(struct nfs4_layout_stateid *ls)
diff --git a/fs/xfs/xfs_pnfs.c b/fs/xfs/xfs_pnfs.c
index c685995b69d7e..1b0b739571612 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -13,6 +13,7 @@
#include "xfs_bmap.h"
#include "xfs_iomap.h"
#include "xfs_pnfs.h"
+#include <linux/exportfs_block.h>
/*
* Ensure that we do not have any outstanding pNFS layouts that can be used by
@@ -45,6 +46,17 @@ xfs_break_leased_layouts(
return error;
}
+static expfs_block_layouts_t
+xfs_fs_layouts_supported(
+ struct super_block *sb)
+{
+ expfs_block_layouts_t supported = EXPFS_BLOCK_IN_BAND_ID;
+
+ if (exportfs_bdev_supports_out_of_band_id(sb->s_bdev))
+ supported |= EXPFS_BLOCK_OUT_OF_BAND_ID;
+ return supported;
+}
+
/*
* Get a unique ID including its location so that the client can identify
* the exported device.
@@ -334,6 +346,7 @@ xfs_fs_commit_blocks(
}
const struct exportfs_block_ops xfs_export_block_ops = {
+ .layouts_supported = xfs_fs_layouts_supported,
.get_uuid = xfs_fs_get_uuid,
.map_blocks = xfs_fs_map_blocks,
.commit_blocks = xfs_fs_commit_blocks,
diff --git a/include/linux/exportfs_block.h b/include/linux/exportfs_block.h
index 1f52fea8e4dce..92f990d190bba 100644
--- a/include/linux/exportfs_block.h
+++ b/include/linux/exportfs_block.h
@@ -7,14 +7,36 @@
#ifndef LINUX_EXPORTFS_BLOCK_H
#define LINUX_EXPORTFS_BLOCK_H 1
-#include <linux/types.h>
+#include <linux/blkdev.h>
+#include <linux/exportfs.h>
+#include <linux/fs.h>
struct iattr;
struct inode;
struct iomap;
struct super_block;
+/*
+ * There are the two types of block-style layout support:
+ * - In-band implies a device identified by a unique cookie inside the actual
+ * device address space checked by the ->get_uuid method as used by the pNFS
+ * block layout. This is a bit dangerous and deprecated.
+ * - Out of band implies identification by out of band unique identifiers
+ * specified by the storage protocol, which is much safer and used by the
+ * pNFS SCSI/NVMe layouts.
+ */
+typedef unsigned int __bitwise expfs_block_layouts_t;
+#define EXPFS_BLOCK_FLAG(__bit) \
+ ((__force expfs_block_layouts_t)(1u << __bit))
+#define EXPFS_BLOCK_IN_BAND_ID EXPFS_BLOCK_FLAG(0)
+#define EXPFS_BLOCK_OUT_OF_BAND_ID EXPFS_BLOCK_FLAG(1)
+
struct exportfs_block_ops {
+ /*
+ * Returns the EXPFS_BLOCK_* bitmap of supported layout types.
+ */
+ expfs_block_layouts_t (*layouts_supported)(struct super_block *sb);
+
/*
* Get the in-band device unique signature exposed to clients.
*/
@@ -36,4 +58,32 @@ struct exportfs_block_ops {
int nr_iomaps, struct iattr *iattr);
};
+static inline bool
+exportfs_bdev_supports_out_of_band_id(struct block_device *bdev)
+{
+ return bdev->bd_disk->fops->pr_ops &&
+ bdev->bd_disk->fops->get_unique_id;
+}
+
+#ifdef CONFIG_EXPORTFS_BLOCK_OPS
+static inline expfs_block_layouts_t
+exportfs_layouts_supported(struct super_block *sb)
+{
+ const struct exportfs_block_ops *bops = sb->s_export_op->block_ops;
+
+ if (!bops ||
+ !bops->layouts_supported ||
+ WARN_ON_ONCE(!bops->map_blocks) ||
+ WARN_ON_ONCE(!bops->commit_blocks))
+ return 0;
+ return bops->layouts_supported(sb);
+}
+#else
+static inline expfs_block_layouts_t
+exportfs_layouts_supported(struct super_block *sb)
+{
+ return 0;
+}
+#endif /* CONFIG_EXPORTFS_BLOCK_OPS */
+
#endif /* LINUX_EXPORTFS_BLOCK_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 040/686] nfsd: dont offer flexfiles layouts when NFSv3 isnt being served
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (38 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 039/686] exportfs,nfsd: rework checking for layout-based block device access support Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 041/686] NFSD: report listener creation failures through extack Greg Kroah-Hartman
` (645 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benji Wiebe, Jeff Layton,
Chuck Lever, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <jlayton@kernel.org>
[ Upstream commit 5d28b2c920d9d9d3c45b41769342ad785eb372a7 ]
The flexfiles layout driver hands out a deviceinfo that names this server
as an NFSv3 DS (flexfilelayout.c hardcodes da->version = 3). With v3
disabled, the client can't talk to the DS: it loops on v3 NULL calls that
the server answers with PROG_MISMATCH, and I/O hangs in D state.
Skip LAYOUT_FLEX_FILES in nfsd4_setup_layout_type() unless v3 is enabled.
Reported-by: Benji Wiebe <itsme@benjiwiebe.com>
Closes: https://lore.kernel.org/linux-nfs/c734eeb8-8486-4491-bb4d-b9656cbaffbe@app.fastmail.com/
Fixes: 9b9960a0ca47 ("nfsd: Add a super simple flex file server")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260904-pnfs-ff-v1-1-5f502cf25401@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4layouts.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c
index c2d435c99bf5e..8ec980c69bec5 100644
--- a/fs/nfsd/nfs4layouts.c
+++ b/fs/nfsd/nfs4layouts.c
@@ -125,10 +125,12 @@ nfsd4_set_deviceid(struct nfsd4_deviceid *id, const struct svc_fh *fhp,
void nfsd4_setup_layout_type(struct svc_export *exp)
{
+ struct nfsd_net *nn = net_generic(exp->cd->net, nfsd_net_id);
struct super_block *sb = exp->ex_path.mnt->mnt_sb;
expfs_block_layouts_t block_supported = exportfs_layouts_supported(sb);
- if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT))
+ if (IS_ENABLED(CONFIG_NFSD_FLEXFILELAYOUT) &&
+ nfsd_vers(nn, 3, NFSD_TEST))
exp->ex_layout_types |= 1 << LAYOUT_FLEX_FILES;
if (IS_ENABLED(CONFIG_NFSD_BLOCKLAYOUT) &&
(block_supported & EXPFS_BLOCK_IN_BAND_ID))
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 041/686] NFSD: report listener creation failures through extack
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (39 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 040/686] nfsd: dont offer flexfiles layouts when NFSv3 isnt being served Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 042/686] SUNRPC: report local rpcbind calls that get no answer Greg Kroah-Hartman
` (644 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.18-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 967c5bf30d051..49cd0588deb39 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2026,7 +2026,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);
@@ -2145,8 +2147,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] 687+ messages in thread
* [PATCH 6.18 042/686] SUNRPC: report local rpcbind calls that get no answer
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (40 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 041/686] NFSD: report listener creation failures through extack Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 043/686] NFSD: stop registering with rpcbind after a failure in listener_set Greg Kroah-Hartman
` (643 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.18-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 5506d20857c31..1668804db44dd 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -75,6 +75,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 */
@@ -435,6 +436,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,
@@ -450,8 +452,9 @@ int svc_set_num_threads(struct svc_serv *, struct svc_pool *, int);
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 2d74c660de666..9b90350820be4 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 61c3c3a743289..a3933f86f2d42 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1207,10 +1207,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
@@ -1221,10 +1251,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;
@@ -1236,10 +1267,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",
@@ -1251,6 +1288,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] 687+ messages in thread
* [PATCH 6.18 043/686] NFSD: stop registering with rpcbind after a failure in listener_set
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (41 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 042/686] SUNRPC: report local rpcbind calls that get no answer Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 044/686] NFS/localio: detect a short read or write before the iterator has moved Greg Kroah-Hartman
` (642 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Olga Kornievskaia, Jeff Layton,
Chuck Lever, Sasha Levin
6.18-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 49cd0588deb39..9ffa72c15aed2 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2029,7 +2029,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;
@@ -2119,13 +2122,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,
@@ -2144,12 +2150,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;
}
}
@@ -2161,8 +2182,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] 687+ messages in thread
* [PATCH 6.18 044/686] NFS/localio: detect a short read or write before the iterator has moved
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (42 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 043/686] NFSD: stop registering with rpcbind after a failure in listener_set Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 045/686] NFSD: Count the delegations held by each client Greg Kroah-Hartman
` (641 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mike Snitzer, Anna Schumaker,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Snitzer <snitzer@kernel.org>
[ Upstream commit db3ca539c1142d2c5380c5dbd3154ab7bb1c7d77 ]
nfs_local_call_read() and nfs_local_call_write() issue a misaligned
DIO as up to three segments and must stop at the first short one, or
the next segment lands at the wrong file offset. They test for that
by comparing the bytes transferred against iov_iter_count() of the
segment, read after read_iter() or write_iter() has advanced the
iterator, when the count is the residual rather than the request:
before the call: count == expected
after the call: count == expected - status
The test is therefore status < expected - status, and it fires only
when less than half of the segment was transferred. A short I/O that
covers between 50% and 99% of a segment slips through: the loop moves
on with ki_pos advanced by the short amount, the next segment is
issued at the wrong offset, and the header's byte count is
over-reported to the caller. A write that slips through also never
sets NFS_CONTEXT_WRITE_SYNC, which is what makes the writes that
follow a short one synchronous.
Take the segment's count before issuing it and compare against that.
This is the same defect that commit 250ec14932d5 ("nfsd: fix
partial-write detection in nfsd_direct_write") fixed in NFSD's version
of this loop.
Fixes: c817248fc831 ("nfs/localio: add proper O_DIRECT support for READ and WRITE")
Fixes: d0497dd27452 ("nfs/localio: backfill missing partial read support for misaligned DIO")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com>
[ sashal: adapted completion handling to the three-argument nfs_local_pgio_done() helper using force_done ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfs/localio.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/localio.c b/fs/nfs/localio.c
index 3c5891d3ab897..3138439d19109 100644
--- a/fs/nfs/localio.c
+++ b/fs/nfs/localio.c
@@ -682,6 +682,8 @@ static void nfs_local_call_read(struct work_struct *work)
n_iters = atomic_read(&iocb->n_iters);
for (int i = 0; i < n_iters ; i++) {
+ size_t expected;
+
if (iocb->iter_is_dio_aligned[i]) {
iocb->kiocb.ki_flags |= IOCB_DIRECT;
/* Only use AIO completion if DIO-aligned segment is last */
@@ -692,12 +694,14 @@ static void nfs_local_call_read(struct work_struct *work)
} else
iocb->kiocb.ki_flags &= ~IOCB_DIRECT;
+ /* read_iter() advances the iterator: measure it beforehand */
+ expected = iov_iter_count(&iocb->iters[i]);
save_cred = override_creds(filp->f_cred);
status = filp->f_op->read_iter(&iocb->kiocb, &iocb->iters[i]);
revert_creds(save_cred);
if (status != -EIOCBQUEUED) {
- if (unlikely(status >= 0 && status < iocb->iters[i].count))
+ if (unlikely(status >= 0 && (size_t)status < expected))
force_done = true; /* Partial read */
if (nfs_local_pgio_done(iocb, status, force_done)) {
nfs_local_read_iocb_done(iocb);
@@ -878,6 +882,8 @@ static void nfs_local_call_write(struct work_struct *work)
file_start_write(filp);
n_iters = atomic_read(&iocb->n_iters);
for (int i = 0; i < n_iters ; i++) {
+ size_t expected;
+
if (iocb->iter_is_dio_aligned[i]) {
iocb->kiocb.ki_flags |= IOCB_DIRECT;
/* Only use AIO completion if DIO-aligned segment is last */
@@ -888,12 +894,14 @@ static void nfs_local_call_write(struct work_struct *work)
} else
iocb->kiocb.ki_flags &= ~IOCB_DIRECT;
+ /* write_iter() advances the iterator: measure it beforehand */
+ expected = iov_iter_count(&iocb->iters[i]);
save_cred = override_creds(filp->f_cred);
status = filp->f_op->write_iter(&iocb->kiocb, &iocb->iters[i]);
revert_creds(save_cred);
if (status != -EIOCBQUEUED) {
- if (unlikely(status >= 0 && status < iocb->iters[i].count))
+ if (unlikely(status >= 0 && (size_t)status < expected))
force_done = true; /* Partial write */
if (nfs_local_pgio_done(iocb, status, force_done)) {
nfs_local_write_iocb_done(iocb);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 045/686] NFSD: Count the delegations held by each client
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (43 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 044/686] NFS/localio: detect a short read or write before the iterator has moved Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 046/686] NFSD: Send a meaningful CB_RECALL_ANY keep count Greg Kroah-Hartman
` (640 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chuck Lever <cel@kernel.org>
[ Upstream commit 5d5a6e996e7c36bc2f7b035743c16f2bf03a227d ]
struct nfs4_client records the delegations it holds on cl_delegations
but keeps no count of them. deleg_reaper() walks nn->client_lru under
nn->client_lock, but cl_delegations is serialized by nn->deleg_lock,
which nests outside nn->client_lock. A caller there cannot take
nn->deleg_lock to count the list. The cost tells against the walk as
well: an O(n) count per client, on a pass that already visits every
client.
Add cl_deleg_count, maintained at the two sites that mutate
cl_delegations. Both hold nn->deleg_lock, so the counter is already
serialized against itself and needs no atomic of its own. The decrement
sits below the delegation_hashed() test, next to the list_del_init it
pairs with, so it runs only when the delegation really leaves the list.
A reader that holds only nn->client_lock is not synchronized against
either update site, so it can see a count that does not match the
list. Such a reader marks the access with data_race() and may not
depend on the value for correctness.
No functional change.
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Link: https://patch.msgid.link/20260817-recall-any-keep-count-v5-2-3b2cffce701e@kernel.org
Signed-off-by: Chuck Lever <cel@kernel.org>
Stable-dep-of: 9af39c0773ef ("NFSD: Send a meaningful CB_RECALL_ANY keep count")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4state.c | 2 ++
fs/nfsd/state.h | 2 ++
2 files changed, 4 insertions(+)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 42035bfebda7a..222f2aadaafad 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1423,6 +1423,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;
}
@@ -1454,6 +1455,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);
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 926e4e8063b33..fd61bac52721d 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -525,6 +525,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] 687+ messages in thread
* [PATCH 6.18 046/686] NFSD: Send a meaningful CB_RECALL_ANY keep count
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (44 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 045/686] NFSD: Count the delegations held by each client Greg Kroah-Hartman
@ 2026-11-13 15:42 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 047/686] NFSD: Move the cld upcall message out of the callers stack frame Greg Kroah-Hartman
` (639 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:42 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.18-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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/nfsd/nfs4state.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 222f2aadaafad..44ca5746911c8 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -7306,6 +7306,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) {
@@ -7315,21 +7316,33 @@ 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);
trace_nfsd_cb_recall_any(clp->cl_ra);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 047/686] NFSD: Move the cld upcall message out of the callers stack frame
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (45 preceding siblings ...)
2026-11-13 15:42 ` [PATCH 6.18 046/686] NFSD: Send a meaningful CB_RECALL_ANY keep count Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 048/686] NFSD: Complete a cld upcall when the daemon closes the pipe Greg Kroah-Hartman
` (638 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+d5c77cabf7a3492aa650,
Chuck Lever, Sasha Levin
6.18-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 d04a7d3aabbc8..b001d3277b9f9 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -711,6 +711,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;
@@ -722,22 +723,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;
}
@@ -910,9 +911,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] 687+ messages in thread
* [PATCH 6.18 048/686] NFSD: Complete a cld upcall when the daemon closes the pipe
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (46 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 047/686] NFSD: Move the cld upcall message out of the callers stack frame Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 049/686] NFSD: Complete a cld upcall when copying its reply fails Greg Kroah-Hartman
` (637 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+edbebd898142ee5e24ce,
Chuck Lever, Sasha Levin
6.18-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 b001d3277b9f9..e810ecb144950 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -929,10 +929,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] 687+ messages in thread
* [PATCH 6.18 049/686] NFSD: Complete a cld upcall when copying its reply fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (47 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 048/686] NFSD: Complete a cld upcall when the daemon closes the pipe Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 050/686] KVM: nSVM: Reject KVM_SET_NESTED_STATE if L1 has EFER.LMA=1 && EFER.LME=0 Greg Kroah-Hartman
` (636 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chuck Lever, Sasha Levin
6.18-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 e810ecb144950..83aba7ad39081 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -901,8 +901,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] 687+ messages in thread
* [PATCH 6.18 050/686] KVM: nSVM: Reject KVM_SET_NESTED_STATE if L1 has EFER.LMA=1 && EFER.LME=0
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (48 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 049/686] NFSD: Complete a cld upcall when copying its reply fails Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 051/686] KVM: Harden and prepare for modifying existing guest_memfd memslots Greg Kroah-Hartman
` (635 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yosry Ahmed, Stefan Teodorescu,
Sean Christopherson, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 5dc500a354cc8e109df678076ae3488094649468 ]
Reject KVM_SET_NESTED_STATE if the incoming L1 host state has what is
effectively an impossible EFER combination of LMA=1 but LME=0, i.e. if the
state says long mode is active but not enabled. Unlike VMX, SVM doesn't
have an explicit consistent check for the illegal combination; presumably
hardware simply ignores EFER.LMA if EFER.LME=0.
Unfortunately, KVM doesn't ignore EFER.LMA in this case and consumes the
illegal state when constructing the shadow MMU for L2. E.g. if userspace
also clears CR4.PAE, then kvm_calc_cpu_role() will compute a role with 4 or
5 levels of paging, but shadow_mmu_init_context() will wire up the MMU to
use the paging32 template, which maxes out its levels at 2.
Note, the "real badness" is effectively the same as what happened with the
nVMX bug fixed by commit 112e66017bff ("KVM: nVMX: add missing consistency
checks for CR0 and CR4"). Unfortunately, the sanity check added by commit
72e2fb24a0b0 ("KVM: x86/mmu: Bug the VM if a vCPU ends up in long mode
without PAE enabled") doesn't work for this case, since L2 state is active
at the time of the page fault, but it's L1 that has the bad state.
Fixes: cc440cdad5b7 ("KVM: nSVM: implement KVM_GET_NESTED_STATE and KVM_SET_NESTED_STATE")
Cc: stable@vger.kernel.org
Cc: Yosry Ahmed <yosry@kernel.org>
Reported-by: Stefan Teodorescu <fane@google.com>
Link: https://patch.msgid.link/20260902232028.2767071-2-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
[ sashal: adjusted context to retain the two-argument __nested_vmcb_check_save() helper instead of nested_vmcb_check_save() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/svm/nested.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/x86/kvm/svm/nested.c b/arch/x86/kvm/svm/nested.c
index 064a2bb9cf8ed..49cc457a4c370 100644
--- a/arch/x86/kvm/svm/nested.c
+++ b/arch/x86/kvm/svm/nested.c
@@ -1880,6 +1880,7 @@ static int svm_set_nested_state(struct kvm_vcpu *vcpu,
if (!(save->cr0 & X86_CR0_PG) ||
!(save->cr0 & X86_CR0_PE) ||
(save->rflags & X86_EFLAGS_VM) ||
+ ((save->efer & EFER_LMA) && !(save->efer & EFER_LME)) ||
!__nested_vmcb_check_save(vcpu, &save_cached))
goto out_free;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 051/686] KVM: Harden and prepare for modifying existing guest_memfd memslots
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (49 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 050/686] KVM: nSVM: Reject KVM_SET_NESTED_STATE if L1 has EFER.LMA=1 && EFER.LME=0 Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 052/686] KVM: Only bind memslot to guest_memfd instance for CREATE operations Greg Kroah-Hartman
` (634 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sean Christopherson, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit af62fe2494da84eb01752282c8228c9bb3fe9f67 ]
Unbind guest_memfd memslots if KVM commits a MOVE or FLAGS_ONLY memslot
change to harden against use-after-free, and to prepare for eventually
supporting dirty logging on guest_memfd memslots, at which point
FLAGS_ONLY changes will be expected/supported.
Add two separate WARNs, once to yell if a guest_memfd memslot is moved
(which KVM is never expected to allow/support), and again if the unbind()
is triggered, to help detect uAPI goofs prior to deliberately allowing
FLAGS_ONLY changes.
Link: https://patch.msgid.link/20251202020334.1171351-3-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Stable-dep-of: 513333a55460 ("KVM: Only bind memslot to guest_memfd instance for CREATE operations")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
virt/kvm/kvm_main.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 23e7d1bb80b04..297fd43b1da6c 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1748,6 +1748,12 @@ static void kvm_commit_memory_region(struct kvm *kvm,
kvm_free_memslot(kvm, old);
break;
case KVM_MR_MOVE:
+ /*
+ * Moving a guest_memfd memslot isn't supported, and will never
+ * be supported.
+ */
+ WARN_ON_ONCE(old->flags & KVM_MEM_GUEST_MEMFD);
+ fallthrough;
case KVM_MR_FLAGS_ONLY:
/*
* Free the dirty bitmap as needed; the below check encompasses
@@ -1756,6 +1762,15 @@ static void kvm_commit_memory_region(struct kvm *kvm,
if (old->dirty_bitmap && !new->dirty_bitmap)
kvm_destroy_dirty_bitmap(old);
+ /*
+ * Unbind the guest_memfd instance as needed; the @new slot has
+ * already created its own binding. TODO: Drop the WARN when
+ * dirty logging guest_memfd memslots is supported. Until then,
+ * flags-only changes on guest_memfd slots should be impossible.
+ */
+ if (WARN_ON_ONCE(old->flags & KVM_MEM_GUEST_MEMFD))
+ kvm_gmem_unbind(old);
+
/*
* The final quirk. Free the detached, old slot, but only its
* memory, not any metadata. Metadata, including arch specific
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 052/686] KVM: Only bind memslot to guest_memfd instance for CREATE operations
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (50 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 051/686] KVM: Harden and prepare for modifying existing guest_memfd memslots Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 053/686] KVM: guest_memfd: take the invalidate lock when unbinding a dying file Greg Kroah-Hartman
` (633 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Hildenbrand (Arm),
Sean Christopherson, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 513333a5546017da2a4a6173bfb70372f83733b3 ]
For additional defense-in-depth, and to avoid having to handle impossible
unwind scenarios when binding to a memslot fails, bind a memslot to a gmem
instance only for CREATE operations, i.e. don't attempt to establish a
binding for MOVE and FLAGS_ONLY operations. And when FLAGS_ONLY operations
are eventually supported (this is currently all dead code), creating a new
binding would be incorrect; KVM instead needs to do a 1:1 replacement of
the existing binding, i.e. FLAGS_ONLY will need its own dedicated handling.
Update the relevant TODO to make a better guess as to what needs to be done
to support toggling dirty logging for guest_memfd memslots.
Because it's dead code, no functional change intended.
Cc: stable@vger.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Link: https://patch.msgid.link/20260922001332.1121266-4-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
virt/kvm/kvm_main.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 297fd43b1da6c..5521743d6e8cb 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1763,10 +1763,10 @@ static void kvm_commit_memory_region(struct kvm *kvm,
kvm_destroy_dirty_bitmap(old);
/*
- * Unbind the guest_memfd instance as needed; the @new slot has
- * already created its own binding. TODO: Drop the WARN when
- * dirty logging guest_memfd memslots is supported. Until then,
- * flags-only changes on guest_memfd slots should be impossible.
+ * TODO: Drop the WARN and do the unbind() call only for MOVE
+ * when dirty logging guest_memfd memslots is supported. Until
+ * then, flags-only changes on guest_memfd slots should also be
+ * impossible; unbind the old memslot for defense-in-depth.
*/
if (WARN_ON_ONCE(old->flags & KVM_MEM_GUEST_MEMFD))
kvm_gmem_unbind(old);
@@ -2127,7 +2127,7 @@ static int kvm_set_memory_region(struct kvm *kvm,
new->npages = npages;
new->flags = mem->flags;
new->userspace_addr = mem->userspace_addr;
- if (mem->flags & KVM_MEM_GUEST_MEMFD) {
+ if (change == KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD)) {
r = kvm_gmem_bind(kvm, new, mem->guest_memfd, mem->guest_memfd_offset);
if (r)
goto out;
@@ -2140,7 +2140,7 @@ static int kvm_set_memory_region(struct kvm *kvm,
return 0;
out_unbind:
- if (mem->flags & KVM_MEM_GUEST_MEMFD)
+ if (change == KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD))
kvm_gmem_unbind(new);
out:
kfree(new);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 053/686] KVM: guest_memfd: take the invalidate lock when unbinding a dying file
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (51 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 052/686] KVM: Only bind memslot to guest_memfd instance for CREATE operations Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 054/686] KVM: TDX: Stuff exit_reason with UNDEFINED on wait_for_sept_zap return Greg Kroah-Hartman
` (632 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Sean Christopherson,
Shivank Garg, David Hildenbrand (Arm), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivank Garg <shivankg@amd.com>
[ Upstream commit 0ee2c883b62deb74d8c43007e8049dc006d3a2fb ]
kvm_gmem_unbind() takes mapping->invalidate_lock only if the
get_file_active() succeeds. When the guest_memfd file is dying, its
reference count is already zero so get_file_active fails and the binding
is removed without holding the invalidate lock.
kvm_gmem_invalidate_{start,end}() checks f->bindings independently to
decide whether to begin or end KVM MMU invalidation. So, the bindings
must therefore remain stable between the two calls. Otherwise, unbind
can remove a binding after start increments mmu_invalidate_in_progress,
but before end finds the binding and decrements it.
Example, unbind race with memory failure:
CPU 0: memory failure CPU 1: memslot delete
---------------------------------- ---------------------------
(guest_memfd file is dying)
kvm_gmem_error_folio()
kvm_gmem_invalidate_start()
finds binding
mmu_invalidate_in_progress++
kvm_gmem_unbind()
get_file_active() fails
removes binding
kvm_gmem_invalidate_end()
no binding found
counter stays elevated
mmu_invalidate_retry() then returns 1 forever, so guest page faults
retry without ever installing a mapping and the guest hangs.
Remove the distinction between live and dying files in the unbind path.
Always use slot->gmem.file and take the invalidate lock when it's non-NULL.
Normal unbind callers hold slots_lock, which prevents release from clearing
the pointer or freeing the file state until unbind completes. Final VM
teardown can only see a NULL pointer because guest_memfd pins the KVM until
release has cleared all bindings.
Fixes: ae431059e75d ("KVM: guest_memfd: Remove bindings on memslot deletion when gmem is dying")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260728092027.225CF1F000E9@smtp.kernel.org
Suggested-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Shivank Garg <shivankg@amd.com>
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Link: https://patch.msgid.link/20260901-gmem-unbind-fix-v2-1-12febe1d2216@amd.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
[ sashal: Adapted unbind to struct kvm_gmem with explicit kvm_gmem_get_file()/fput() removal replacing upstream's automatic cleanup removal. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
virt/kvm/guest_memfd.c | 48 ++++++++++++++++--------------------------
1 file changed, 18 insertions(+), 30 deletions(-)
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 2ab7bb46a371e..5f9a25fa0a09b 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -635,53 +635,41 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
return r;
}
-static void __kvm_gmem_unbind(struct kvm_memory_slot *slot, struct kvm_gmem *gmem)
+void kvm_gmem_unbind(struct kvm_memory_slot *slot)
{
+ struct file *file = slot->gmem.file;
unsigned long start = slot->gmem.pgoff;
unsigned long end = start + slot->npages;
-
- xa_store_range(&gmem->bindings, start, end - 1, NULL, GFP_KERNEL);
-
- /*
- * synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn()
- * cannot see this memslot.
- */
- WRITE_ONCE(slot->gmem.file, NULL);
-}
-
-void kvm_gmem_unbind(struct kvm_memory_slot *slot)
-{
- struct file *file;
+ struct kvm_gmem *gmem;
/*
* Nothing to do if the underlying file was _already_ closed, as
* kvm_gmem_release() invalidates and nullifies all bindings.
*/
- if (!slot->gmem.file)
+ if (!file)
return;
- file = kvm_gmem_get_file(slot);
-
/*
* However, if the file is _being_ closed, then the bindings need to be
* removed as kvm_gmem_release() might not run until after the memslot
- * is freed. Note, modifying the bindings is safe even though the file
- * is dying as kvm_gmem_release() nullifies slot->gmem.file under
- * slots_lock, and only puts its reference to KVM after destroying all
- * bindings. I.e. reaching this point means kvm_gmem_release() hasn't
- * yet destroyed the bindings or freed the gmem_file, and can't do so
- * until the caller drops slots_lock.
+ * is freed. Modifying the bindings is safe even if the file is dying
+ * as kvm_gmem_release() nullifies slot->gmem.file under slots_lock,
+ * and only puts its reference to KVM after destroying all bindings.
+ * I.e. reaching this point means kvm_gmem_release() hasn't destroyed
+ * the bindings or freed the gmem_file and can't do so until the caller
+ * drops slots_lock, so there's no need to verify the file is live.
*/
- if (!file) {
- __kvm_gmem_unbind(slot, slot->gmem.file->private_data);
- return;
- }
+ gmem = file->private_data;
filemap_invalidate_lock(file->f_mapping);
- __kvm_gmem_unbind(slot, file->private_data);
- filemap_invalidate_unlock(file->f_mapping);
+ xa_store_range(&gmem->bindings, start, end - 1, NULL, GFP_KERNEL);
- fput(file);
+ /*
+ * synchronize_srcu(&kvm->srcu) ensured that kvm_gmem_get_pfn()
+ * cannot see this memslot.
+ */
+ WRITE_ONCE(slot->gmem.file, NULL);
+ filemap_invalidate_unlock(file->f_mapping);
}
/* Returns a locked folio on success. */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 054/686] KVM: TDX: Stuff exit_reason with UNDEFINED on wait_for_sept_zap return
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (52 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 053/686] KVM: guest_memfd: take the invalidate lock when unbinding a dying file Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 055/686] KVM: TDX: Set bits 31:16 to 0 and use UNDEFINED when synthesizing exit reason Greg Kroah-Hartman
` (631 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiaoyao Li, Sean Christopherson,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaoyao Li <xiaoyao.li@intel.com>
[ Upstream commit e5f1d62c59aea4f270773de1bf6e8867f5b1124c ]
Forcefully update the exit_reason to KVM's "standard" EXIT_REASON_UNDEFINED
if tdx_vcpu_run() bails without trying to run the vCPU because KVM needs to
wait for an in-progress S-EPT zap to complete. This avoids handling the
previous exit multiple times due to a stale exit_reason.
Fixes: 4b2abc49712b ("KVM: TDX: Kick off vCPUs when SEAMCALL is busy during TD page removal")
Cc: stable@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://patch.msgid.link/20260819094903.3060020-6-xiaoyao.li@intel.com
[sean: use EXIT_REASON_UNDEFINED, drop comment about bits 31:16]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/vmx/tdx.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index dcbfcd79791c8..02a15ad90c586 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -1041,8 +1041,16 @@ fastpath_t tdx_vcpu_run(struct kvm_vcpu *vcpu, u64 run_flags)
* allowing vCPU entry to avoid contention with tdh_vp_enter() and
* TDCALLs.
*/
- if (unlikely(READ_ONCE(to_kvm_tdx(vcpu->kvm)->wait_for_sept_zap)))
+ if (unlikely(READ_ONCE(to_kvm_tdx(vcpu->kvm)->wait_for_sept_zap))) {
+ /*
+ * The vCPU never entered the guest, but this looks like a
+ * handled exit to the caller. Synthesize an invalid exit
+ * reason so the previous exit's stale value isn't consumed
+ * a second time.
+ */
+ vt->exit_reason.full = EXIT_REASON_UNDEFINED;
return EXIT_FASTPATH_EXIT_HANDLED;
+ }
trace_kvm_entry(vcpu, run_flags & KVM_RUN_FORCE_IMMEDIATE_EXIT);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 055/686] KVM: TDX: Set bits 31:16 to 0 and use UNDEFINED when synthesizing exit reason
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (53 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 054/686] KVM: TDX: Stuff exit_reason with UNDEFINED on wait_for_sept_zap return Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 056/686] KVM: TDX: Dont assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() Greg Kroah-Hartman
` (630 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiaoyao Li, Rick Edgecombe,
Binbin Wu, Sean Christopherson, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaoyao Li <xiaoyao.li@intel.com>
[ Upstream commit b43c520b198ab70868307a489ef2117ed6d6c4cc ]
Set bits 31:16 to 0 instead of all-1s when synthesizing an exit reason,
e.g. if the TDX Module never attempted VM-Enter, or when stuffing the exit
reason due to an unexpected "real" EPT Misconfig. Opportunistically use
VMX's KVM-defined EXIT_REASON_UNDEFINED (0xdead) instead of -1u.
KVM is going to support Bus Lock VM exit for TDX, after which bit 26 of
the Exit Reason becomes meaningful and indicates that a bus lock happened.
The existing synthesized Exit Reason, -1u, will cause a false positive in
that case. Change the synthesized Exit Reason from -1u to U16_MAX, so that
bits 31:16 are set to 0. This also avoids the potential issues when other
bits in 31:16 become valid in the future.
As a bonus, the check for synthesized Exit Reason in tdx_failed_vmentry()
becomes unnecessary. Just drop it.
Cc: stable@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Reviewed-by: Binbin Wu <binbin.wu@linux.intel.com>
Link: https://patch.msgid.link/20260819094903.3060020-4-xiaoyao.li@intel.com
[sean: use EXIT_REASON_UNDEFINED instead of another magic value]
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/vmx/tdx.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 02a15ad90c586..411291603681f 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -904,8 +904,13 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
struct vcpu_tdx *tdx = to_tdx(vcpu);
u32 exit_reason;
+ /*
+ * Return the synthesized invalid Exit Reason, as the TDX module
+ * never attempted to run the vCPU, i.e. the Exit Reason is undefined,
+ * but this is NOT a failed VM-Enter.
+ */
if (!tdx_is_exit_reason_valid(tdx->vp_enter_ret))
- return -1u;
+ return EXIT_REASON_UNDEFINED;
exit_reason = tdx->vp_enter_ret;
@@ -920,7 +925,7 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
* Defer KVM_BUG_ON() until tdx_handle_exit() because this is in
* non-instrumentable code with interrupts disabled.
*/
- return -1u;
+ return EXIT_REASON_UNDEFINED;
default:
break;
}
@@ -951,8 +956,7 @@ static noinstr void tdx_vcpu_enter_exit(struct kvm_vcpu *vcpu)
static bool tdx_failed_vmentry(struct kvm_vcpu *vcpu)
{
- return vmx_get_exit_reason(vcpu).failed_vmentry &&
- vmx_get_exit_reason(vcpu).full != -1u;
+ return vmx_get_exit_reason(vcpu).failed_vmentry;
}
static fastpath_t tdx_exit_handlers_fastpath(struct kvm_vcpu *vcpu)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 056/686] KVM: TDX: Dont assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (54 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 055/686] KVM: TDX: Set bits 31:16 to 0 and use UNDEFINED when synthesizing exit reason Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 057/686] ksmbd: look up stream size by exact xattr name Greg Kroah-Hartman
` (629 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiaoyao Li, Sean Christopherson,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaoyao Li <xiaoyao.li@intel.com>
[ Upstream commit bc335ce04408750585b4b32f248c543c9493d545 ]
When handling the real Exit Reason, don't assume the upper 16 bits as
all-0 in tdx_to_vmx_exit_reason(), in preparation for enabling Bus Lock
VM exit.
When Bus Lock VM exit is enabled, the bit 26 of Exit Reason becomes
valid and it can be 1 with various exit reasons. Change the logic in
tdx_to_vmx_exit_reason() to check the 'basic' Exit Reason for correctness.
Also preserve bit[31:16] when changing the (basic) Exit Reason, to not
lose the information in bit[31:16].
Change the return type of tdx_to_vmx_exit_reason() to
"union vmx_exit_reason" for the convenience of manipulating the basic
field.
Fixes: c42856af8f70 ("KVM: TDX: Add a place holder for handler of TDX hypercalls (TDG.VP.VMCALL)")
Cc: stable@vger.kernel.org
Signed-off-by: Xiaoyao Li <xiaoyao.li@intel.com>
Link: https://patch.msgid.link/20260819094903.3060020-5-xiaoyao.li@intel.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kvm/vmx/tdx.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index 411291603681f..43d6b20dfbb16 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -899,10 +899,10 @@ static __always_inline bool tdx_is_exit_reason_valid(u64 vp_enter_ret)
}
}
-static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
+static __always_inline union vmx_exit_reason tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
{
struct vcpu_tdx *tdx = to_tdx(vcpu);
- u32 exit_reason;
+ union vmx_exit_reason exit_reason;
/*
* Return the synthesized invalid Exit Reason, as the TDX module
@@ -910,22 +910,26 @@ static __always_inline u32 tdx_to_vmx_exit_reason(struct kvm_vcpu *vcpu)
* but this is NOT a failed VM-Enter.
*/
if (!tdx_is_exit_reason_valid(tdx->vp_enter_ret))
- return EXIT_REASON_UNDEFINED;
+ return (union vmx_exit_reason) {
+ .basic = EXIT_REASON_UNDEFINED,
+ };
- exit_reason = tdx->vp_enter_ret;
+ exit_reason.full = (u32)tdx->vp_enter_ret;
- switch (exit_reason) {
+ switch (exit_reason.basic) {
case EXIT_REASON_TDCALL:
if (tdvmcall_exit_type(vcpu))
- return EXIT_REASON_VMCALL;
-
- return tdcall_to_vmx_exit_reason(vcpu);
+ exit_reason.basic = EXIT_REASON_VMCALL;
+ else
+ exit_reason.basic = tdcall_to_vmx_exit_reason(vcpu);
+ break;
case EXIT_REASON_EPT_MISCONFIG:
/*
* Defer KVM_BUG_ON() until tdx_handle_exit() because this is in
* non-instrumentable code with interrupts disabled.
*/
- return EXIT_REASON_UNDEFINED;
+ exit_reason.basic = EXIT_REASON_UNDEFINED;
+ break;
default:
break;
}
@@ -942,7 +946,7 @@ static noinstr void tdx_vcpu_enter_exit(struct kvm_vcpu *vcpu)
tdx->vp_enter_ret = tdh_vp_enter(&tdx->vp, &tdx->vp_enter_args);
- vt->exit_reason.full = tdx_to_vmx_exit_reason(vcpu);
+ vt->exit_reason = tdx_to_vmx_exit_reason(vcpu);
vt->exit_qualification = tdx->vp_enter_args.rcx;
tdx->ext_exit_qualification = tdx->vp_enter_args.rdx;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 057/686] ksmbd: look up stream size by exact xattr name
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (55 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 056/686] KVM: TDX: Dont assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 058/686] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload Greg Kroah-Hartman
` (628 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gael Blivet, Namjae Jeon,
Sasha Levin
6.18-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 c784aa6d9b6ad..1cbc425d7273e 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -5275,17 +5275,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 c470d419e7ce8..a3db77b3c2728 100644
--- a/fs/smb/server/vfs.c
+++ b/fs/smb/server/vfs.c
@@ -950,8 +950,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 e9a5798d7baed..ca5048ebb1308 100644
--- a/fs/smb/server/vfs.h
+++ b/fs/smb/server/vfs.h
@@ -106,6 +106,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] 687+ messages in thread
* [PATCH 6.18 058/686] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (56 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 057/686] ksmbd: look up stream size by exact xattr name Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 059/686] mlxsw: Initialize register query payloads Greg Kroah-Hartman
` (627 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Janne Grunau, Neal Gompa,
Arend van Spriel, Johannes Berg, Sasha Levin
6.18-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 1fc9ecd86d5d9..1ca879ffb6021 100644
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6481,6 +6481,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");
@@ -6505,7 +6506,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] 687+ messages in thread
* [PATCH 6.18 059/686] mlxsw: Initialize register query payloads
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (57 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 058/686] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 060/686] io_uring/cancel: drop sqd->lock while SQPOLL waits Greg Kroah-Hartman
` (626 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Til Kaiser, Ido Schimmel,
Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Til Kaiser <mail@tk154.de>
[ Upstream commit 15b7a86a8888dc6a8fd19e181757e32389de9064 ]
MFGD register queries can exhaust EMAD retries and leave Mellanox
Spectrum switches stuck during boot or shutdown when running OpenWrt
built with GCC 15.
An example failure is shown below with the second line wrapped:
EMAD retries (5/5) (tid=9b544fc100001f35)
EMAD reg access failed (tid=9b544fc100001f35,reg_id=90f0(mfgd),
type=query,status=0(operation performed))
On an SN2100, the failure occurs during driver teardown on reboot.
On an SN3420, it occurs while probing mlxsw_spectrum during boot.
The register query API transmits the supplied payload to the device
before replacing it with the response. Both MFGD callers pass an
uninitialized stack buffer, so the request contains arbitrary register
field values and reserved bits. This makes the request depend on stack
contents and compiler code generation.
Initialize both MFGD query buffers in the firmware fatal event
configuration and reporter test paths. The initialization has been
confirmed to eliminate the boot and shutdown hangs on both switches.
The subsequent read-modify-write still preserves the other fields
returned by the device.
Also initialize the FORE fan fault query and the MOGCR mirroring policer
base query, which pass entirely uninitialized payloads. Restore the MTMP
query initialization in the temperature history reset path, where only
the slot and sensor index fields are set before querying the register.
This follows commit 5b0907407e7f ("mlxsw: core: Zero payload buffers for
couple of registers"), which initialized other query payloads after a
firmware field length bug caused firmware to consume uninitialized data.
Tested with firmware 2020.1148 and with 2016.3900 from linux-firmware.
Fixes: 7d83ee111008 ("mlxsw: core: Introduce fw_fatal health reporter")
Fixes: 2c6a33cd334b ("mlxsw: core: Extend hwmon interface with fan fault attribute")
Fixes: 4039504e6a0c ("mlxsw: spectrum_span: Allow setting policer on a SPAN agent")
Fixes: b890ad418e1f ("mlxsw: core_hwmon: Extend internal structures to support multi hwmon objects")
Cc: stable@vger.kernel.org
Signed-off-by: Til Kaiser <mail@tk154.de>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261014173117.26305-1-mail@tk154.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
(cherry picked from commit 15b7a86a8888dc6a8fd19e181757e32389de9064)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlxsw/core.c | 4 ++--
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c | 4 ++--
drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c | 2 +-
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 83c7cf3bbea3a..bd15c14bf5c86 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -2001,7 +2001,7 @@ mlxsw_core_health_fw_fatal_test(struct devlink_health_reporter *reporter,
struct netlink_ext_ack *extack)
{
struct mlxsw_core *mlxsw_core = devlink_health_reporter_priv(reporter);
- char mfgd_pl[MLXSW_REG_MFGD_LEN];
+ char mfgd_pl[MLXSW_REG_MFGD_LEN] = {0};
int err;
/* Read the register first to make sure no other bits are changed. */
@@ -2022,7 +2022,7 @@ mlxsw_core_health_fw_fatal_ops = {
static int mlxsw_core_health_fw_fatal_config(struct mlxsw_core *mlxsw_core,
bool enable)
{
- char mfgd_pl[MLXSW_REG_MFGD_LEN];
+ char mfgd_pl[MLXSW_REG_MFGD_LEN] = {0};
int err;
/* Read the register first to make sure no other bits are changed. */
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
index 9c12e1feb6437..e39a8b0a57095 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
@@ -120,7 +120,7 @@ static ssize_t mlxsw_hwmon_temp_rst_store(struct device *dev,
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
- char mtmp_pl[MLXSW_REG_MTMP_LEN];
+ char mtmp_pl[MLXSW_REG_MTMP_LEN] = {0};
unsigned long val;
int index;
int err;
@@ -177,7 +177,7 @@ static ssize_t mlxsw_hwmon_fan_fault_show(struct device *dev,
container_of(attr, struct mlxsw_hwmon_attr, dev_attr);
struct mlxsw_hwmon_dev *mlxsw_hwmon_dev = mlxsw_hwmon_attr->mlxsw_hwmon_dev;
struct mlxsw_hwmon *mlxsw_hwmon = mlxsw_hwmon_dev->hwmon;
- char fore_pl[MLXSW_REG_FORE_LEN];
+ char fore_pl[MLXSW_REG_FORE_LEN] = {0};
bool fault;
int err;
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
index 32d2e61f2b823..91fb77c8e20d6 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_span.c
@@ -1720,7 +1720,7 @@ static int mlxsw_sp2_span_init(struct mlxsw_sp *mlxsw_sp)
static int mlxsw_sp2_span_policer_id_base_set(struct mlxsw_sp *mlxsw_sp,
u16 policer_id_base)
{
- char mogcr_pl[MLXSW_REG_MOGCR_LEN];
+ char mogcr_pl[MLXSW_REG_MOGCR_LEN] = {0};
int err;
err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(mogcr), mogcr_pl);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 060/686] io_uring/cancel: drop sqd->lock while SQPOLL waits
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (58 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 059/686] mlxsw: Initialize register query payloads Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 061/686] io_uring/sqpoll: dont attach to a thread that is canceling Greg Kroah-Hartman
` (625 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chris Mason, Jens Axboe, Sasha Levin
6.18-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 50ec818aa19f6..44d8b7b25267e 100644
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -641,7 +641,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;
}
@@ -659,8 +668,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] 687+ messages in thread
* [PATCH 6.18 061/686] io_uring/sqpoll: dont attach to a thread that is canceling
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (59 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 060/686] io_uring/cancel: drop sqd->lock while SQPOLL waits Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 062/686] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit Greg Kroah-Hartman
` (624 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Jens Axboe,
Sasha Levin
6.18-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 406029c14fbce..1c7f84192c0af 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -438,6 +438,12 @@ static int io_sq_thread(void *data)
if (retry_list)
io_sq_tw(&retry_list, 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);
@@ -506,7 +512,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] 687+ messages in thread
* [PATCH 6.18 062/686] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (60 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 061/686] io_uring/sqpoll: dont attach to a thread that is canceling Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 063/686] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread Greg Kroah-Hartman
` (623 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+675af112519ca34f5502,
Shuai Liu, Jens Axboe, Sasha Levin
6.18-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 1c7f84192c0af..1d31a4b1a9aaa 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -28,6 +28,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)
@@ -441,9 +442,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);
@@ -514,7 +516,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] 687+ messages in thread
* [PATCH 6.18 063/686] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (61 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 062/686] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 064/686] io_uring/cancel: count all requests that a CANCEL_ALL cancels Greg Kroah-Hartman
` (622 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shakeel Butt, Jens Axboe,
Sasha Levin
6.18-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 1d31a4b1a9aaa..66405f4630e71 100644
--- a/io_uring/sqpoll.c
+++ b/io_uring/sqpoll.c
@@ -358,6 +358,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 = __io_sq_thread(ctx, sqd, cap_entries, &ist);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 064/686] io_uring/cancel: count all requests that a CANCEL_ALL cancels
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (62 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 063/686] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 065/686] io_uring/poll: cancel all matching requests in one pass Greg Kroah-Hartman
` (621 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shang En Sim, Jens Axboe,
Sasha Levin
6.18-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 44d8b7b25267e..1db26c66e45c6 100644
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -192,7 +192,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] 687+ messages in thread
* [PATCH 6.18 065/686] io_uring/poll: cancel all matching requests in one pass
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (63 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 064/686] io_uring/cancel: count all requests that a CANCEL_ALL cancels Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 066/686] io_uring/poll: dont poll a writer for a read side hangup Greg Kroah-Hartman
` (620 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shang En Sim, Jens Axboe,
Sasha Levin
6.18-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 1db26c66e45c6..471d6f2e5f18f 100644
--- a/io_uring/cancel.c
+++ b/io_uring/cancel.c
@@ -192,7 +192,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 48381f0cbe327..6af64c7618e5a 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -824,12 +824,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] 687+ messages in thread
* [PATCH 6.18 066/686] io_uring/poll: dont poll a writer for a read side hangup
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (64 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 065/686] io_uring/poll: cancel all matching requests in one pass Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 067/686] io_uring/poll: dont poll a writer for urgent data Greg Kroah-Hartman
` (619 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lukáš Lalinský,
Jens Axboe, Sasha Levin
6.18-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 6af64c7618e5a..3239bc3039fb3 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);
}
@@ -1003,7 +1015,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] 687+ messages in thread
* [PATCH 6.18 067/686] io_uring/poll: dont poll a writer for urgent data
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (65 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 066/686] io_uring/poll: dont poll a writer for a read side hangup Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 068/686] io_uring/rsrc: hold uring_lock across index-alloc put_user Greg Kroah-Hartman
` (618 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lukáš Lalinský,
Jens Axboe, Sasha Levin
6.18-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 3239bc3039fb3..2594c1f04e705 100644
--- a/io_uring/poll.c
+++ b/io_uring/poll.c
@@ -736,7 +736,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;
@@ -744,7 +744,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] 687+ messages in thread
* [PATCH 6.18 068/686] io_uring/rsrc: hold uring_lock across index-alloc put_user
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (66 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 067/686] io_uring/poll: dont poll a writer for urgent data Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 069/686] fsverity: Explicitly require FMODE_READ to retrieve hashes Greg Kroah-Hartman
` (617 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yuansheng Yang, Jens Axboe,
Sasha Levin
6.18-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>
[axboe: 6.18 uses copy_to_user() for the slot rather than put_user()]
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 41e5755bd9aac..7170b3f001d41 100644
--- a/io_uring/rsrc.c
+++ b/io_uring/rsrc.c
@@ -429,11 +429,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++) {
@@ -447,15 +448,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 copy_to_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 (copy_to_user(&fds[done], &ret, sizeof(ret))) {
- __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] 687+ messages in thread
* [PATCH 6.18 069/686] fsverity: Explicitly require FMODE_READ to retrieve hashes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (67 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 068/686] io_uring/rsrc: hold uring_lock across index-alloc put_user Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 070/686] xor: add missing vzeroupper to AVX code Greg Kroah-Hartman
` (616 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrey Albershteyn, Eric Biggers,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit 1acb4fd2d011c4bd6cc961095ae17361c71ff61a upstream.
The comment in fsverity_ioctl_read_metadata(), which justifies not
checking for FMODE_READ, doesn't consider that the nonstandard access
mode 3 (ioctl-only) exists.
Opening an ioctl-only fd generally requires read (and write) permission.
However, there are gaps with certain LSMs: an ioctl-only fd requests
read (and write) permission via security_inode_permission, but not
security_file_open. With certain LSMs relying on the latter, such as
Landlock and AppArmor, an ioctl-only fd can be opened without the LSM
granting read (and write) permission.
Since FS_IOC_READ_VERITY_METADATA returns hashes of file contents
blocks, it should require read permission. This also applies to
FS_IOC_MEASURE_VERITY, which returns a hash for the whole file.
Meanwhile, ioctl-only fds are a rarely-used feature, not known to be
used with either ioctl.
Therefore, just disallow these ioctls on ioctl-only file descriptors,
similar to what was already done with FS_IOC_ENABLE_VERITY.
More specifically, explicitly check for FMODE_READ. This also covers
write-only fds to non-verity files which otherwise would have failed
with ENODATA. This change in error code for write-only fds should be
fine too, as these ioctls cannot be usefully used with write-only fds
anyway, but it's worth noting as another technicality.
Fixes: 4dd893d832cf ("fs-verity: implement FS_IOC_MEASURE_VERITY ioctl")
Fixes: e17fe6579de0 ("fs-verity: add FS_IOC_READ_VERITY_METADATA ioctl")
Cc: stable@vger.kernel.org
Reviewed-by: Andrey Albershteyn <aalbersh@kernel.org>
Link: https://patch.msgid.link/20261022211522.1489943-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/filesystems/fsverity.rst | 3 +++
fs/verity/measure.c | 10 ++++++++++
fs/verity/read_metadata.c | 14 ++++++++++----
3 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/Documentation/filesystems/fsverity.rst b/Documentation/filesystems/fsverity.rst
index 412cf11e32985..fd17bbf5795c9 100644
--- a/Documentation/filesystems/fsverity.rst
+++ b/Documentation/filesystems/fsverity.rst
@@ -170,6 +170,7 @@ fatal signal), no changes are made to the file.
FS_IOC_ENABLE_VERITY can fail with the following errors:
- ``EACCES``: the process does not have write access to the file
+- ``EBADF``: the file descriptor is not open for reading
- ``EBADMSG``: the builtin signature is malformed
- ``EBUSY``: this ioctl is already running on the file
- ``EEXIST``: the file already has verity enabled
@@ -232,6 +233,7 @@ regardless of the size of the file.
FS_IOC_MEASURE_VERITY can fail with the following errors:
+- ``EBADF``: the file descriptor is not open for reading
- ``EFAULT``: the caller provided inaccessible memory
- ``ENODATA``: the file is not a verity file
- ``ENOTTY``: this type of filesystem does not implement fs-verity
@@ -310,6 +312,7 @@ blocks from disk without actually verifying the path to the root node.
FS_IOC_READ_VERITY_METADATA can fail with the following errors:
+- ``EBADF``: the file descriptor is not open for reading
- ``EFAULT``: the caller provided inaccessible memory
- ``EINTR``: the ioctl was interrupted before any data was read
- ``EINVAL``: reserved fields were set, or ``offset + length``
diff --git a/fs/verity/measure.c b/fs/verity/measure.c
index 433d963edf3bb..5ec36d845008b 100644
--- a/fs/verity/measure.c
+++ b/fs/verity/measure.c
@@ -31,6 +31,16 @@ int fsverity_ioctl_measure(struct file *filp, void __user *_uarg)
const struct fsverity_hash_alg *hash_alg;
struct fsverity_digest arg;
+ /*
+ * This ioctl returns a hash of the file contents, so it should require
+ * read permission. Disallow it on ioctl-only (i.e., nonstandard access
+ * mode 3) fds, which can in some cases be acquired without passing all
+ * LSM read-permission checks. Also disallow write-only fds, which can
+ * refer only to non-verity files which would fail with ENODATA anyway.
+ */
+ if (!(filp->f_mode & FMODE_READ))
+ return -EBADF;
+
vi = fsverity_get_info(inode);
if (!vi)
return -ENODATA; /* not a verity file */
diff --git a/fs/verity/read_metadata.c b/fs/verity/read_metadata.c
index cba5d6af4e04f..cfe9227a41c45 100644
--- a/fs/verity/read_metadata.c
+++ b/fs/verity/read_metadata.c
@@ -157,13 +157,19 @@ int fsverity_ioctl_read_metadata(struct file *filp, const void __user *uarg)
int length;
void __user *buf;
+ /*
+ * This ioctl returns file contents block hashes, so it should require
+ * read permission. Disallow it on ioctl-only (i.e., nonstandard access
+ * mode 3) fds, which can in some cases be acquired without passing all
+ * LSM read-permission checks. Also disallow write-only fds, which can
+ * refer only to non-verity files which would fail with ENODATA anyway.
+ */
+ if (!(filp->f_mode & FMODE_READ))
+ return -EBADF;
+
vi = fsverity_get_info(inode);
if (!vi)
return -ENODATA; /* not a verity file */
- /*
- * Note that we don't have to explicitly check that the file is open for
- * reading, since verity files can only be opened for reading.
- */
if (copy_from_user(&arg, uarg, sizeof(arg)))
return -EFAULT;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 070/686] xor: add missing vzeroupper to AVX code
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (68 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 069/686] fsverity: Explicitly require FMODE_READ to retrieve hashes Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 071/686] raid6: add missing vzeroupper to AVX-512 code Greg Kroah-Hartman
` (615 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Biggers, Andrew Morton,
Christoph Hellwig, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit 7b8fc26c40d6cf4c6751a045c9e42bbb7e78d81b upstream.
Since the AVX optimized XOR code uses YMM registers, execute vzeroupper
before returning from it. This is needed to avoid degrading the
performance of any later SSE code that may happen to be executed.
(Backported to the old organization of the XOR code.)
Link: https://lore.kernel.org/20260831212248.213805-1-ebiggers@kernel.org
Fixes: ea4d26ae24e5 ("raid5: add AVX optimized RAID5 checksumming")
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/include/asm/xor_avx.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/x86/include/asm/xor_avx.h b/arch/x86/include/asm/xor_avx.h
index 7f81dd5897f41..c6450acd055d1 100644
--- a/arch/x86/include/asm/xor_avx.h
+++ b/arch/x86/include/asm/xor_avx.h
@@ -50,6 +50,7 @@ do { \
p1 = (unsigned long *)((uintptr_t)p1 + 512);
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -81,6 +82,7 @@ do { \
p2 = (unsigned long *)((uintptr_t)p2 + 512);
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -116,6 +118,7 @@ do { \
p3 = (unsigned long *)((uintptr_t)p3 + 512);
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -155,6 +158,7 @@ do { \
p4 = (unsigned long *)((uintptr_t)p4 + 512);
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 071/686] raid6: add missing vzeroupper to AVX-512 code
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (69 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 070/686] xor: add missing vzeroupper to AVX code Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 072/686] mm/damon/core: skip applying scheme if region split for quota fails Greg Kroah-Hartman
` (614 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Biggers, Andrew Morton,
Christoph Hellwig, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit b82cf9e49c1be7cf1fd8e1bd806b0cdd25ab8127 upstream.
Since the AVX-512 optimized RAID6 code uses ZMM registers, execute
vzeroupper before returning from it. This is needed to avoid degrading
the performance of any later SSE code that may happen to be executed.
Link: https://lore.kernel.org/20260831212316.213896-1-ebiggers@kernel.org
Fixes: e0a491c12968 ("lib/raid6: Add AVX512 optimized gen_syndrome functions")
Fixes: 13c520b2993c ("lib/raid6: Add AVX512 optimized recovery functions")
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/raid6/avx512.c | 6 ++++++
lib/raid6/recov_avx512.c | 2 ++
2 files changed, 8 insertions(+)
diff --git a/lib/raid6/avx512.c b/lib/raid6/avx512.c
index 009bd0adeebf0..d989ca64847a5 100644
--- a/lib/raid6/avx512.c
+++ b/lib/raid6/avx512.c
@@ -93,6 +93,7 @@ static void raid6_avx5121_gen_syndrome(int disks, size_t bytes, void **ptrs)
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -152,6 +153,7 @@ static void raid6_avx5121_xor_syndrome(int disks, int start, int stop,
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -225,6 +227,7 @@ static void raid6_avx5122_gen_syndrome(int disks, size_t bytes, void **ptrs)
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -309,6 +312,7 @@ static void raid6_avx5122_xor_syndrome(int disks, int start, int stop,
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -415,6 +419,7 @@ static void raid6_avx5124_gen_syndrome(int disks, size_t bytes, void **ptrs)
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -548,6 +553,7 @@ static void raid6_avx5124_xor_syndrome(int disks, int start, int stop,
"m" (q[d+128]), "m" (q[d+192]));
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
const struct raid6_calls raid6_avx512x4 = {
diff --git a/lib/raid6/recov_avx512.c b/lib/raid6/recov_avx512.c
index 7986120ca4442..32a9720be269d 100644
--- a/lib/raid6/recov_avx512.c
+++ b/lib/raid6/recov_avx512.c
@@ -219,6 +219,7 @@ static void raid6_2data_recov_avx512(int disks, size_t bytes, int faila,
#endif
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -361,6 +362,7 @@ static void raid6_datap_recov_avx512(int disks, size_t bytes, int faila,
#endif
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 072/686] mm/damon/core: skip applying scheme if region split for quota fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (70 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 071/686] raid6: add missing vzeroupper to AVX-512 code Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 073/686] mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total Greg Kroah-Hartman
` (613 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Usama Arif,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit 90c2fa6adfed7abe0935506a43cdff3a05c1fff0 ]
Patch series "mm/damon: fix DAMOS bugs in core, paddr and vaddr".
Fix misc bugs of DAMOS. Patch 1 makes DAMOS less stress memory allocator
under extreme situation. Patches 2 and 3 fix wrong folios walking in
DAMON_PADDR. Patches 4 and 5 fix wrong folios walking in DAMON_VADDR.
Patches 6-8 handle extreme and unlikely memory situations that can cause
divide by zero and underflow.
All bugs are discovered by Sashiko.
This patch (of 8):
damos_apply_scheme() splits a region and apply the action to the subregion
if it is needed for not violating the quota. The split operation
(damon_split_region_at()) could fail for allocation failure. In the case,
the quota could be violated. From the user's perspective, DAMOS becomes
more aggressive than expected under the extreme situation. Handle the
failure.
The user impact is not critical. The failure of damon_split_region_at()
is unlikely since it is arguably too small to fail. Also DAMOS being
aggressive is limited to the single region. Users can set min_nr_regions
to set the maximum size of each region. If it is reasonably set, the
transient overhead shouldn't be critical.
The issue was discovered [1] by Sashiko.
6.18.y porting notes. Modify damon_split_region_at() to return
failures. It is a part of commit c60874860762 ("mm/damon/core: handle
region split failure in apply_min_nr_regions()"). Without it, build
fails.
Link: https://lore.kernel.org/20260901131850.98037-1-sj@kernel.org
Link: https://lore.kernel.org/20260901131850.98037-2-sj@kernel.org
Link: https://lore.kernel.org/20260718171523.87547-1-sj@kernel.org [1]
Fixes: 2b8a248d5873 ("mm/damon/schemes: implement size quota for schemes application speed control")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Usama Arif <usamaarif642@gmail.com>
Cc: <stable@vger.kernel.org> # 5.16.x
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/core.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 56f2343ffefac..09365f4275032 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -1700,7 +1700,7 @@ static void kdamond_tune_intervals(struct damon_ctx *c)
damon_set_attrs(c, &new_attrs);
}
-static void damon_split_region_at(struct damon_target *t,
+static int damon_split_region_at(struct damon_target *t,
struct damon_region *r, unsigned long sz_r);
static bool __damos_valid_target(struct damon_region *r, struct damos *s)
@@ -2000,7 +2000,8 @@ static void damos_apply_scheme(struct damon_ctx *c, struct damon_target *t,
c->min_sz_region);
if (!sz)
goto update_stat;
- damon_split_region_at(t, r, sz);
+ if (damon_split_region_at(t, r, sz))
+ goto update_stat;
}
if (damos_filter_out(c, t, r, s))
return;
@@ -2462,15 +2463,17 @@ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int threshold,
*
* r the region to be split
* sz_r size of the first sub-region that will be made
+ *
+ * Return: 0 on success, negative error code otherwise.
*/
-static void damon_split_region_at(struct damon_target *t,
+static int damon_split_region_at(struct damon_target *t,
struct damon_region *r, unsigned long sz_r)
{
struct damon_region *new;
new = damon_new_region(r->ar.start + sz_r, r->ar.end);
if (!new)
- return;
+ return -ENOMEM;
r->ar.end = new->ar.start;
@@ -2480,6 +2483,7 @@ static void damon_split_region_at(struct damon_target *t,
new->nr_accesses = r->nr_accesses;
damon_insert_region(new, r, damon_next_region(r), t);
+ return 0;
}
/* Split every region in the given target into 'nr_subs' regions */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 073/686] mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (71 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 072/686] mm/damon/core: skip applying scheme if region split for quota fails Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 074/686] mm/damon/core: remove unreachable damos charge_{target,addr}_from Greg Kroah-Hartman
` (612 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Lian Wang,
Kunwu Chan, Brendan Higgins, David Gow, Quanmin Yan, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit 29c6084658af41b5b1fefd873d26d441830ced34 ]
When DAMOS_QUOTA_SOME_MEM_PSI_US metric damos quota goal is set, the PSI
delta for the feedback loop is calculated using
damos_quota_goal->last_psi_total. However, it is initialized only after
the first feedback loop. The first iteration of the loop uses the
uninitialized value. As a result, the feedback loop can change the
effective quota in an unexpected way at the first iteration.
The user impact of the issue is not big, because the issue impacts only
the first iteration of the feedback loop. The feedback loop also has an
internal cap of the quota adjustment. The wrong adjustment will soon be
corrected over a few iterations. For this reason, doing no initialization
at commit time was intentional. It is also explicitly commented. That
said, nobody likes behaviors that are unexpected or difficult to be
expected.
Check last_psi_total initialization and skip the tuning round when it is
not initialized. For this, initialize last_psi_total with U64_MAX in the
goal creation and the goal commit time. U64_MAX means the field is not
initialized. The tuning round shows the value and adjusts it to guarantee
the current quota is maintained for the round, and last_psi_total is
correctly initialized on the next round.
Before this change, committing a new PSI goal on an existing PSI goal with
goal-only DAMON sysfs command (commit_schemes_quota_goals) just worked.
After this change, the tuning round right after the commit will be
unnecessarily skipped, because last_psi_total is unconditionally marked as
not initialized in the damos_commit_quota_goal_union(). This is an
intended tradeoff for simplicity. Skipping just one round of tuning is no
problem. Meanwhile it makes both the code and the behavior simple to
understand.
Also update the quota goal commit unit test for changed last_psi_total
setup behavior.
The issue was discovered [1] by Sashiko.
Link: https://lore.kernel.org/20260902002725.108635-3-sj@kernel.org
Link: https://lore.kernel.org/20260718005316.89585-1-sj@kernel.org [1]
Fixes: 2dbb60f789cb ("mm/damon/core: implement PSI metric DAMOS quota goal")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Lian Wang <lianux.mm@gmail.com>
Tested-by: Lian Wang <lianux.mm@gmail.com>
Reviewed-by: Kunwu Chan <kunwu.chan@gmail.com>
Cc: Brendan Higgins <brendan.higgins@linux.dev>
Cc: David Gow <davidgow@davidgow.net>
Cc: Quanmin Yan <yanquanmin1@huawei.com>
Cc: <stable@vger.kernel.org> # 6.9.x
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/core.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 09365f4275032..6f97b28eda634 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -348,6 +348,8 @@ struct damos_quota_goal *damos_new_quota_goal(
return NULL;
goal->metric = metric;
goal->target_value = target_value;
+ if (metric == DAMOS_QUOTA_SOME_MEM_PSI_US)
+ goal->last_psi_total = U64_MAX;
INIT_LIST_HEAD(&goal->list);
return goal;
}
@@ -798,6 +800,9 @@ static void damos_commit_quota_goal_union(
struct damos_quota_goal *dst, struct damos_quota_goal *src)
{
switch (dst->metric) {
+ case DAMOS_QUOTA_SOME_MEM_PSI_US:
+ dst->last_psi_total = U64_MAX;
+ break;
case DAMOS_QUOTA_NODE_MEM_USED_BP:
case DAMOS_QUOTA_NODE_MEM_FREE_BP:
dst->nid = src->nid;
@@ -816,7 +821,6 @@ static int damos_commit_quota_goal(
dst->target_value = src->target_value;
if (dst->metric == DAMOS_QUOTA_USER_INPUT)
dst->current_value = src->current_value;
- /* keep last_psi_total as is, since it will be updated in next cycle */
damos_commit_quota_goal_union(dst, src);
return 0;
}
@@ -2179,7 +2183,12 @@ static void damos_set_quota_goal_current_value(struct damos_quota_goal *goal)
break;
case DAMOS_QUOTA_SOME_MEM_PSI_US:
now_psi_total = damos_get_some_mem_psi_total();
- goal->current_value = now_psi_total - goal->last_psi_total;
+ /* uninitialized last_psi_total; make no effect this round */
+ if (goal->last_psi_total == U64_MAX)
+ goal->current_value = goal->target_value;
+ else
+ goal->current_value = now_psi_total -
+ goal->last_psi_total;
goal->last_psi_total = now_psi_total;
break;
case DAMOS_QUOTA_NODE_MEM_USED_BP:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 074/686] mm/damon/core: remove unreachable damos charge_{target,addr}_from
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (72 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 073/686] mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 075/686] mm/damon/core: filter out damos address filter-split failed region Greg Kroah-Hartman
` (611 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Sasha Levin
6.18-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 6f97b28eda634..33f47dcecc74b 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -2269,6 +2269,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;
@@ -2305,6 +2325,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] 687+ messages in thread
* [PATCH 6.18 075/686] mm/damon/core: filter out damos address filter-split failed region
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (73 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 074/686] mm/damon/core: remove unreachable damos charge_{target,addr}_from Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 076/686] rust: bug: pass TAINT_WARN to warn_slowpath_fmt() on UML Greg Kroah-Hartman
` (610 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: SJ Park <sj@kernel.org>
[ Upstream commit bbeec2d8324d7aac438bb12dd2d22b184e0a8d43 ]
When an address type DAMOS filter is configured, DAMOS tries to split the
region for the filter range, and apply DAMOS action to the filter-in
region. The split operation (damon_split_region_at()) could fail from
allocation failure under extreme memory pressure. In the case, DAMOS
action could be applied more or less than expected, ignoring the address
filter.
The issue only rarely happens under extreme memory pressure. No crash or
leak happens. Occasionally not applying the action to a few regions
shouldn't be a real problem. But applying the action to a region that the
user has excluded via address filter could be a surprise depending on the
use case. It is only theoretical. No such real case is found yet.
Filter out the entire region if the split is failed. Update
damos_filter_match() signature to receive the error from split. Also
update kunit tests for the updated signature.
The issue was discovered [1] by sashiko.
Link: https://lore.kernel.org/20261020004119.106690-1-sj@kernel.org
Link: https://lore.kernel.org/20260801203121.117449-1-sj@kernel.org [1]
Fixes: ab9bda001b68 ("mm/damon/core: introduce address range type damos filter")
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: <stable@vger.kernel.org> # 6.6.x
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/damon/core.c | 16 ++++++++++++----
mm/damon/tests/core-kunit.h | 16 +++++++++++-----
2 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 33f47dcecc74b..54a29d21d0dd1 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -1812,13 +1812,14 @@ static void damos_update_stat(struct damos *s,
static bool damos_filter_match(struct damon_ctx *ctx, struct damon_target *t,
struct damon_region *r, struct damos_filter *filter,
- unsigned long min_sz_region)
+ unsigned long min_sz_region, int *err)
{
bool matched = false;
struct damon_target *ti;
int target_idx = 0;
unsigned long start, end;
+ *err = 0;
switch (filter->type) {
case DAMOS_FILTER_TYPE_TARGET:
damon_for_each_target(ti, ctx) {
@@ -1844,12 +1845,13 @@ static bool damos_filter_match(struct damon_ctx *ctx, struct damon_target *t,
}
/* start before the range and overlap */
if (r->ar.start < start) {
- damon_split_region_at(t, r, start - r->ar.start);
+ *err = damon_split_region_at(t, r,
+ start - r->ar.start);
matched = false;
break;
}
/* start inside the range */
- damon_split_region_at(t, r, end - r->ar.start);
+ *err = damon_split_region_at(t, r, end - r->ar.start);
matched = true;
break;
default:
@@ -1863,10 +1865,16 @@ static bool damos_filter_out(struct damon_ctx *ctx, struct damon_target *t,
struct damon_region *r, struct damos *s)
{
struct damos_filter *filter;
+ bool matching;
+ int err;
s->core_filters_allowed = false;
damos_for_each_filter(filter, s) {
- if (damos_filter_match(ctx, t, r, filter, ctx->min_sz_region)) {
+ matching = damos_filter_match(ctx, t, r, filter,
+ ctx->min_sz_region, &err);
+ if (err)
+ return true;
+ if (matching) {
if (filter->allow)
s->core_filters_allowed = true;
return !filter->allow;
diff --git a/mm/damon/tests/core-kunit.h b/mm/damon/tests/core-kunit.h
index 0ce6481319432..814197da4f507 100644
--- a/mm/damon/tests/core-kunit.h
+++ b/mm/damon/tests/core-kunit.h
@@ -548,6 +548,7 @@ static void damos_test_filter_out(struct kunit *test)
struct damon_target *t;
struct damon_region *r, *r2;
struct damos_filter *f;
+ int err;
f = damos_new_filter(DAMOS_FILTER_TYPE_ADDR, true, false);
if (!f)
@@ -570,28 +571,32 @@ static void damos_test_filter_out(struct kunit *test)
/* region in the range */
KUNIT_EXPECT_TRUE(test,
- damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION));
+ damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION,
+ &err));
KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
/* region before the range */
r->ar.start = DAMON_MIN_REGION * 1;
r->ar.end = DAMON_MIN_REGION * 2;
KUNIT_EXPECT_FALSE(test,
- damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION));
+ damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION,
+ &err));
KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
/* region after the range */
r->ar.start = DAMON_MIN_REGION * 6;
r->ar.end = DAMON_MIN_REGION * 8;
KUNIT_EXPECT_FALSE(test,
- damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION));
+ damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION,
+ &err));
KUNIT_EXPECT_EQ(test, damon_nr_regions(t), 1);
/* region started before the range */
r->ar.start = DAMON_MIN_REGION * 1;
r->ar.end = DAMON_MIN_REGION * 4;
KUNIT_EXPECT_FALSE(test,
- damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION));
+ damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION,
+ &err));
/* filter should have split the region */
KUNIT_EXPECT_EQ(test, r->ar.start, DAMON_MIN_REGION * 1);
KUNIT_EXPECT_EQ(test, r->ar.end, DAMON_MIN_REGION * 2);
@@ -607,7 +612,8 @@ static void damos_test_filter_out(struct kunit *test)
r->ar.start = DAMON_MIN_REGION * 2;
r->ar.end = DAMON_MIN_REGION * 8;
KUNIT_EXPECT_TRUE(test,
- damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION));
+ damos_filter_match(NULL, t, r, f, DAMON_MIN_REGION,
+ &err));
/* filter should have split the region */
KUNIT_EXPECT_EQ(test, r->ar.start, DAMON_MIN_REGION * 2);
KUNIT_EXPECT_EQ(test, r->ar.end, DAMON_MIN_REGION * 6);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 076/686] rust: bug: pass TAINT_WARN to warn_slowpath_fmt() on UML
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (74 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 075/686] mm/damon/core: filter out damos address filter-split failed region Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 077/686] rust: bug: update the SAFETY comment for " Greg Kroah-Hartman
` (609 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, FUJITA Tomonori, Miguel Ojeda,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori <fujita.tomonori@gmail.com>
commit 951d09ca450ca76a695016ea76c3fa653bd20439 upstream.
On UML, `warn_flags!` calls `warn_slowpath_fmt()` directly. Its third
argument is a taint number, but `warn_on!` passes its bug flags there.
As a result, `add_taint()` gets 2304 instead of 9 (`TAINT_WARN`). The
warning is not recorded: `/proc/sys/kernel/tainted` stays 0 after
`warn_on!` fires, where it should be 512. It also causes an
out-of-bounds write in `add_taint()`.
Pass `TAINT_WARN` directly, as C does on UML.
Cc: stable@vger.kernel.org
Fixes: dff64b072708 ("rust: Add warn_on macro")
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Link: https://patch.msgid.link/20261001123103.2198104-1-tomo@flapping.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
[ Adapted to the single-argument `warn_flags!` macro. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
rust/kernel/bug.rs | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/bug.rs b/rust/kernel/bug.rs
index 53dbdaec3560b..364d90c6404c7 100644
--- a/rust/kernel/bug.rs
+++ b/rust/kernel/bug.rs
@@ -79,13 +79,17 @@ macro_rules! warn_flags {
#[cfg(all(CONFIG_BUG, CONFIG_UML))]
macro_rules! warn_flags {
($flags:expr) => {
+ if false {
+ _ = $flags;
+ }
+
// SAFETY: It is always safe to call `warn_slowpath_fmt()`
// with a valid null-terminated string.
unsafe {
$crate::bindings::warn_slowpath_fmt(
$crate::c_str!(::core::file!()).as_char_ptr(),
line!() as $crate::ffi::c_int,
- $flags as $crate::ffi::c_uint,
+ $crate::bindings::TAINT_WARN,
::core::ptr::null(),
);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 077/686] rust: bug: update the SAFETY comment for warn_slowpath_fmt() on UML
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (75 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 076/686] rust: bug: pass TAINT_WARN to warn_slowpath_fmt() on UML Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 078/686] wifi: rtw88: TX report with long timeout for non-PCIE devices Greg Kroah-Hartman
` (608 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miguel Ojeda, FUJITA Tomonori,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori <fujita.tomonori@gmail.com>
commit 5c94956f2bfb87025c1eaded6c51d5841d38d333 upstream.
The SAFETY comment says that it is always safe to call
`warn_slowpath_fmt()` with a valid null-terminated string. This is not
true. The taint argument must also be a valid taint number.
Commit 951d09ca450c ("rust: bug: pass TAINT_WARN to warn_slowpath_fmt()
on UML") fixed a bug where it was not.
List each condition that the call meets: the file name, the taint
number, and the null `fmt`.
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
Link: https://patch.msgid.link/20261002104550.2877930-1-tomo@flapping.org
Cc: stable@vger.kernel.org
Fixes: dff64b072708 ("rust: Add warn_on macro")
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
rust/kernel/bug.rs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/rust/kernel/bug.rs b/rust/kernel/bug.rs
index 364d90c6404c7..95bfd195c986a 100644
--- a/rust/kernel/bug.rs
+++ b/rust/kernel/bug.rs
@@ -83,8 +83,10 @@ macro_rules! warn_flags {
_ = $flags;
}
- // SAFETY: It is always safe to call `warn_slowpath_fmt()`
- // with a valid null-terminated string.
+ // SAFETY:
+ // - The file name is a null-terminated string with `'static` lifetime.
+ // - `TAINT_WARN` is a valid taint number.
+ // - `fmt` can be NULL, and NULL is passed.
unsafe {
$crate::bindings::warn_slowpath_fmt(
$crate::c_str!(::core::file!()).as_char_ptr(),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 078/686] wifi: rtw88: TX report with long timeout for non-PCIE devices
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (76 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 077/686] rust: bug: update the SAFETY comment for " Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 079/686] ACPI: CPPC: Validate FFH register fields before hardware access Greg Kroah-Hartman
` (607 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ping-Ke Shih, Luka Gejak,
Josef Schlehofer, Sasha Levin
6.18-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 e73c06b268cfa..b46f4fc8384cb 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] 687+ messages in thread
* [PATCH 6.18 079/686] ACPI: CPPC: Validate FFH register fields before hardware access
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (77 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 078/686] wifi: rtw88: TX report with long timeout for non-PCIE devices Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 080/686] ACPI: CPPC: Propagate errors from cross-CPU FFH calls Greg Kroah-Hartman
` (606 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Loehle, Sumit Gupta,
Rafael J. Wysocki, Sasha Levin
6.18-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 | 9 +++++++++
arch/x86/kernel/acpi/cppc.c | 15 +++++++++++++++
drivers/acpi/cppc_acpi.c | 10 ++++++----
3 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index 202f677e2b0f2..bbbe866680fd2 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -478,10 +478,19 @@ bool cpc_ffh_supported(void)
return true;
}
+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;
+}
+
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 0x0:
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 be4c5e9e5ff6f..ca5287ccd8968 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 531777557b47c..a3984e061ce0c 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -1017,6 +1017,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) &&
@@ -1044,8 +1047,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);
@@ -1091,6 +1092,9 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
struct cpc_desc *cpc_desc;
unsigned long flags;
+ 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) &&
@@ -1116,8 +1120,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] 687+ messages in thread
* [PATCH 6.18 080/686] ACPI: CPPC: Propagate errors from cross-CPU FFH calls
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (78 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 079/686] ACPI: CPPC: Validate FFH register fields before hardware access Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 081/686] ACPI: CPPC: Accept requests to retain immutable autonomous selection Greg Kroah-Hartman
` (605 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Loehle, Sumit Gupta,
Rafael J. Wysocki, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Loehle <christian.loehle@arm.com>
commit 36e96b469da24868f727b4cd168d7cf01cbd163d upstream.
The arm64 and RISC-V CPPC FFH accessors ignore the return value of
smp_call_function_single(). If the target CPU is offline, the call can
return -ENXIO without running the callback. The accessors then consume
callback output which was never initialized and may report success.
CPU offlining leaves the CPU's CPPC sysfs attributes present. On arm64,
the AMU feature mask does not exclude an offline CPU, so a paired counter
read can expose uninitialized stack values through feedback_ctrs. RISC-V
has the same problem in both SBI and CSR reads, and its write paths also
inspect an uninitialized callback status after a failed cross-CPU call.
Return the SMP call error before using callback output. The arm64 single
and paired counter readers already check the helper's return value. For
RISC-V, also check the callback status before copying a read value: an
unsupported CSR sets the error but does not initialize the value.
Fixes: 68c5debcc06d ("arm64: implement CPPC FFH support using AMUs")
Fixes: 30f3ffbee86b ("ACPI: RISC-V: Add CPPC driver")
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-18-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 | 4 +---
drivers/acpi/riscv/cppc.c | 26 ++++++++++++++++++++------
2 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/kernel/topology.c b/arch/arm64/kernel/topology.c
index bbbe866680fd2..415891ffa62e7 100644
--- a/arch/arm64/kernel/topology.c
+++ b/arch/arm64/kernel/topology.c
@@ -449,9 +449,7 @@ int counters_read_on_cpu(int cpu, smp_call_func_t func, u64 *val)
if (WARN_ON_ONCE(irqs_disabled()))
return -EPERM;
- smp_call_function_single(cpu, func, val, 1);
-
- return 0;
+ return smp_call_function_single(cpu, func, val, 1);
}
/*
diff --git a/drivers/acpi/riscv/cppc.c b/drivers/acpi/riscv/cppc.c
index 42c1a90524707..4ea4ddedd91f1 100644
--- a/drivers/acpi/riscv/cppc.c
+++ b/drivers/acpi/riscv/cppc.c
@@ -97,6 +97,7 @@ bool cpc_ffh_supported(void)
int cpc_read_ffh(int cpu, struct cpc_reg *reg, u64 *val)
{
struct sbi_cppc_data data;
+ int ret;
if (WARN_ON_ONCE(irqs_disabled()))
return -EPERM;
@@ -107,19 +108,27 @@ int cpc_read_ffh(int cpu, struct cpc_reg *reg, u64 *val)
data.reg = FFH_CPPC_SBI_REG(reg->address);
- smp_call_function_single(cpu, sbi_cppc_read, &data, 1);
+ ret = smp_call_function_single(cpu, sbi_cppc_read, &data, 1);
+ if (ret)
+ return ret;
+ if (data.ret.error)
+ return sbi_err_map_linux_errno(data.ret.error);
*val = data.ret.value;
- return (data.ret.error) ? sbi_err_map_linux_errno(data.ret.error) : 0;
+ return 0;
} else if (FFH_CPPC_TYPE(reg->address) == FFH_CPPC_CSR) {
data.reg = FFH_CPPC_CSR_NUM(reg->address);
- smp_call_function_single(cpu, cppc_ffh_csr_read, &data, 1);
+ ret = smp_call_function_single(cpu, cppc_ffh_csr_read, &data, 1);
+ if (ret)
+ return ret;
+ if (data.ret.error)
+ return data.ret.error;
*val = data.ret.value;
- return data.ret.error;
+ return 0;
}
return -EINVAL;
@@ -128,6 +137,7 @@ int cpc_read_ffh(int cpu, struct cpc_reg *reg, u64 *val)
int cpc_write_ffh(int cpu, struct cpc_reg *reg, u64 val)
{
struct sbi_cppc_data data;
+ int ret;
if (WARN_ON_ONCE(irqs_disabled()))
return -EPERM;
@@ -139,14 +149,18 @@ int cpc_write_ffh(int cpu, struct cpc_reg *reg, u64 val)
data.reg = FFH_CPPC_SBI_REG(reg->address);
data.val = val;
- smp_call_function_single(cpu, sbi_cppc_write, &data, 1);
+ ret = smp_call_function_single(cpu, sbi_cppc_write, &data, 1);
+ if (ret)
+ return ret;
return (data.ret.error) ? sbi_err_map_linux_errno(data.ret.error) : 0;
} else if (FFH_CPPC_TYPE(reg->address) == FFH_CPPC_CSR) {
data.reg = FFH_CPPC_CSR_NUM(reg->address);
data.val = val;
- smp_call_function_single(cpu, cppc_ffh_csr_write, &data, 1);
+ ret = smp_call_function_single(cpu, cppc_ffh_csr_write, &data, 1);
+ if (ret)
+ return ret;
return data.ret.error;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 081/686] ACPI: CPPC: Accept requests to retain immutable autonomous selection
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (79 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 080/686] ACPI: CPPC: Propagate errors from cross-CPU FFH calls Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 082/686] writeback: keep cleanup_offline_cgwb()s scan out of syncs Greg Kroah-Hartman
` (604 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Loehle, Sumit Gupta,
Rafael J. Wysocki, Sasha Levin
6.18-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 +++++++++++++++----
include/acpi/cppc_acpi.h | 6 +++++
3 files changed, 72 insertions(+), 7 deletions(-)
diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index a3984e061ce0c..2668004e89ec7 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))
@@ -899,12 +910,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;
}
@@ -956,6 +967,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;
@@ -1273,6 +1286,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");
@@ -1722,6 +1740,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 0b06bbd7215ff..c5047b56be50f 100644
--- a/drivers/cpufreq/amd-pstate.c
+++ b/drivers/cpufreq/amd-pstate.c
@@ -1653,7 +1653,7 @@ EXPORT_SYMBOL_GPL(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;
@@ -1663,12 +1663,27 @@ int amd_pstate_update_status(const char *buf, size_t size)
if (mode_idx < 0 || mode_idx >= AMD_PSTATE_MAX)
return -EINVAL;
- 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_GPL(amd_pstate_update_status);
diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h
index 13fa815048445..382a74430e748 100644
--- a/include/acpi/cppc_acpi.h
+++ b/include/acpi/cppc_acpi.h
@@ -171,6 +171,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 amd_get_highest_perf(unsigned int cpu, u32 *highest_perf);
extern int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator);
@@ -256,6 +257,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] 687+ messages in thread
* [PATCH 6.18 082/686] writeback: keep cleanup_offline_cgwb()s scan out of syncs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (80 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 081/686] ACPI: CPPC: Accept requests to retain immutable autonomous selection Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 083/686] pppoe: delete session hash entries by pointer match Greg Kroah-Hartman
` (603 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tejun Heo, Liz Fong-Jones, Jan Kara,
Christian Brauner (Amutable), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liz Fong-Jones <lizf@honeycomb.io>
[ Upstream commit 90c96612460e6accddbda5a195e6ddaa391ecde0 ]
On a filesystem mounted with lazytime, sync() and syncfs() can return
without persisting timestamp updates of inodes attached to a dying
cgroup wb, so a crash after the sync loses them. File data and sizes are
not affected.
Since commit f6988c90671e ("writeback: bound cleanup_offline_cgwb()
rescans by rotating scanned inodes"), isw_prepare_wbs_switch() moves the
inodes it walks to the newest end of the list. When a pass fills its isw
before reaching an inode that got its lazytime update after a sync's
cutoff, the walked inodes land past it on b_dirty_time, and the sync's
queue_io(), which stops at the first inode dirtied after the cutoff,
misses them. The late inode has to be one without a pending lazytime
update; one already on b_dirty_time keeps its position.
The window is narrow. cleanup_offline_cgwbs_workfn() skips wbs with
anything on b_dirty, b_io or b_more_io, so the scan has to land between
wb_writeback() fixing dirtied_before and taking list_lock for its first
queue_io(), unless a multi-pass drain started before the wb got dirty
IO.
Take wb_switch_rwsem for read across the scan, as
process_inode_switch_wbs() does for the switches.
Fixes: f6988c90671e ("writeback: bound cleanup_offline_cgwb() rescans by rotating scanned inodes")
Cc: stable@vger.kernel.org
Suggested-by: Tejun Heo <tj@kernel.org>
Link: https://lore.kernel.org/all/0bc5d58533f10b4841807be3025daa11@kernel.org/
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Liz Fong-Jones <lizf@honeycomb.io>
Link: https://patch.msgid.link/20261017040710.1174009-1-lizf@honeycomb.io
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ Take wb_switch_rwsem before this branch's rcu_read_lock(), as
down_read() can sleep. ]
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Liz Fong-Jones <lizf@honeycomb.io>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/fs-writeback.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 3025fc7ddfe84..85f21ecc59958 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -757,6 +757,13 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb)
new_wb = &wb->bdi->wb; /* wb_get() is noop for bdi's wb */
nr = 0;
+ /*
+ * The scan moves walked inodes to the newest end of b_dirty_time,
+ * past ones it didn't reach. If one of those was dirtied after a
+ * sync's cutoff, the sync's queue_io() stops there and misses the
+ * moved ones. Exclude syncs as process_inode_switch_wbs() does.
+ */
+ down_read(&wb->bdi->wb_switch_rwsem);
/*
* Paired with synchronize_rcu() in cgroup_writeback_umount().
* Holding rcu_read_lock across the SB_ACTIVE check, the inode grab
@@ -779,6 +786,7 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb)
restart = isw_prepare_wbs_switch(new_wb, isw, &wb->b_dirty_time,
&nr);
spin_unlock(&wb->list_lock);
+ up_read(&wb->bdi->wb_switch_rwsem);
/* no attached inodes? bail out */
if (nr == 0) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 083/686] pppoe: delete session hash entries by pointer match
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (81 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 082/686] writeback: keep cleanup_offline_cgwb()s scan out of syncs Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 084/686] xfs: reinitialize dquot block if non-first dquot cant load Greg Kroah-Hartman
` (602 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qingfang Deng, Jakub Kicinski,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <qingfang.deng@linux.dev>
[ Upstream commit b5b8c81836e2bec7b444dfa2b14fd14e912e9d63 ]
pppoe_connect() copies the requested PPPoE address to a socket before
attempting to insert the socket into the session hash table. If the
tuple already exists, __set_item() returns -EALREADY, but the copied
address and ifindex remain set on the failed socket.
Closing that socket then deletes the existing socket's hash entry
through pppoe_release(), preventing it from receiving further session
traffic. An unprivileged process in the same network namespace can
trigger this through a duplicate connection attempt.
To avoid the accidental delete, pass the pppox_sock to __delete_item(),
and unlink only an entry whose pointer matches the requested socket.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Link: https://patch.msgid.link/20261020092118.47416-1-qingfang.deng@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
[ Resolve conflict, and remove const qualifier of pppox_sock to match
hash_item(). ]
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ppp/pppoe.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
index 7ee63051a1619..0bfb048c291a3 100644
--- a/drivers/net/ppp/pppoe.c
+++ b/drivers/net/ppp/pppoe.c
@@ -195,18 +195,16 @@ static int __set_item(struct pppoe_net *pn, struct pppox_sock *po)
return 0;
}
-static void __delete_item(struct pppoe_net *pn, __be16 sid,
- char *addr, int ifindex)
+static void __delete_item(struct pppoe_net *pn, struct pppox_sock *po)
{
- int hash = hash_item(sid, addr);
+ int hash = hash_item(po->pppoe_pa.sid, po->pppoe_pa.remote);
struct pppox_sock *ret, __rcu **src;
ret = rcu_dereference_protected(pn->hash_table[hash], lockdep_is_held(&pn->hash_lock));
src = &pn->hash_table[hash];
while (ret) {
- if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
- ret->pppoe_ifindex == ifindex) {
+ if (ret == po) {
struct pppox_sock *next;
next = rcu_dereference_protected(ret->next,
@@ -256,11 +254,10 @@ static inline struct pppox_sock *__get_item_by_addr(struct net *net,
return pppox_sock;
}
-static inline void delete_item(struct pppoe_net *pn, __be16 sid,
- char *addr, int ifindex)
+static void delete_item(struct pppoe_net *pn, struct pppox_sock *po)
{
spin_lock(&pn->hash_lock);
- __delete_item(pn, sid, addr, ifindex);
+ __delete_item(pn, po);
spin_unlock(&pn->hash_lock);
}
@@ -602,8 +599,7 @@ static int pppoe_release(struct socket *sock)
* protect "po" from concurrent updates
* on pppoe_flush_dev
*/
- delete_item(pn, po->pppoe_pa.sid, po->pppoe_pa.remote,
- po->pppoe_ifindex);
+ delete_item(pn, po);
sock_orphan(sk);
sock->sk = NULL;
@@ -653,8 +649,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
if (stage_session(po->pppoe_pa.sid)) {
pppox_unbind_sock(sk);
pn = pppoe_pernet(sock_net(sk));
- delete_item(pn, po->pppoe_pa.sid,
- po->pppoe_pa.remote, po->pppoe_ifindex);
+ delete_item(pn, po);
if (po->pppoe_dev) {
dev_put(po->pppoe_dev);
po->pppoe_dev = NULL;
@@ -705,8 +700,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
error = ppp_register_net_channel(dev_net(dev), &po->chan);
if (error) {
- delete_item(pn, po->pppoe_pa.sid,
- po->pppoe_pa.remote, po->pppoe_ifindex);
+ delete_item(pn, po);
goto err_put;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 084/686] xfs: reinitialize dquot block if non-first dquot cant load
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (82 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 083/686] pppoe: delete session hash entries by pointer match Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 085/686] xfs: forcibly reset quota timers when upgrading to bigtime during repair Greg Kroah-Hartman
` (601 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-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 baf77a158eac8..cf17d35b70cce 100644
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -299,7 +299,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;
@@ -321,14 +320,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;
}
@@ -341,7 +347,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] 687+ messages in thread
* [PATCH 6.18 085/686] xfs: forcibly reset quota timers when upgrading to bigtime during repair
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (83 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 084/686] xfs: reinitialize dquot block if non-first dquot cant load Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 086/686] smb: client: reclaim credits for decrypted reads with no matching mid Greg Kroah-Hartman
` (600 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-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 cf17d35b70cce..44806ce8c0bf4 100644
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -348,6 +348,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);
@@ -356,8 +358,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] 687+ messages in thread
* [PATCH 6.18 086/686] smb: client: reclaim credits for decrypted reads with no matching mid
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (84 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 085/686] xfs: forcibly reset quota timers when upgrading to bigtime during repair Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 087/686] smb: client: reject FIND data areas that run past the received response Greg Kroah-Hartman
` (599 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paulo Alcantara, David Howells,
Namjae Jeon, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
Bharath SM, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
[ Upstream commit 78f73985846465a25a7bd1d89904053661f3ca92 ]
When a decrypted SMB2 READ response carries a MessageId that matches no
outstanding request, both the inline receive_encrypted_read() and the
offloaded smb2_decrypt_offload() paths drop the frame without accounting
the credits the server granted in it. The plaintext unknown-frame path in
cifs_demultiplex_thread() already reclaims them with
smb2_add_credits_from_hdr(), so encrypted reads leak credits that the
plaintext path would not.
This also happens for legitimate frames - e.g. a reply that arrives after
the client has timed out and dropped the mid - so over a long-lived
connection the client's credit count drifts down and can eventually starve
it of the ability to issue requests. The frame is AEAD-authenticated, so
the granted credits in the decrypted header come from the real server and
are safe to apply.
Reclaim the credits from the decrypted header before dropping the frame,
and export smb2_add_credits_from_hdr() so the SMB2 receive paths can use it.
Fixes: c42a6abe3012 ("CIFS: Add capability to decrypt big read responses")
Fixes: 35cf94a39728 ("smb3: allow parallelizing decryption of reads")
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Reviewed-by: David Howells <dhowells@redhat.com>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
[ sashal: adjusted prototype insertion context to preserve existing declaration formatting and extern keywords ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifsproto.h | 1 +
fs/smb/client/connect.c | 3 +--
fs/smb/client/smb2ops.c | 6 ++++--
3 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 325408073888e..d47ad5d86b4b1 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -161,6 +161,7 @@ cifs_mark_tcp_ses_conns_for_reconnect(struct TCP_Server_Info *server,
bool mark_smb_session);
extern int cifs_reconnect(struct TCP_Server_Info *server,
bool mark_smb_session);
+void smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server);
extern int checkSMB(char *buf, unsigned int len, struct TCP_Server_Info *srvr);
extern bool is_valid_oplock_break(char *, struct TCP_Server_Info *);
extern bool backup_cred(struct cifs_sb_info *);
diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c
index 0a60c411aba67..b4e139471e865 100644
--- a/fs/smb/client/connect.c
+++ b/fs/smb/client/connect.c
@@ -1235,8 +1235,7 @@ cifs_handle_standard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
return 0;
}
-static void
-smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
+void smb2_add_credits_from_hdr(char *buffer, struct TCP_Server_Info *server)
{
struct smb2_hdr *shdr = (struct smb2_hdr *)buffer;
int scredits, in_flight;
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 71cf42981ab04..f7f8e8b981f75 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -5256,9 +5256,10 @@ static void smb2_decrypt_offload(struct work_struct *work)
dw->server->lstrp = jiffies;
mid = smb2_find_dequeue_mid(dw->server, dw->buf);
- if (mid == NULL)
+ if (mid == NULL) {
cifs_dbg(FYI, "mid not found\n");
- else {
+ smb2_add_credits_from_hdr(dw->buf, dw->server);
+ } else {
mid->decrypted = true;
rc = handle_read_data(dw->server, mid, dw->buf,
dw->server->vals->read_rsp_size,
@@ -5381,6 +5382,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid,
*mid = smb2_find_mid(server, buf);
if (*mid == NULL) {
cifs_dbg(FYI, "mid not found\n");
+ smb2_add_credits_from_hdr(buf, server);
rc = -1;
} else {
cifs_dbg(FYI, "mid found\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 087/686] smb: client: reject FIND data areas that run past the received response
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (85 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 086/686] smb: client: reclaim credits for decrypted reads with no matching mid Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 088/686] raid6: add missing vzeroupper to AVX2 code Greg Kroah-Hartman
` (598 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diego Oliva, David Howells,
Paulo Alcantara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diego Oliva <diego@bynar.io>
[ Upstream commit 29bd6773187cb5c1bbbdf90d677c6add7d58af26 ]
CIFSFindFirst() and CIFSFindNext() take the directory entries of a
TRANS2_FIND_FIRST2 or TRANS2_FIND_NEXT2 response from DataOffset for
DataCount bytes. validate_t2() bounds DataOffset at 1024 and
ParameterCount + DataCount by the byte count, and nothing compares
DataOffset + DataCount with the number of bytes SendReceive() copied
into the buffer.
smb_init() places the request and the response in the same
cifs_request allocation and cifs_buf_get() clears only the start of
it, so a short response whose data area extends past its end has
srch_entries_start point at bytes of the request that was just sent,
or at whatever the allocation held before, and those bytes are parsed
as directory entries. cifs_readdir() and find_cifs_entry() walk the
entries with nxt_dir_entry(), which checks every entry but the first
of a response against the end of the SMB; cifs_query_path_info() and
cifs_backup_query_path_info() read the first entry with no check at
all. Those reads stay inside the allocation, but what they return is
not part of the response. The last entry, which LastNameOffset locates
relative to the data area, is bounded against the received response
by an earlier patch of this series, as is every entry that
cifs_fill_dirent() parses; the walk itself and the two query functions
are not.
SMB1 is not negotiated by default; reaching this code requires an
explicit vers=1.0 mount.
Reject a response whose data area extends past the received length,
with the -EINVAL that validate_t2() returns for the other malformed
transaction responses. cifs_query_path_info() and
cifs_backup_query_path_info() still read a whole entry from a data
area that may be smaller than one; that is not changed here.
A conforming server is not affected. The data block of a transaction
response is part of the SMB, so DataOffset + DataCount cannot exceed
the smbCalcSize() bytes that SendReceive() copies; coalesce_t2()
appends each secondary response to the data area and adds its length
to both DataCount and the byte count, which keeps that relation.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Assisted-by: Bynario AI
Signed-off-by: Diego Oliva <diego@bynar.io>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
[ sashal: Adjusted declaration context in CIFSFindFirst() and CIFSFindNext() to account for the missing in_len variable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/cifssmb.c | 31 +++++++++++++++++++++++++------
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index 1049a64241bc0..320274e7f7051 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -4325,8 +4325,9 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
/* level 257 SMB_ */
TRANSACTION2_FFIRST_REQ *pSMB = NULL;
TRANSACTION2_FFIRST_RSP *pSMBr = NULL;
- T2_FFIRST_RSP_PARMS *parms;
+ unsigned int data_off, data_count;
struct nls_table *nls_codepage;
+ T2_FFIRST_RSP_PARMS *parms;
unsigned int lnoff;
__u16 params, byte_count;
int bytes_returned = 0;
@@ -4445,11 +4446,19 @@ CIFSFindFirst(const unsigned int xid, struct cifs_tcon *tcon,
return rc;
}
+ data_off = le16_to_cpu(pSMBr->t2.DataOffset);
+ data_count = le16_to_cpu(pSMBr->t2.DataCount);
+ if (data_off + data_count > (unsigned int)bytes_returned) {
+ cifs_dbg(VFS, "%s: data area offset %u count %u past response length %d\n",
+ __func__, data_off, data_count, bytes_returned);
+ cifs_buf_release(pSMB);
+ return -EINVAL;
+ }
+
psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
psrch_inf->ntwrk_buf_start = (char *)pSMBr;
psrch_inf->smallBuf = false;
- psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
+ psrch_inf->srch_entries_start = (char *)&pSMBr->hdr.Protocol + data_off;
parms = (T2_FFIRST_RSP_PARMS *)((char *)&pSMBr->hdr.Protocol +
le16_to_cpu(pSMBr->t2.ParameterOffset));
@@ -4482,8 +4491,9 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
{
TRANSACTION2_FNEXT_REQ *pSMB = NULL;
TRANSACTION2_FNEXT_RSP *pSMBr = NULL;
- T2_FNEXT_RSP_PARMS *parms;
+ unsigned int data_off, data_count;
unsigned int name_len;
+ T2_FNEXT_RSP_PARMS *parms;
unsigned int lnoff;
__u16 params, byte_count;
char *response_data;
@@ -4566,13 +4576,22 @@ int CIFSFindNext(const unsigned int xid, struct cifs_tcon *tcon,
cifs_buf_release(pSMB);
return rc;
}
+
+ data_off = le16_to_cpu(pSMBr->t2.DataOffset);
+ data_count = le16_to_cpu(pSMBr->t2.DataCount);
+ if (data_off + data_count > (unsigned int)bytes_returned) {
+ cifs_dbg(VFS, "%s: data area offset %u count %u past response length %d\n",
+ __func__, data_off, data_count, bytes_returned);
+ cifs_buf_release(pSMB);
+ return -EINVAL;
+ }
+
/* BB fixme add lock for file (srch_info) struct here */
psrch_inf->unicode = !!(pSMBr->hdr.Flags2 & SMBFLG2_UNICODE);
response_data = (char *)&pSMBr->hdr.Protocol +
le16_to_cpu(pSMBr->t2.ParameterOffset);
parms = (T2_FNEXT_RSP_PARMS *)response_data;
- response_data = (char *)&pSMBr->hdr.Protocol +
- le16_to_cpu(pSMBr->t2.DataOffset);
+ response_data = (char *)&pSMBr->hdr.Protocol + data_off;
if (psrch_inf->smallBuf)
cifs_small_buf_release(psrch_inf->ntwrk_buf_start);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 088/686] raid6: add missing vzeroupper to AVX2 code
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (86 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 087/686] smb: client: reject FIND data areas that run past the received response Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 089/686] mtd: rawnand: ndfc: use ioread32be/iowrite32be and allow COMPILE_TEST Greg Kroah-Hartman
` (597 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Biggers, Andrew Morton,
Christoph Hellwig, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit 24f1241cdb056fd630e6710a916e0f7c8c910a70 upstream.
Since the AVX2 optimized RAID6 code uses YMM registers, execute vzeroupper
before returning from it. This is needed to avoid degrading the
performance of any later SSE code that may happen to be executed.
Link: https://lore.kernel.org/20260831212308.213855-1-ebiggers@kernel.org
Fixes: 2c935842bdb4 ("lib/raid6: Add AVX2 optimized gen_syndrome functions")
Fixes: 7056741fd9fc ("lib/raid6: Add AVX2 optimized recovery functions")
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Cc: Christoph Hellwig <hch@lst.de>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/raid6/avx2.c | 6 ++++++
lib/raid6/recov_avx2.c | 2 ++
2 files changed, 8 insertions(+)
diff --git a/lib/raid6/avx2.c b/lib/raid6/avx2.c
index 059024234dce1..2d03ce97f655d 100644
--- a/lib/raid6/avx2.c
+++ b/lib/raid6/avx2.c
@@ -76,6 +76,7 @@ static void raid6_avx21_gen_syndrome(int disks, size_t bytes, void **ptrs)
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -124,6 +125,7 @@ static void raid6_avx21_xor_syndrome(int disks, int start, int stop,
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -186,6 +188,7 @@ static void raid6_avx22_gen_syndrome(int disks, size_t bytes, void **ptrs)
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -254,6 +257,7 @@ static void raid6_avx22_xor_syndrome(int disks, int start, int stop,
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -347,6 +351,7 @@ static void raid6_avx24_gen_syndrome(int disks, size_t bytes, void **ptrs)
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -457,6 +462,7 @@ static void raid6_avx24_xor_syndrome(int disks, int start, int stop,
asm volatile("vmovntdq %%ymm14,%0" : "=m" (q[d+96]));
}
asm volatile("sfence" : : : "memory");
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
diff --git a/lib/raid6/recov_avx2.c b/lib/raid6/recov_avx2.c
index 97d598d2535ca..0ae0a621538a1 100644
--- a/lib/raid6/recov_avx2.c
+++ b/lib/raid6/recov_avx2.c
@@ -180,6 +180,7 @@ static void raid6_2data_recov_avx2(int disks, size_t bytes, int faila,
#endif
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
@@ -297,6 +298,7 @@ static void raid6_datap_recov_avx2(int disks, size_t bytes, int faila,
#endif
}
+ asm volatile("vzeroupper");
kernel_fpu_end();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 089/686] mtd: rawnand: ndfc: use ioread32be/iowrite32be and allow COMPILE_TEST
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (87 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 088/686] raid6: add missing vzeroupper to AVX2 code Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 090/686] mtd: rawnand: ndfc: add CONFIG_OF dependency Greg Kroah-Hartman
` (596 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rosen Penev, Miquel Raynal,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <rosenp@gmail.com>
[ Upstream commit 4f2692a5383e4bdd43ae940cda012360f7217a2d ]
Replace ppc4xx-specific in_be32/out_be32 with generic ioread32be/
iowrite32be to make the driver portable. Add COMPILE_TEST dependency
to get build coverage on non-ppc4xx architectures.
While at it, replace 4xx with 44x. The latter was removed a while ago
and is only kept for compatibility.
Assisted-by: opencode:big-pickle
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/nand/raw/Kconfig | 2 +-
drivers/mtd/nand/raw/ndfc.c | 20 ++++++++++----------
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 7408f34f0c68a..ee01b845694de 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -71,7 +71,7 @@ config MTD_NAND_AU1550
config MTD_NAND_NDFC
tristate "IBM/MCC 4xx NAND controller"
- depends on 4xx
+ depends on 44x || COMPILE_TEST
select MTD_NAND_ECC_SW_HAMMING
select MTD_NAND_ECC_SW_HAMMING_SMC
help
diff --git a/drivers/mtd/nand/raw/ndfc.c b/drivers/mtd/nand/raw/ndfc.c
index 13365128194d0..9a38da68976c8 100644
--- a/drivers/mtd/nand/raw/ndfc.c
+++ b/drivers/mtd/nand/raw/ndfc.c
@@ -44,13 +44,13 @@ static void ndfc_select_chip(struct nand_chip *nchip, int chip)
uint32_t ccr;
struct ndfc_controller *ndfc = nand_get_controller_data(nchip);
- ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
+ ccr = ioread32be(ndfc->ndfcbase + NDFC_CCR);
if (chip >= 0) {
ccr &= ~NDFC_CCR_BS_MASK;
ccr |= NDFC_CCR_BS(chip + ndfc->chip_select);
} else
ccr |= NDFC_CCR_RESET_CE;
- out_be32(ndfc->ndfcbase + NDFC_CCR, ccr);
+ iowrite32be(ccr, ndfc->ndfcbase + NDFC_CCR);
}
static void ndfc_hwcontrol(struct nand_chip *chip, int cmd, unsigned int ctrl)
@@ -70,7 +70,7 @@ static int ndfc_ready(struct nand_chip *chip)
{
struct ndfc_controller *ndfc = nand_get_controller_data(chip);
- return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
+ return ioread32be(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
}
static void ndfc_enable_hwecc(struct nand_chip *chip, int mode)
@@ -78,9 +78,9 @@ static void ndfc_enable_hwecc(struct nand_chip *chip, int mode)
uint32_t ccr;
struct ndfc_controller *ndfc = nand_get_controller_data(chip);
- ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
+ ccr = ioread32be(ndfc->ndfcbase + NDFC_CCR);
ccr |= NDFC_CCR_RESET_ECC;
- out_be32(ndfc->ndfcbase + NDFC_CCR, ccr);
+ iowrite32be(ccr, ndfc->ndfcbase + NDFC_CCR);
wmb();
}
@@ -92,7 +92,7 @@ static int ndfc_calculate_ecc(struct nand_chip *chip,
uint8_t *p = (uint8_t *)&ecc;
wmb();
- ecc = in_be32(ndfc->ndfcbase + NDFC_ECC);
+ ecc = ioread32be(ndfc->ndfcbase + NDFC_ECC);
/* The NDFC uses Smart Media (SMC) bytes order */
ecc_code[0] = p[1];
ecc_code[1] = p[2];
@@ -114,7 +114,7 @@ static void ndfc_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
uint32_t *p = (uint32_t *) buf;
for(;len > 0; len -= 4)
- *p++ = in_be32(ndfc->ndfcbase + NDFC_DATA);
+ *p++ = ioread32be(ndfc->ndfcbase + NDFC_DATA);
}
static void ndfc_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
@@ -123,7 +123,7 @@ static void ndfc_write_buf(struct nand_chip *chip, const uint8_t *buf, int len)
uint32_t *p = (uint32_t *) buf;
for(;len > 0; len -= 4)
- out_be32(ndfc->ndfcbase + NDFC_DATA, *p++);
+ iowrite32be(*p++, ndfc->ndfcbase + NDFC_DATA);
}
/*
@@ -223,13 +223,13 @@ static int ndfc_probe(struct platform_device *ofdev)
if (reg)
ccr |= be32_to_cpup(reg);
- out_be32(ndfc->ndfcbase + NDFC_CCR, ccr);
+ iowrite32be(ccr, ndfc->ndfcbase + NDFC_CCR);
/* Set the bank settings if given */
reg = of_get_property(ofdev->dev.of_node, "bank-settings", NULL);
if (reg) {
int offset = NDFC_BCFG0 + (ndfc->chip_select << 2);
- out_be32(ndfc->ndfcbase + offset, be32_to_cpup(reg));
+ iowrite32be(be32_to_cpup(reg), ndfc->ndfcbase + offset);
}
err = ndfc_chip_init(ndfc, ofdev->dev.of_node);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 090/686] mtd: rawnand: ndfc: add CONFIG_OF dependency
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (88 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 089/686] mtd: rawnand: ndfc: use ioread32be/iowrite32be and allow COMPILE_TEST Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 091/686] mtd: rawnand: ndfc: fix gcc uninitialized var Greg Kroah-Hartman
` (595 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arnd Bergmann, Rosen Penev,
Miquel Raynal, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <arnd@arndb.de>
[ Upstream commit 97f9e509d839f7e5b9a32105ae322e5223c86786 ]
When compile-testing on x86 without CONFIG_OF, the ndfc driver produces
a harmless warning:
drivers/mtd/nand/raw/ndfc.c: In function 'ndfc_probe':
include/linux/dev_printk.h:154:31: error: 'len' is used uninitialized [-Werror=uninitialized]
154 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__)
| ^
drivers/mtd/nand/raw/ndfc.c:196:17: note: in expansion of macro 'dev_err'
196 | dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
Limit compile-testing to configurations with CONFIG_OF to trivially
avoid this. The driver will still be built in allmodconfig and many
randconfig builds.
Fixes: 4f2692a5383e ("mtd: rawnand: ndfc: use ioread32be/iowrite32be and allow COMPILE_TEST")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/nand/raw/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index ee01b845694de..2aba02ebe03e2 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -72,6 +72,7 @@ config MTD_NAND_AU1550
config MTD_NAND_NDFC
tristate "IBM/MCC 4xx NAND controller"
depends on 44x || COMPILE_TEST
+ depends on OF
select MTD_NAND_ECC_SW_HAMMING
select MTD_NAND_ECC_SW_HAMMING_SMC
help
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 091/686] mtd: rawnand: ndfc: fix gcc uninitialized var
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (89 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 090/686] mtd: rawnand: ndfc: add CONFIG_OF dependency Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 092/686] mtd: rawnand: ndfc: use devm_platform_ioremap_resource() Greg Kroah-Hartman
` (594 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Rosen Penev,
Miquel Raynal, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <rosenp@gmail.com>
[ Upstream commit cceca8cb776b03e83985578f84bd730c30d57f70 ]
Now that this can be built with COMPILE_TEST, an unassigned variable was
found. Set to 0 to fix the W=1 error under GCC.
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202606141301.iyVdFgl7-lkp@intel.com/
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/nand/raw/ndfc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/nand/raw/ndfc.c b/drivers/mtd/nand/raw/ndfc.c
index 9a38da68976c8..e1628d021a8b6 100644
--- a/drivers/mtd/nand/raw/ndfc.c
+++ b/drivers/mtd/nand/raw/ndfc.c
@@ -188,7 +188,7 @@ static int ndfc_probe(struct platform_device *ofdev)
const __be32 *reg;
u32 ccr;
u32 cs;
- int err, len;
+ int err, len = 0;
/* Read the reg property to get the chip select */
reg = of_get_property(ofdev->dev.of_node, "reg", &len);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 092/686] mtd: rawnand: ndfc: use devm_platform_ioremap_resource()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (90 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 091/686] mtd: rawnand: ndfc: fix gcc uninitialized var Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 093/686] net: bgmac: enable interrupts only after NAPI is ready Greg Kroah-Hartman
` (593 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rosen Penev, Miquel Raynal,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <rosenp@gmail.com>
[ Upstream commit 0d66f9895f286d2fab396a71e6efeb95c4a7e5a6 ]
Replace the open-coded of_iomap()/iounmap() with the managed
devm_platform_ioremap_resource() helper. This fixes a mapping leak on
driver remove (the old code never called iounmap()) and simplifies the
error path by dropping the manual cleanup in ndfc_probe().
There is no overlapping memory-region concern introduced by this
change: each supported board DT describes a single ndfc node with a
unique 0x2000 register region, and the EBC parent uses dcr-reg rather
than a MEM reg resource, so the newly added request_mem_region() cannot
conflict with an existing reservation. Distinct chip selects map to
distinct 64-bit physical addresses, so CS instances do not overlap.
Fixes: a808ad3b0d28 ("[MTD] [NAND] ndfc driver")
Cc: stable@vger.kernel.org
Assisted-by: opencode:hy3-free
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mtd/nand/raw/ndfc.c | 21 ++++++++-------------
1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/drivers/mtd/nand/raw/ndfc.c b/drivers/mtd/nand/raw/ndfc.c
index e1628d021a8b6..6f67bfe32a094 100644
--- a/drivers/mtd/nand/raw/ndfc.c
+++ b/drivers/mtd/nand/raw/ndfc.c
@@ -185,10 +185,15 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
static int ndfc_probe(struct platform_device *ofdev)
{
struct ndfc_controller *ndfc;
+ void __iomem *ndfcbase;
const __be32 *reg;
u32 ccr;
u32 cs;
- int err, len = 0;
+ int len = 0;
+
+ ndfcbase = devm_platform_ioremap_resource(ofdev, 0);
+ if (IS_ERR(ndfcbase))
+ return PTR_ERR(ndfcbase);
/* Read the reg property to get the chip select */
reg = of_get_property(ofdev->dev.of_node, "reg", &len);
@@ -210,11 +215,7 @@ static int ndfc_probe(struct platform_device *ofdev)
ndfc->ofdev = ofdev;
dev_set_drvdata(&ofdev->dev, ndfc);
- ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0);
- if (!ndfc->ndfcbase) {
- dev_err(&ofdev->dev, "failed to get memory\n");
- return -EIO;
- }
+ ndfc->ndfcbase = ndfcbase;
ccr = NDFC_CCR_BS(ndfc->chip_select);
@@ -232,13 +233,7 @@ static int ndfc_probe(struct platform_device *ofdev)
iowrite32be(be32_to_cpup(reg), ndfc->ndfcbase + offset);
}
- err = ndfc_chip_init(ndfc, ofdev->dev.of_node);
- if (err) {
- iounmap(ndfc->ndfcbase);
- return err;
- }
-
- return 0;
+ return ndfc_chip_init(ndfc, ofdev->dev.of_node);
}
static void ndfc_remove(struct platform_device *ofdev)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 093/686] net: bgmac: enable interrupts only after NAPI is ready
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (91 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 092/686] mtd: rawnand: ndfc: use devm_platform_ioremap_resource() Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 094/686] ksmbd: fix tree connection use-after-free in smb2_tree_connect() Greg Kroah-Hartman
` (592 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rosen Penev, Daniel Machon,
Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <rosenp@gmail.com>
[ Upstream commit ac1f6e58cb77bb66b8811f7d98703e0f076a8f65 ]
bgmac_open() calls bgmac_chip_init(), which unmasks the interrupts and
enables the MAC receiver, before request_irq() and napi_enable().
bgmac_enet_resume() also enables NAPI only after bgmac_chip_init().
When frames arrive in that window, the first RX interrupt masks all
interrupts in bgmac_interrupt() and calls napi_schedule() on a NAPI
instance that is still disabled, so nothing is scheduled. Nothing
unmasks the interrupts again, the RX ring fills up and the interface
stays deaf until it is brought down and up without traffic.
On an Asus RT-N16 (BCM4716) a single "ip link set eth0 down/up" while
a host sends UDP to the router left INT_MASK at 0, INT_STATUS with RX
pending and the RX DMA idle on a full ring, with the RX packet and
interrupt counters no longer moving. With this change, 10 of 10 such
cycles recovered on their own.
Request the IRQ and enable NAPI before the chip is initialized.
Fixes: dd4544f05469 ("bgmac: driver for GBit MAC core on BCMA bus")
Fixes: f3537b3494c0 ("net: ethernet: bgmac: driver power manangement")
Cc: stable@vger.kernel.org
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Reviewed-by: Daniel Machon <daniel.machon@microchip.com>
Link: https://patch.msgid.link/20261010070011.60403-1-rosenp@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bgmac.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
index 3e9c57196a397..1835266fdd09f 100644
--- a/drivers/net/ethernet/broadcom/bgmac.c
+++ b/drivers/net/ethernet/broadcom/bgmac.c
@@ -1183,9 +1183,6 @@ static int bgmac_open(struct net_device *net_dev)
if (err)
return err;
- /* Specs say about reclaiming rings here, but we do that in DMA init */
- bgmac_chip_init(bgmac);
-
err = request_irq(bgmac->irq, bgmac_interrupt, IRQF_SHARED,
net_dev->name, net_dev);
if (err < 0) {
@@ -1195,6 +1192,9 @@ static int bgmac_open(struct net_device *net_dev)
}
napi_enable(&bgmac->napi);
+ /* Specs say about reclaiming rings here, but we do that in DMA init */
+ bgmac_chip_init(bgmac);
+
phy_start(net_dev->phydev);
netif_start_queue(net_dev);
@@ -1608,10 +1608,10 @@ int bgmac_enet_resume(struct bgmac *bgmac)
if (rc)
return rc;
- bgmac_chip_init(bgmac);
-
napi_enable(&bgmac->napi);
+ bgmac_chip_init(bgmac);
+
netif_tx_lock(bgmac->net_dev);
netif_device_attach(bgmac->net_dev);
netif_tx_unlock(bgmac->net_dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 094/686] ksmbd: fix tree connection use-after-free in smb2_tree_connect()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (92 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 093/686] net: bgmac: enable interrupts only after NAPI is ready Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 095/686] nfsd: shorten extack string returned with dodgy listener Greg Kroah-Hartman
` (591 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiang Mei (Microsoft),
AutonomousCodeSecurity, Cen Zhang (Microsoft Security FORGE Labs),
Namjae Jeon, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
[ Upstream commit b5ec6c462aab1062cf5d1e667ba7c6442f737055 ]
ksmbd_tree_conn_connect() publishes a new tree connection in
sess->tree_conns with a single reference and returns its pointer to
smb2_tree_connect(). The handler continues to initialize the object and
build the response after publication. A concurrent session logoff can
erase the connection and drop that reference, freeing the object while
the handler still uses it.
BUG: KASAN: slab-use-after-free in smb2_tree_connect+0xe3d/0xf90
smb2_tree_connect (fs/smb/server/smb2pdu.c:2872)
handle_ksmbd_work
process_one_work
worker_thread
kthread
After xa_store() succeeds, take a second reference before releasing
tree_conns_lock. The original reference belongs to the xarray entry and
the second belongs to the creating smb2_tree_connect() handler.
Keep the references balanced in every path:
- On normal exit or an error after publication, smb2_tree_connect()
drops its creator reference. Error cleanup also calls
ksmbd_tree_conn_disconnect(), which drops the xarray reference only if
it removes the exact entry.
- SMB2 TREE_DISCONNECT uses the same helper to remove the entry and drop
its xarray reference. The request's existing lookup reference remains
owned by the request and is released by the existing cleanup.
- Session LOGOFF removes each entry and drops its xarray reference. If
it wins the race, later cleanup sees that the entry is gone and does
not drop that reference again.
To enforce this ownership, claim the disconnected state and erase the
exact entry atomically under tree_conns_lock. This guarantees one drop
for the xarray reference and one drop by each in-flight user, regardless
of which teardown path wins. If logoff removes the entry before
initialization completes, fail the connect instead of marking the
detached object TREE_CONNECTED.
Fixes: 33b235a6e6eb ("ksmbd: fix race condition between tree conn lookup and disconnect")
Reported-by: Xiang Mei (Microsoft) <xmei5@asu.edu>
Cc: AutonomousCodeSecurity@microsoft.com
Cc: stable@vger.kernel.org
Signed-off-by: Cen Zhang (Microsoft Security FORGE Labs) <cenzhang@linux.microsoft.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
[ sashal: Adapted the smb2_tree_connect() hunk to the older brace-less if/else layout and fixed the context for the missing counter-decrement line in tree_connect.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/mgmt/tree_connect.c | 8 ++++++++
fs/smb/server/smb2pdu.c | 32 +++++++++++++++----------------
2 files changed, 23 insertions(+), 17 deletions(-)
diff --git a/fs/smb/server/mgmt/tree_connect.c b/fs/smb/server/mgmt/tree_connect.c
index c7a89eddcda7b..6d8f3ebcbc53d 100644
--- a/fs/smb/server/mgmt/tree_connect.c
+++ b/fs/smb/server/mgmt/tree_connect.c
@@ -82,6 +82,8 @@ ksmbd_tree_conn_connect(struct ksmbd_work *work, const char *share_name)
down_write(&sess->tree_conns_lock);
ret = xa_err(xa_store(&sess->tree_conns, tree_conn->id, tree_conn,
KSMBD_DEFAULT_GFP));
+ if (!ret)
+ atomic_inc(&tree_conn->refcount);
up_write(&sess->tree_conns_lock);
if (ret) {
status.ret = -ENOMEM;
@@ -122,6 +124,12 @@ int ksmbd_tree_conn_disconnect(struct ksmbd_session *sess,
struct ksmbd_tree_connect *tree_conn)
{
down_write(&sess->tree_conns_lock);
+ if (tree_conn->t_state == TREE_DISCONNECTED ||
+ xa_load(&sess->tree_conns, tree_conn->id) != tree_conn) {
+ up_write(&sess->tree_conns_lock);
+ return -ENOENT;
+ }
+ tree_conn->t_state = TREE_DISCONNECTED;
xa_erase(&sess->tree_conns, tree_conn->id);
up_write(&sess->tree_conns_lock);
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 1cbc425d7273e..40d86993dbe3d 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -2023,6 +2023,7 @@ int smb2_tree_connect(struct ksmbd_work *work)
struct ksmbd_session *sess = work->sess;
char *treename = NULL, *name = NULL;
struct ksmbd_tree_conn_status status;
+ struct ksmbd_tree_connect *tree_conn = NULL;
struct ksmbd_share_config *share = NULL;
int rc = -EINVAL;
@@ -2049,9 +2050,10 @@ int smb2_tree_connect(struct ksmbd_work *work)
name, treename);
status = ksmbd_tree_conn_connect(work, name);
- if (status.ret == KSMBD_TREE_CONN_STATUS_OK)
+ if (status.ret == KSMBD_TREE_CONN_STATUS_OK) {
+ tree_conn = status.tree_conn;
rsp->hdr.Id.SyncId.TreeId = cpu_to_le32(status.tree_conn->id);
- else
+ } else
goto out_err1;
share = status.tree_conn->share_conf;
@@ -2083,8 +2085,15 @@ int smb2_tree_connect(struct ksmbd_work *work)
status.tree_conn->posix_extensions = true;
down_write(&sess->tree_conns_lock);
- status.tree_conn->t_state = TREE_CONNECTED;
+ if (status.tree_conn->t_state == TREE_DISCONNECTED) {
+ status.ret = KSMBD_TREE_CONN_STATUS_ERROR;
+ share = NULL;
+ } else {
+ status.tree_conn->t_state = TREE_CONNECTED;
+ }
up_write(&sess->tree_conns_lock);
+ if (status.ret != KSMBD_TREE_CONN_STATUS_OK)
+ goto out_err1;
rsp->StructureSize = cpu_to_le16(16);
out_err1:
/*
@@ -2099,9 +2108,6 @@ int smb2_tree_connect(struct ksmbd_work *work)
rc = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_tree_connect_rsp));
if (rc) {
if (status.ret == KSMBD_TREE_CONN_STATUS_OK) {
- down_write(&sess->tree_conns_lock);
- status.tree_conn->t_state = TREE_DISCONNECTED;
- up_write(&sess->tree_conns_lock);
ksmbd_tree_conn_disconnect(sess, status.tree_conn);
status.tree_conn = NULL;
}
@@ -2142,6 +2148,9 @@ int smb2_tree_connect(struct ksmbd_work *work)
if (status.ret != KSMBD_TREE_CONN_STATUS_OK)
smb2_set_err_rsp(work);
+ if (tree_conn)
+ ksmbd_tree_connect_put(tree_conn);
+
return rc;
}
@@ -2245,17 +2254,6 @@ int smb2_tree_disconnect(struct ksmbd_work *work)
ksmbd_close_tree_conn_fds(work);
- down_write(&sess->tree_conns_lock);
- if (tcon->t_state == TREE_DISCONNECTED) {
- up_write(&sess->tree_conns_lock);
- rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
- err = -ENOENT;
- goto err_out;
- }
-
- tcon->t_state = TREE_DISCONNECTED;
- up_write(&sess->tree_conns_lock);
-
err = ksmbd_tree_conn_disconnect(sess, tcon);
if (err) {
rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 095/686] nfsd: shorten extack string returned with dodgy listener
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (93 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 094/686] ksmbd: fix tree connection use-after-free in smb2_tree_connect() Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 096/686] s390/vmcp: Initialize full session info to zero Greg Kroah-Hartman
` (590 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jeff Layton, Chuck Lever,
Sasha Levin
6.18-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 9ffa72c15aed2..15fb9ffc12a78 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -2188,7 +2188,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] 687+ messages in thread
* [PATCH 6.18 096/686] s390/vmcp: Initialize full session info to zero
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (94 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 095/686] nfsd: shorten extack string returned with dodgy listener Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 097/686] PCI: rcar-gen4: Limit Max_Read_Request_Size to 256 Bytes Greg Kroah-Hartman
` (589 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian Borntraeger,
Heiko Carstens, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Borntraeger <borntraeger@linux.ibm.com>
[ Upstream commit f63eb4ee4a30fc5d8de07a229d92310e3c8d560c ]
The cma_alloc bit as well as the response can contain old data.
cma_release will not free the kmalloced memory in that case and
the response code might leak kernel stack data to CAP_SYS_ADMIN
users.
Cc: stable@vger.kernel.org
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
[borntraeger@linux.ibm.com: use kzalloc instead of kzalloc_obj for older versions]
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/char/vmcp.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 69899bb86b3ef..1d07d7b6acb82 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -105,13 +105,11 @@ static int vmcp_open(struct inode *inode, struct file *file)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- session = kmalloc(sizeof(*session), GFP_KERNEL);
+ session = kzalloc(sizeof(*session), GFP_KERNEL);
if (!session)
return -ENOMEM;
session->bufsize = PAGE_SIZE;
- session->response = NULL;
- session->resp_size = 0;
mutex_init(&session->mutex);
file->private_data = session;
return nonseekable_open(inode, file);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 097/686] PCI: rcar-gen4: Limit Max_Read_Request_Size to 256 Bytes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (95 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 096/686] s390/vmcp: Initialize full session info to zero Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 098/686] wifi: mt76: mt792x: fix negative errno truncation in offload capability Greg Kroah-Hartman
` (588 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marek Vasut, Manivannan Sadhasivam,
Bjorn Helgaas, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <marek.vasut+renesas@mailbox.org>
[ Upstream commit f0a5c6bd797c2b9900034983a1118d27eb2f2f16 ]
R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
Max_Payload_Size (MPS). PCIe specification indicates that the MPS must not
exceed minimum MPS of any element along the packet path. The PCI core
already enforces this, but add a check to warn if MPS is ever set larger
than 256.
R-Car Gen4 Reference Manual, chapter 104.4.8 Usage notes for MRRS (Max Read
Request Size) states:
Please set "Max Read Request Size" to 128 bytes or 256 bytes.
If "Max Read Request Size" is set to anything other than the
above, the transferred data will not match the expected value.
This limitation also seems to apply to devices doing DMA reads, i.e.,
issuing MRd TLPs. This limitation can be triggered by using non-HMB NVMe
SSD with Max_Read_Request_Size 512 Bytes, for example Crucial P5 Plus. Any
write to the SSD (MRd TLP issued by the SSD controller) longer than 256
Bytes wraps around at the 256 Byte boundary, and the same data are written
to the SSD starting at offset 0 and at 256 Bytes.
Limit Max_Read_Request_Size to at most 256 Bytes for each device connected
to this PCIe controller to avoid this behavior.
A non-HMB (Host Memory Buffer) NVMe SSD can be identified using the
following command. Affected SSD reports 'hmpre' field as 0:
$ nvme id-ctrl /dev/nvme0 | grep hmpre
hmpre : 0
The symptom is a read from the SSD which wraps around at 256 Byte boundary.
The test for this symptom can be implemented by writing 512 Byte of random
data into the SSD and reading the data back. If the read back data repeat
after 256 Bytes, the device is affected.
$ dd if=/dev/urandom of=/tmp/data.bin bs=256 count=2 ; \
dd if=/tmp/data.bin of=/dev/nvme0n1 bs=256 count=2 ; \
dd if=/dev/nvme0n1 bs=256 count=2 of=/tmp/readback.bin
Expected data:
$ hexdump -vC /tmp/data.bin
00000000 97 81 b7 3b 0e 38 2b 4d a7 d3 e0 47 ff c2 4b ca
00000010 c1 85 98 f0 4a ac 03 a0 3b ab f3 19 44 dd 06 8b
...
00000100 7a ce 3c b2 e1 d5 d9 11 88 63 10 59 76 3c dc 32 <-- random
00000110 72 32 2a 7d a3 e1 aa 13 7c da 58 a1 7b 21 11 50 <-- data
Faulty readback, collected without this change in place:
$ hexdump -vC /tmp/readback.bin
00000000 97 81 b7 3b 0e 38 2b 4d a7 d3 e0 47 ff c2 4b ca <---.
00000010 c1 85 98 f0 4a ac 03 a0 3b ab f3 19 44 dd 06 8b <-. |
... | |
00000100 97 81 b7 3b 0e 38 2b 4d a7 d3 e0 47 ff c2 4b ca <-:-+- repeated
00000110 c1 85 98 f0 4a ac 03 a0 3b ab f3 19 44 dd 06 8b <-+--- data
^^^
|
'--- Repeat starts at offset 0x100 = 256 Bytes
Fixes: 0d0c551011df ("PCI: rcar-gen4: Add R-Car Gen4 PCIe controller support for host mode")
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
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/20260821020636.111719-1-marek.vasut+renesas@mailbox.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/controller/dwc/pcie-rcar-gen4.c | 54 +++++++++++++++++++++
1 file changed, 54 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-rcar-gen4.c b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
index 7e171526b1ded..9e5dc1009ed4e 100644
--- a/drivers/pci/controller/dwc/pcie-rcar-gen4.c
+++ b/drivers/pci/controller/dwc/pcie-rcar-gen4.c
@@ -305,6 +305,57 @@ static struct rcar_gen4_pcie *rcar_gen4_pcie_alloc(struct platform_device *pdev)
return rcar;
}
+static int rcar_gen4_pcie_enable_device(struct pci_host_bridge *bridge,
+ struct pci_dev *dev)
+{
+ /*
+ * R-Car Gen4 PCIe controller has a hardware limitation of 256 Bytes
+ * Max_Payload_Size (MPS). PCIe specification indicates that the MPS
+ * must not exceed minimum MPS of any element along the packet path.
+ * The controller reports Max_Payload_Size_Supported (MPSS) 256 Bytes
+ * for header type 0 and 128 Bytes for header type 1. The PCIe core
+ * will not allow MPS to be set higher than MPSS; warn here in case
+ * something went very wrong in the core.
+ *
+ * For details, refer to chapter "104.1.1 Features" in either of:
+ * R-Car S4 R19UH0161EJ0140 Rev.1.40 Jul. 31, 2026 or
+ * R-Car V4H R19UH0186EJ0140 Rev.1.40 Aug. 7, 2026 or
+ * R-Car V4M R19UH0217EJ0110 Rev.1.10 Jun. 30, 2026.
+ */
+ WARN_ON(pcie_get_mps(dev) > 256);
+
+ /*
+ * R-Car Gen4 Reference Manual, chapter 104.4.8 Usage notes for
+ * MRRS (Max Read Request Size) states:
+ *
+ * Please set "Max Read Request Size" to 128 bytes or 256 bytes.
+ * If "Max Read Request Size" is set to anything other than the
+ * above, the transferred data will not match the expected value.
+ *
+ * This limitation also seems to apply to devices issuing MRd TLPs.
+ * This limitation can be triggered by using non-HMB NVMe SSD with
+ * Max_Read_Request_Size 512 Bytes, for example Crucial P5 Plus.
+ * Any write into the SSD (MRd TLP issued by the SSD) longer than
+ * 256 Bytes wraps around at 256 Byte boundary, and the same data
+ * are written into the SSD starting at offset 0 and at 256 Bytes.
+ *
+ * Limit Max_Read_Request_Size to at most 256 Bytes for each
+ * device connected to this PCIe controller to avoid this behavior.
+ *
+ * For details, refer to aforementioned chapter in either of:
+ * R-Car S4 R19UH0161EJ0140 Rev.1.40 Jul. 31, 2026 or
+ * R-Car V4H R19UH0186EJ0140 Rev.1.40 Aug. 7, 2026 or
+ * R-Car V4M R19UH0217EJ0110 Rev.1.10 Jun. 30, 2026.
+ */
+ bridge->no_inc_mrrs = 1;
+ if (pcie_get_readrq(dev) > 256) {
+ pci_info(dev, "Limiting MRRS to 256 bytes\n");
+ pcie_set_readrq(dev, 256);
+ }
+
+ return 0;
+}
+
/* Host mode */
static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
{
@@ -313,6 +364,9 @@ static int rcar_gen4_pcie_host_init(struct dw_pcie_rp *pp)
int ret;
u32 val;
+ if (pp->bridge)
+ pp->bridge->enable_device = rcar_gen4_pcie_enable_device;
+
gpiod_set_value_cansleep(dw->pe_rst, 1);
ret = rcar_gen4_pcie_common_init(rcar);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 098/686] wifi: mt76: mt792x: fix negative errno truncation in offload capability
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (96 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 097/686] PCI: rcar-gen4: Limit Max_Read_Request_Size to 256 Bytes Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 099/686] hwmon: (nct6775) Add ASUS ROG STRIX X870E-H GAMING WIFI7 Greg Kroah-Hartman
` (587 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yi Cong, Felix Fietkau, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yi Cong <yicong@kylinos.cn>
[ Upstream commit d0115096429ca090a592770c7645f9553a839954 ]
Returning a negative errno as u8 turned -ENOENT into 0xfe, wrongly
enabling CNM and NAN caps. Return int and default to no caps on error.
Fixes: e8a264ccd2de ("wifi: mt76: mt7921: move init shared code in mt792x-lib module")
Cc: stable@vger.kernel.org
Signed-off-by: Yi Cong <yicong@kylinos.cn>
Link: https://patch.msgid.link/20260824021429.43761-1-cong.yi@linux.dev
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt792x_core.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
index 96c50a501c1a9..d00807075c71f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
@@ -704,7 +704,7 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)
}
EXPORT_SYMBOL_GPL(mt792x_init_wiphy);
-static u8
+static int
mt792x_get_offload_capability(struct device *dev, const char *fw_wm)
{
const struct mt76_connac2_fw_trailer *hdr;
@@ -766,13 +766,20 @@ mt792x_get_mac80211_ops(struct device *dev,
void *drv_data, u8 *fw_features)
{
struct ieee80211_ops *ops;
+ int ret;
ops = devm_kmemdup(dev, mac80211_ops, sizeof(struct ieee80211_ops),
GFP_KERNEL);
if (!ops)
return NULL;
- *fw_features = mt792x_get_offload_capability(dev, drv_data);
+ ret = mt792x_get_offload_capability(dev, drv_data);
+ if (ret < 0) {
+ dev_warn(dev, "failed to read firmware offload caps: %d\n", ret);
+ *fw_features = 0;
+ } else {
+ *fw_features = ret;
+ }
if (!(*fw_features & MT792x_FW_CAP_CNM)) {
ops->remain_on_channel = NULL;
ops->cancel_remain_on_channel = NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 099/686] hwmon: (nct6775) Add ASUS ROG STRIX X870E-H GAMING WIFI7
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (97 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 098/686] wifi: mt76: mt792x: fix negative errno truncation in offload capability Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 100/686] hwmon: (nct6775) Add ASUS X870/W480 to WMI monitoring list Greg Kroah-Hartman
` (586 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maximilian Luz, Guenter Roeck,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maximilian Luz <luzmaximilian@gmail.com>
[ Upstream commit 03897f9baf3eeea509b2c749bab435072f5e637a ]
The ASUS ROG STRIX X870E-H GAMING WIFI7 has a NCT6799D compatible chip,
which is also accessed via ACPI.
Signed-off-by: Maximilian Luz <luzmaximilian@gmail.com>
Link: https://lore.kernel.org/r/20251002184958.359744-1-luzmaximilian@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/nct6775-platform.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c
index 0b529a542b0d4..555029dfe713f 100644
--- a/drivers/hwmon/nct6775-platform.c
+++ b/drivers/hwmon/nct6775-platform.c
@@ -1404,6 +1404,7 @@ static const char * const asus_msi_boards[] = {
"ROG STRIX X670E-E GAMING WIFI",
"ROG STRIX X670E-F GAMING WIFI",
"ROG STRIX X670E-I GAMING WIFI",
+ "ROG STRIX X870E-H GAMING WIFI7",
"ROG STRIX Z590-A GAMING WIFI",
"ROG STRIX Z590-A GAMING WIFI II",
"ROG STRIX Z590-E GAMING WIFI",
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 100/686] hwmon: (nct6775) Add ASUS X870/W480 to WMI monitoring list
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (98 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 099/686] hwmon: (nct6775) Add ASUS ROG STRIX X870E-H GAMING WIFI7 Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 101/686] wifi: mac80211: queue frames while off-channel Greg Kroah-Hartman
` (585 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Denis Pauk,
Tomáš Bžatek, Theunis Scheepers, Guenter Roeck,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Denis Pauk <pauk.denis@gmail.com>
[ Upstream commit 21518579cbdeb4e86a6fffbc3d52f52bd74ab87e ]
Boards such as
* G15CE,
* PRIME X870-P WIFI,
* PRIME X870-P,
* Pro WS W480-ACE,
* ProArt X870E-CREATOR WIFI,
* ROG CROSSHAIR X870E APEX,
* ROG CROSSHAIR X870E DARK HERO,
* ROG CROSSHAIR X870E EXTREME,
* ROG CROSSHAIR X870E GLACIAL,
* ROG CROSSHAIR X870E HERO BTF,
* ROG CROSSHAIR X870E HERO,
* ROG STRIX X870-A GAMING WIFI,
* ROG STRIX X870-F GAMING WIFI,
* ROG STRIX X870-I GAMING WIFI,
* ROG STRIX X870E-E GAMING WIFI,
* ROG STRIX X870E-E GAMING WIFI7 R2,
* TUF GAMING X870-PLUS WIFI,
* TUF GAMING X870-PRO WIFI7 W NEO,
* TUF GAMING X870E-PLUS WIFI7,
* W480/SYS,
* X870 AYW GAMING WIFI W,
* X870 MAX GAMING WIFI7 W,
* X870 MAX GAMING WIFI7
have got a nct6775 chip, but by default there's no use of it because of
resource conflict with WMI method.
Add the boards to the WMI monitoring list.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=204807
Signed-off-by: Denis Pauk <pauk.denis@gmail.com>
Tested-by: Tomáš Bžatek <bugs@bzatek.net>
Tested-by: Theunis Scheepers <ptscheepers@gmail.com>
Link: https://lore.kernel.org/r/20260322131848.6261-1-pauk.denis@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/nct6775-platform.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/hwmon/nct6775-platform.c b/drivers/hwmon/nct6775-platform.c
index 555029dfe713f..1975399ac440d 100644
--- a/drivers/hwmon/nct6775-platform.c
+++ b/drivers/hwmon/nct6775-platform.c
@@ -1159,6 +1159,7 @@ static const char * const asus_wmi_boards[] = {
"Pro A520M-C",
"Pro A520M-C II",
"Pro B550M-C",
+ "Pro WS W480-ACE",
"Pro WS X570-ACE",
"ProArt B550-CREATOR",
"ProArt X570-CREATOR WIFI",
@@ -1258,6 +1259,7 @@ static const char * const asus_wmi_boards[] = {
"TUF Z390-PRO GAMING",
"TUF Z390M-PRO GAMING",
"TUF Z390M-PRO GAMING (WI-FI)",
+ "W480/SYS",
"WS Z390 PRO",
"Z490-GUNDAM (WI-FI)",
};
@@ -1270,6 +1272,7 @@ static const char * const asus_msi_boards[] = {
"EX-B760M-V5 D4",
"EX-H510M-V3",
"EX-H610M-V3 D4",
+ "G15CE",
"G15CF",
"PRIME A620M-A",
"PRIME B560-PLUS",
@@ -1320,6 +1323,8 @@ static const char * const asus_msi_boards[] = {
"PRIME X670-P",
"PRIME X670-P WIFI",
"PRIME X670E-PRO WIFI",
+ "PRIME X870-P",
+ "PRIME X870-P WIFI",
"PRIME Z590-A",
"PRIME Z590-P",
"PRIME Z590-P WIFI",
@@ -1362,11 +1367,18 @@ static const char * const asus_msi_boards[] = {
"ProArt B660-CREATOR D4",
"ProArt B760-CREATOR D4",
"ProArt X670E-CREATOR WIFI",
+ "ProArt X870E-CREATOR WIFI",
"ProArt Z690-CREATOR WIFI",
"ProArt Z790-CREATOR WIFI",
"ROG CROSSHAIR X670E EXTREME",
"ROG CROSSHAIR X670E GENE",
"ROG CROSSHAIR X670E HERO",
+ "ROG CROSSHAIR X870E APEX",
+ "ROG CROSSHAIR X870E DARK HERO",
+ "ROG CROSSHAIR X870E EXTREME",
+ "ROG CROSSHAIR X870E GLACIAL",
+ "ROG CROSSHAIR X870E HERO",
+ "ROG CROSSHAIR X870E HERO BTF",
"ROG MAXIMUS XIII APEX",
"ROG MAXIMUS XIII EXTREME",
"ROG MAXIMUS XIII EXTREME GLACIAL",
@@ -1404,6 +1416,11 @@ static const char * const asus_msi_boards[] = {
"ROG STRIX X670E-E GAMING WIFI",
"ROG STRIX X670E-F GAMING WIFI",
"ROG STRIX X670E-I GAMING WIFI",
+ "ROG STRIX X870-A GAMING WIFI",
+ "ROG STRIX X870-F GAMING WIFI",
+ "ROG STRIX X870-I GAMING WIFI",
+ "ROG STRIX X870E-E GAMING WIFI",
+ "ROG STRIX X870E-E GAMING WIFI7 R2",
"ROG STRIX X870E-H GAMING WIFI7",
"ROG STRIX Z590-A GAMING WIFI",
"ROG STRIX Z590-A GAMING WIFI II",
@@ -1451,6 +1468,9 @@ static const char * const asus_msi_boards[] = {
"TUF GAMING H770-PRO WIFI",
"TUF GAMING X670E-PLUS",
"TUF GAMING X670E-PLUS WIFI",
+ "TUF GAMING X870-PLUS WIFI",
+ "TUF GAMING X870-PRO WIFI7 W NEO",
+ "TUF GAMING X870E-PLUS WIFI7",
"TUF GAMING Z590-PLUS",
"TUF GAMING Z590-PLUS WIFI",
"TUF GAMING Z690-PLUS",
@@ -1460,6 +1480,9 @@ static const char * const asus_msi_boards[] = {
"TUF GAMING Z790-PLUS D4",
"TUF GAMING Z790-PLUS WIFI",
"TUF GAMING Z790-PLUS WIFI D4",
+ "X870 AYW GAMING WIFI W",
+ "X870 MAX GAMING WIFI7",
+ "X870 MAX GAMING WIFI7 W",
"Z590 WIFI GUNDAM EDITION",
};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 101/686] wifi: mac80211: queue frames while off-channel
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (99 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 100/686] hwmon: (nct6775) Add ASUS X870/W480 to WMI monitoring list Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 102/686] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2 Greg Kroah-Hartman
` (584 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stanislaw Gruszka, Johannes Berg,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanislaw Gruszka <stf_xl@wp.pl>
[ Upstream commit 13e51269b6656768dc595ed6025e4974f2026543 ]
Drivers without FAST_XMIT and hardware scan support currently drop TX
frames during software scanning while being off-channel. This happens
in ieee80211_tx_h_check_assoc() before frames reach internal TX queue.
Move the off-channel check to invoke_tx_handlers_late(), after
ieee80211_queue_skb(). Frames can then remain queued and be transmitted
when the interface returns on-channel. This how TX works currently when
code goes via ieee80211_xmit_fast() path.
Below is rt2x00 driver ping output example while scanning, before and
after the fix. After the fix, packets are no longer lost. Some have
increased latency, what is expected behavior.
BEFORE:
64 bytes from 192.168.0.1: icmp_seq=29 ttl=64 time=3.61 ms
64 bytes from 192.168.0.1: icmp_seq=31 ttl=64 time=3.33 ms # Missed 30
64 bytes from 192.168.0.1: icmp_seq=32 ttl=64 time=4.03 ms
64 bytes from 192.168.0.1: icmp_seq=34 ttl=64 time=3.10 ms # Missed 33
64 bytes from 192.168.0.1: icmp_seq=36 ttl=64 time=3.04 ms # Missed 35
64 bytes from 192.168.0.1: icmp_seq=38 ttl=64 time=3.05 ms # Missed 37
64 bytes from 192.168.0.1: icmp_seq=40 ttl=64 time=4.14 ms # Missed 39
64 bytes from 192.168.0.1: icmp_seq=41 ttl=64 time=4.50 ms
AFTER:
64 bytes from 192.168.0.1: icmp_seq=29 ttl=64 time=3.40 ms
64 bytes from 192.168.0.1: icmp_seq=30 ttl=64 time=6.10 ms
64 bytes from 192.168.0.1: icmp_seq=31 ttl=64 time=4.69 ms
64 bytes from 192.168.0.1: icmp_seq=32 ttl=64 time=4.49 ms
64 bytes from 192.168.0.1: icmp_seq=33 ttl=64 time=148 ms
64 bytes from 192.168.0.1: icmp_seq=34 ttl=64 time=6.83 ms
64 bytes from 192.168.0.1: icmp_seq=35 ttl=64 time=8.66 ms
64 bytes from 192.168.0.1: icmp_seq=36 ttl=64 time=13.0 ms
64 bytes from 192.168.0.1: icmp_seq=37 ttl=64 time=4.78 ms
64 bytes from 192.168.0.1: icmp_seq=38 ttl=64 time=3.85 ms
Cc: <stable@vger.kernel.org>
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Link: https://patch.msgid.link/20260908124651.2995-1-stf_xl@wp.pl
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Stanislaw Gruszka <stf_xl@wp.pl>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mac80211/tx.c | 55 ++++++++++++++++++++++++-----------------------
1 file changed, 28 insertions(+), 27 deletions(-)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 63867702ab08a..b012451f45253 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -269,7 +269,6 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
static ieee80211_tx_result debug_noinline
ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
{
-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
bool assoc = false;
@@ -277,23 +276,6 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
return TX_CONTINUE;
- if (unlikely(test_bit(SCAN_SW_SCANNING, &tx->local->scanning)) &&
- test_bit(SDATA_STATE_OFFCHANNEL, &tx->sdata->state) &&
- !ieee80211_is_probe_req(hdr->frame_control) &&
- !ieee80211_is_any_nullfunc(hdr->frame_control))
- /*
- * When software scanning only nullfunc frames (to notify
- * the sleep state to the AP) and probe requests (for the
- * active scan) are allowed, all other frames should not be
- * sent and we should not get here, but if we do
- * nonetheless, drop them to avoid sending them
- * off-channel. See the link below and
- * ieee80211_start_scan() for more.
- *
- * http://article.gmane.org/gmane.linux.kernel.wireless.general/30089
- */
- return TX_DROP;
-
if (tx->sdata->vif.type == NL80211_IFTYPE_OCB)
return TX_CONTINUE;
@@ -806,6 +788,33 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
return TX_CONTINUE;
}
+static ieee80211_tx_result debug_noinline
+ieee80211_tx_h_check_offchannel(struct ieee80211_tx_data *tx)
+{
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
+
+ if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
+ return TX_CONTINUE;
+
+ if (unlikely(test_bit(SCAN_SW_SCANNING, &tx->local->scanning)) &&
+ test_bit(SDATA_STATE_OFFCHANNEL, &tx->sdata->state) &&
+ !ieee80211_is_probe_req(hdr->frame_control) &&
+ !ieee80211_is_any_nullfunc(hdr->frame_control)) {
+ /*
+ * When software scanning only nullfunc frames (to notify
+ * the sleep state to the AP) and probe requests (for the
+ * active scan) are allowed, all other frames should not be
+ * sent and we should not get here, but if we do
+ * nonetheless, drop them to avoid sending them
+ * off-channel. See __ieee80211_start_scan() for more.
+ */
+ return TX_DROP;
+ }
+
+ return TX_CONTINUE;
+}
+
static __le16 ieee80211_tx_next_seq(struct sta_info *sta, int tid)
{
u16 *seq = &sta->tid_seq[tid];
@@ -1852,6 +1861,7 @@ static int invoke_tx_handlers_late(struct ieee80211_tx_data *tx)
goto txh_done;
}
+ CALL_TXH(ieee80211_tx_h_check_offchannel);
CALL_TXH(ieee80211_tx_h_michael_mic_add);
CALL_TXH(ieee80211_tx_h_sequence);
CALL_TXH(ieee80211_tx_h_fragment);
@@ -4691,10 +4701,6 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
queue = ieee80211_select_queue(sdata, sta, skb);
skb_set_queue_mapping(skb, queue);
- if (unlikely(test_bit(SCAN_SW_SCANNING, &local->scanning)) &&
- test_bit(SDATA_STATE_OFFCHANNEL, &sdata->state))
- goto out_free;
-
skb = skb_share_check(skb, GFP_ATOMIC);
if (unlikely(!skb))
return;
@@ -4771,11 +4777,6 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata,
ieee80211_tpt_led_trig_tx(local, len);
ieee80211_tx_8023(sdata, skb, sta, false);
-
- return;
-
-out_free:
- kfree_skb(skb);
}
static bool ieee80211_check_mcast_offload(struct ieee80211_sub_if_data *sdata,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 102/686] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (100 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 101/686] wifi: mac80211: queue frames while off-channel Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 103/686] media: uvcvideo: Force UVC version for Avermedia GC515 Greg Kroah-Hartman
` (583 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Baggaley, Ricardo Ribalda,
Hans de Goede, Laurent Pinchart, Hans Verkuil, Sasha Levin
6.18-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 aa3e8d295e0f5..c15e73f419101 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2847,6 +2847,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] 687+ messages in thread
* [PATCH 6.18 103/686] media: uvcvideo: Force UVC version for Avermedia GC515
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (101 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 102/686] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2 Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 104/686] mkiss: size the frame buffers for worst-case KISS escaping Greg Kroah-Hartman
` (582 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Edwin Gatier, Laurent Pinchart,
Hans de Goede, Ricardo Ribalda, Hans Verkuil, Sasha Levin
6.18-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 c15e73f419101..511912074ba09 100644
--- a/drivers/media/usb/uvc/uvc_driver.c
+++ b/drivers/media/usb/uvc/uvc_driver.c
@@ -2847,6 +2847,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] 687+ messages in thread
* [PATCH 6.18 104/686] mkiss: size the frame buffers for worst-case KISS escaping
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (102 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 103/686] media: uvcvideo: Force UVC version for Avermedia GC515 Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 105/686] mkiss: dont use a tty write error as a byte count Greg Kroah-Hartman
` (581 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
ax_encaps() accepts a frame for transmission as long as it is not
longer than dev->mtu + 73 bytes, and KISS escaping can double every
byte of it (END and ESC are each sent as two bytes). The transmit
buffer, however, is only max(2 * dev->mtu, 1152) + 4 bytes long, so the
73 bytes of header allowance are not covered once they are doubled.
With the default MTU of 236 the 1152 byte floor hides the problem. As
soon as the MTU is raised above 502, a maximum length frame made of END
or ESC bytes makes kiss_esc() or kiss_esc_crc() write up to 148 bytes
past the end of xbuff. The content of the frame does not have to come
from the local machine: it can be traffic forwarded for another
station, a routed IP datagram for instance.
Reproduced under KASAN on 6.12.94 with the MTU set to 1024 and a
1097 byte UI frame whose payload is all 0xC0:
BUG: KASAN: slab-out-of-bounds in kiss_esc+0x316/0x390 [mkiss]
Write of size 1 at addr ffff888001c9c804 by task init/1
kiss_esc+0x316/0x390 [mkiss]
ax_xmit+0x346/0xcd5 [mkiss]
dev_hard_start_xmit+0xf8/0x580
sch_direct_xmit+0x131/0xa10
__dev_queue_xmit+0x27f6/0x34b0
packet_sendmsg+0x30c5/0x4a10
The buggy address is located 0 bytes to the right of
allocated 2052-byte region [ffff888001c9c000, ffff888001c9c804)
In addition the driver sets no upper bound on the MTU. An MTU of 2^30
or more makes "dev->mtu * 2" negative, which leaves the buffers at
their minimum size while the length check in ax_encaps() no longer
rejects anything.
Compute the buffer length in one place, from the largest frame that
ax_encaps() accepts, and allocate six more bytes for the two END
delimiters and the two CRC bytes, which may need escaping too. Set
max_mtu so that the computation cannot overflow.
With the change the same test produces no KASAN report, the frames
found on the serial line are identical to those sent, with and without
CRC (SMACK and FlexNet), and an MTU above 65535 is refused.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 1d80a1c3a4591b20182a8adb3bcb0427f85331a5)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/hamradio/mkiss.c | 49 ++++++++++++++++++++++--------------
1 file changed, 30 insertions(+), 19 deletions(-)
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 5f38a002bd9e3..05c7a234de6ca 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -30,6 +30,7 @@
#include <net/ax25.h>
#define AX_MTU 236
+#define AX_MAX_MTU 65535
/* some arch define END as assembly function ending, just undef it */
#undef END
@@ -355,13 +356,19 @@ static int ax_set_mac_address(struct net_device *dev, void *addr)
/*---------------------------------------------------------------------------*/
-static void ax_changedmtu(struct mkiss *ax)
-{
- struct net_device *dev = ax->dev;
- unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
- int len;
+/*
+ * Length of the frame buffers for the current MTU.
+ *
+ * ax_encaps() accepts frames of up to dev->mtu + 73 bytes and KISS escaping
+ * can double every one of them. The buffers are allocated AX_BUF_SLACK bytes
+ * larger than this, for the two END delimiters and the two CRC bytes, which
+ * can need escaping as well.
+ */
+#define AX_BUF_SLACK 6
- len = dev->mtu * 2;
+static int ax_buflen(const struct net_device *dev)
+{
+ int len = (dev->mtu + 73) * 2;
/*
* allow for arrival of larger UDP packets, even if we say not to
@@ -371,8 +378,19 @@ static void ax_changedmtu(struct mkiss *ax)
if (len < 576 * 2)
len = 576 * 2;
- xbuff = kmalloc(len + 4, GFP_ATOMIC);
- rbuff = kmalloc(len + 4, GFP_ATOMIC);
+ return len;
+}
+
+static void ax_changedmtu(struct mkiss *ax)
+{
+ struct net_device *dev = ax->dev;
+ unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
+ int len;
+
+ len = ax_buflen(dev);
+
+ xbuff = kmalloc(len + AX_BUF_SLACK, GFP_ATOMIC);
+ rbuff = kmalloc(len + AX_BUF_SLACK, GFP_ATOMIC);
if (xbuff == NULL || rbuff == NULL) {
printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, "
@@ -581,20 +599,12 @@ static int ax_open(struct net_device *dev)
* rbuff Receive buffer.
* xbuff Transmit buffer.
*/
- len = dev->mtu * 2;
-
- /*
- * allow for arrival of larger UDP packets, even if we say not to
- * also fixes a bug in which SunOS sends 512-byte packets even with
- * an MSS of 128
- */
- if (len < 576 * 2)
- len = 576 * 2;
+ len = ax_buflen(dev);
- if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
+ if ((ax->rbuff = kmalloc(len + AX_BUF_SLACK, GFP_KERNEL)) == NULL)
goto norbuff;
- if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
+ if ((ax->xbuff = kmalloc(len + AX_BUF_SLACK, GFP_KERNEL)) == NULL)
goto noxbuff;
ax->mtu = dev->mtu + 73;
@@ -640,6 +650,7 @@ static void ax_setup(struct net_device *dev)
{
/* Finish setting up the DEVICE info. */
dev->mtu = AX_MTU;
+ dev->max_mtu = AX_MAX_MTU;
dev->hard_header_len = AX25_MAX_HEADER_LEN;
dev->addr_len = AX25_ADDR_LEN;
dev->type = ARPHRD_AX25;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 105/686] mkiss: dont use a tty write error as a byte count
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (103 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 104/686] mkiss: size the frame buffers for worst-case KISS escaping Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 106/686] bpqether: leave the Ethernet devices queue and counters alone Greg Kroah-Hartman
` (580 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
ax_encaps() and mkiss_write_wakeup() take whatever tty->ops->write()
returns as the number of bytes accepted by the tty. Some tty drivers
return a negative errno instead, USB serial adapters for instance when
the device is gone or the URB cannot be submitted.
A negative value moves ax->xhead to before the start of xbuff and
makes ax->xleft larger than the frame, so the next write wakeup sends
memory that does not belong to the transmit buffer down the line. It is
also added to the tx_bytes counter.
Treat a negative return as a transmit error: count it in tx_errors,
drop what is left of the frame and restart the queue, as is already
done for an oversized frame.
This path could not be exercised on the test bench, where neither the
8250 driver nor a pty ever returns an error from write(). The change
was compile tested and checked for regressions only: 46 frames out of
46 are still sent unchanged.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit eb6e59f373ad5fa6646a3e836a887830addd0687)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/hamradio/mkiss.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 05c7a234de6ca..f11019d155764 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -526,6 +526,14 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
actual = ax->tty->ops->write(ax->tty, ax->xbuff, count);
+ if (actual < 0) {
+ /* The tty refused the frame: drop it. */
+ clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
+ dev->stats.tx_errors++;
+ ax->xleft = 0;
+ netif_start_queue(dev);
+ return;
+ }
dev->stats.tx_packets++;
dev->stats.tx_bytes += actual;
@@ -939,6 +947,14 @@ static void mkiss_write_wakeup(struct tty_struct *tty)
}
actual = tty->ops->write(tty, ax->xhead, ax->xleft);
+ if (actual < 0) {
+ /* Give up on the rest of this frame. */
+ clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+ ax->dev->stats.tx_errors++;
+ ax->xleft = 0;
+ netif_wake_queue(ax->dev);
+ goto out;
+ }
ax->xleft -= actual;
ax->xhead += actual;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 106/686] bpqether: leave the Ethernet devices queue and counters alone
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (104 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 105/686] mkiss: dont use a tty write error as a byte count Greg Kroah-Hartman
@ 2026-11-13 15:43 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 107/686] bpqether: fix truncated /proc/net/bpqether on partial reads Greg Kroah-Hartman
` (579 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:43 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
bpq_xmit() replaces its "dev" argument with the underlying Ethernet
device before it builds the Ethernet header. The three statements that
follow were written for the bpq device but now act on the Ethernet one:
- tx_packets and tx_bytes are added to the Ethernet device's
statistics, so the bpq device never counts a transmitted frame;
- netif_wake_queue() restarts the transmit queue of the Ethernet
device. If its driver had stopped that queue because its transmit
ring is full, bpqether overrides the driver's flow control.
Count the frame on the bpq device, which is still at hand in orig_dev,
and drop the netif_wake_queue() call. The bpq device does not stop its
own queue outside of ndo_stop, so there is nothing to wake.
Tested in a QEMU guest (6.12.94, KASAN and lockdep) with two e1000
ports on the same hub, bpq0 on the first and bpq1 on the second. After
40 UI frames bpq0 reported tx_packets=0 before the change and 40 after.
With the transmit queue of eth0 stopped by a small helper module, a
frame sent on bpq0 restarted that queue before the change and leaves it
stopped after; the frame goes out once the queue is woken. In both
cases the 40 frames are received unchanged on bpq1.
Fixes: f57505fd7ce5 ("bpqether: convert to internal net_device_stats")
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 568cfa4507c2ef88099acd6cf88fdf76f7cef8d4)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/hamradio/bpqether.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 045c5177262ea..209dddef51d06 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -267,11 +267,10 @@ static netdev_tx_t bpq_xmit(struct sk_buff *skb, struct net_device *dev)
skb->protocol = ax25_type_trans(skb, dev);
skb_reset_network_header(skb);
dev_hard_header(skb, dev, ETH_P_BPQ, bpq->dest_addr, NULL, 0);
- dev->stats.tx_packets++;
- dev->stats.tx_bytes+=skb->len;
-
+ orig_dev->stats.tx_packets++;
+ orig_dev->stats.tx_bytes += skb->len;
+
dev_queue_xmit(skb);
- netif_wake_queue(dev);
return NETDEV_TX_OK;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 107/686] bpqether: fix truncated /proc/net/bpqether on partial reads
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (105 preceding siblings ...)
2026-11-13 15:43 ` [PATCH 6.18 106/686] bpqether: leave the Ethernet devices queue and counters alone Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 108/686] rose: arm the neighbour timers with mod_timer() Greg Kroah-Hartman
` (578 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
bpq_seq_start() walks the device list to find the entry at *pos, but
never increments its counter. It returns the first device when *pos is
1 and NULL for any larger value.
The seq_file core calls ->start() with the saved position each time a
read() needs more data, so the listing stops after the first device as
soon as it is not produced in a single pass: when it is read with a
small buffer, or when it is longer than a page.
With five bpq devices, reading the file 64 bytes at a time returned
the header and one device before the change, and all five devices
after.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 0a529c12d374e1dc74c2360e7ca13ab4e594a445)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/hamradio/bpqether.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 209dddef51d06..f30616d915fd3 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -366,6 +366,7 @@ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
if (i == *pos)
return bpqdev;
+ i++;
}
return NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 108/686] rose: arm the neighbour timers with mod_timer()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (106 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 107/686] bpqether: fix truncated /proc/net/bpqether on partial reads Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 109/686] netrom: ignore a BPQ transport timeout below the sysctl minimum Greg Kroah-Hartman
` (577 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
rose_start_t0timer() and rose_start_ftimer() restart a neighbour timer
in two steps: timer_delete(), then a rewrite of .function and .expires
followed by add_timer(). Nothing serialises these calls. Two sockets
using the same neighbour can reach rose_transmit_link() at the same
time on two CPUs, for instance rose_connect() in process context and
rose_route_frame() in softirq context, or a connect racing the
self-rearm at the end of rose_t0timer_expiry(). Both see the timer
idle, both call timer_delete(), and the second add_timer() finds the
timer already pending:
WARNING: CPU: 1 PID: 11465 at kernel/time/timer.c:1294 add_timer+0x60/0x90
rose_write_internal+0x3ab/0x15b0 [rose]
rose_connect+0x60f/0x1320 [rose]
With panic_on_warn this takes the machine down.
Set the expiry functions once, when the neighbour is created, and
start the timers with a single mod_timer() call, which updates a
pending timer or arms an idle one atomically.
This also stops rewriting .function on every start, so a start
that would come after timer_shutdown_sync() in rose_neigh_put() is
ignored, as that function's comment expects, instead of bringing the
timer back.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 41748d2730f1eb6b85fb957581d7ffb6dfe39859)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/rose.h | 1 +
net/rose/rose_link.c | 24 ++++++++++--------------
net/rose/rose_route.c | 6 ++----
3 files changed, 13 insertions(+), 18 deletions(-)
diff --git a/include/net/rose.h b/include/net/rose.h
index 2fa0331e36f09..83d6b611eb735 100644
--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -231,6 +231,7 @@ int rose_rcv_frame(struct sock *sk, struct sk_buff *skb);
int rose_backlog_rcv(struct sock *sk, struct sk_buff *skb);
/* rose_link.c */
+void rose_neigh_init_timers(struct rose_neigh *neigh);
void rose_start_ftimer(struct rose_neigh *);
void rose_stop_ftimer(struct rose_neigh *);
void rose_stop_t0timer(struct rose_neigh *);
diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
index 1fe48d58726f5..49a45936eb2bd 100644
--- a/net/rose/rose_link.c
+++ b/net/rose/rose_link.c
@@ -30,26 +30,22 @@ static void rose_t0timer_expiry(struct timer_list *);
static void rose_transmit_restart_confirmation(struct rose_neigh *neigh);
static void rose_transmit_restart_request(struct rose_neigh *neigh);
-void rose_start_ftimer(struct rose_neigh *neigh)
+void rose_neigh_init_timers(struct rose_neigh *neigh)
{
- timer_delete(&neigh->ftimer);
-
- neigh->ftimer.function = rose_ftimer_expiry;
- neigh->ftimer.expires =
- jiffies + msecs_to_jiffies(sysctl_rose_link_fail_timeout);
+ timer_setup(&neigh->ftimer, rose_ftimer_expiry, 0);
+ timer_setup(&neigh->t0timer, rose_t0timer_expiry, 0);
+}
- add_timer(&neigh->ftimer);
+void rose_start_ftimer(struct rose_neigh *neigh)
+{
+ mod_timer(&neigh->ftimer,
+ jiffies + msecs_to_jiffies(sysctl_rose_link_fail_timeout));
}
static void rose_start_t0timer(struct rose_neigh *neigh)
{
- timer_delete(&neigh->t0timer);
-
- neigh->t0timer.function = rose_t0timer_expiry;
- neigh->t0timer.expires =
- jiffies + msecs_to_jiffies(sysctl_rose_restart_request_timeout);
-
- add_timer(&neigh->t0timer);
+ mod_timer(&neigh->t0timer,
+ jiffies + msecs_to_jiffies(sysctl_rose_restart_request_timeout));
}
void rose_stop_ftimer(struct rose_neigh *neigh)
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 6a1de0055e28b..3499f034b83c6 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -102,8 +102,7 @@ static int __must_check rose_add_node(struct rose_route_struct *rose_route,
skb_queue_head_init(&rose_neigh->queue);
- timer_setup(&rose_neigh->ftimer, NULL, 0);
- timer_setup(&rose_neigh->t0timer, NULL, 0);
+ rose_neigh_init_timers(rose_neigh);
if (rose_route->ndigis != 0) {
rose_neigh->digipeat =
@@ -446,8 +445,7 @@ void rose_add_loopback_neigh(void)
skb_queue_head_init(&sn->queue);
- timer_setup(&sn->ftimer, NULL, 0);
- timer_setup(&sn->t0timer, NULL, 0);
+ rose_neigh_init_timers(sn);
spin_lock_bh(&rose_neigh_list_lock);
sn->next = rose_neigh_list;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 109/686] netrom: ignore a BPQ transport timeout below the sysctl minimum
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (107 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 108/686] rose: arm the neighbour timers with mod_timer() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 110/686] rose: dont give the same LCI to two calls placed at the same time Greg Kroah-Hartman
` (576 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
A connect request carrying the BPQ extension (37 bytes) ends with the
transport timeout the caller proposes, in seconds. nr_rx_frame()
takes it as the new circuit's T1 whenever it is smaller than the
current one, with no lower bound. A proposal of 0 leaves T1 at 0:
the first unacknowledged information frame is sent N2 times within
a few jiffies and the circuit is torn down with ETIMEDOUT. Values
of a few seconds are not much better on a slow radio link. The
transport_timeout sysctl refuses anything below 5 seconds, and
setsockopt(NETROM_T1) anything below 1 second, but a remote node can
set what the local administrator cannot.
Ignore proposals below 5 seconds and keep the local T1 in that case.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit ecf309417afbdcff7986ef8ec16c86dadcd5530c)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/af_netrom.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index c9433b1a28721..6de086082f71b 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1027,10 +1027,13 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
if (window < nr_make->window)
nr_make->window = window;
- /* L4 timeout negotiation */
+ /*
+ * L4 timeout negotiation. Ignore a proposal shorter than the
+ * smallest transport timeout the sysctl accepts (5 s), such as 0.
+ */
if (skb->len == 37) {
timeout = skb->data[36] * 256 + skb->data[35];
- if (timeout * HZ < nr_make->t1)
+ if (timeout >= 5 && timeout * HZ < nr_make->t1)
nr_make->t1 = timeout * HZ;
nr_make->bpqext = 1;
} else {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 110/686] rose: dont give the same LCI to two calls placed at the same time
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (108 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 109/686] netrom: ignore a BPQ transport timeout below the sysctl minimum Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 111/686] ax25: dont create a second connection for a link on an incoming SABM Greg Kroah-Hartman
` (575 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
rose_connect() picks the logical channel of a new call with
rose_new_lci(), which looks for an LCI used neither by a socket nor by
a through route on the neighbour, and stores the result in rose->lci
afterwards. Nothing serialises the search and the store, so two
sockets calling through the same neighbour on two CPUs can pick the
same LCI. An unbound socket is worse: it is only put on the socket
list by the autobind after its LCI was chosen, so it stays invisible
to the search for longer. Both calls go out on the same channel, the
neighbour accepts one of them, and the other connect() hangs until T1
expires while the neighbour holds a circuit nobody uses.
rose_new_lci() also walks rose_route_list through
rose_route_free_lci() without rose_route_list_lock when called from
rose_connect(), while rose_route_frame() may add or remove routes on
another CPU.
Do the autobind first, so the socket is on the list before it gets an
LCI, then choose and store the LCI under rose_route_list_lock, as
rose_route_frame() already does for a through route. Assert the lock
in rose_route_free_lci().
On a QEMU bench with two 4-CPU guests, eight connect() calls started at
the same time through one neighbour, six rounds: before, 14 duplicate
LCIs and 14 of the 48 calls timed out; after, no duplicate and 48/48
calls connected.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 4e9d49c39bf7161e1b14493076816c715f9ed557)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/rose.h | 1 +
net/rose/af_rose.c | 32 ++++++++++++++++----------------
net/rose/rose_route.c | 19 +++++++++++++++++++
3 files changed, 36 insertions(+), 16 deletions(-)
diff --git a/include/net/rose.h b/include/net/rose.h
index 83d6b611eb735..7ee480e0a64e7 100644
--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -267,6 +267,7 @@ void rose_link_device_down(struct net_device *);
struct net_device *rose_dev_first(void);
struct net_device *rose_dev_get(rose_address *);
struct rose_route *rose_route_free_lci(unsigned int, struct rose_neigh *);
+unsigned int rose_assign_lci(struct sock *sk);
struct rose_neigh *rose_get_neigh(rose_address *, unsigned char *,
unsigned char *, int);
int rose_rt_ioctl(unsigned int, void __user *);
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 4912138bb2f69..614d033410fa3 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -330,6 +330,7 @@ struct sock *rose_find_socket(unsigned int lci, struct rose_neigh *neigh)
/*
* Find a unique LCI for a given device.
+ * The caller holds rose_route_list_lock.
*/
unsigned int rose_new_lci(struct rose_neigh *neigh)
{
@@ -854,20 +855,6 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
- rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause,
- &diagnostic, 0);
- if (!rose->neighbour) {
- err = -ENETUNREACH;
- goto out_release;
- }
-
- rose->lci = rose_new_lci(rose->neighbour);
- if (!rose->lci) {
- err = -ENETUNREACH;
- rose_neigh_put(rose->neighbour);
- goto out_release;
- }
-
if (sock_flag(sk, SOCK_ZAPPED)) { /* Must bind first - autobinding in this may or may not work */
struct net_device *dev;
@@ -876,14 +863,12 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
dev = rose_dev_first();
if (!dev) {
err = -ENETUNREACH;
- rose_neigh_put(rose->neighbour);
goto out_release;
}
user = ax25_findbyuid(current_euid());
if (!user) {
err = -EINVAL;
- rose_neigh_put(rose->neighbour);
dev_put(dev);
goto out_release;
}
@@ -897,6 +882,21 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le
rose_insert_socket(sk); /* Finish the bind */
}
+
+ rose->neighbour = rose_get_neigh(&addr->srose_addr, &cause,
+ &diagnostic, 0);
+ if (!rose->neighbour) {
+ err = -ENETUNREACH;
+ goto out_release;
+ }
+
+ /* The socket is on the list now, so others see the LCI it gets */
+ if (!rose_assign_lci(sk)) {
+ err = -ENETUNREACH;
+ rose_neigh_put(rose->neighbour);
+ goto out_release;
+ }
+
rose->dest_addr = addr->srose_addr;
rose->dest_call = addr->srose_call;
rose->rand = ((long)rose & 0xFFFF) + rose->lci;
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 3499f034b83c6..87a33f5c65d8a 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -724,6 +724,8 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig
{
struct rose_route *rose_route;
+ lockdep_assert_held(&rose_route_list_lock);
+
for (rose_route = rose_route_list; rose_route != NULL; rose_route = rose_route->next)
if ((rose_route->neigh1 == neigh && rose_route->lci1 == lci) ||
(rose_route->neigh2 == neigh && rose_route->lci2 == lci))
@@ -732,6 +734,23 @@ struct rose_route *rose_route_free_lci(unsigned int lci, struct rose_neigh *neig
return NULL;
}
+/*
+ * Give a socket placing a call a free LCI on its neighbour. As for a
+ * through route in rose_route_frame(), the search and the assignment
+ * are done under rose_route_list_lock, so two calls cannot pick the
+ * same LCI. The socket must already be on the socket list.
+ */
+unsigned int rose_assign_lci(struct sock *sk)
+{
+ struct rose_sock *rose = rose_sk(sk);
+
+ spin_lock_bh(&rose_route_list_lock);
+ rose->lci = rose_new_lci(rose->neighbour);
+ spin_unlock_bh(&rose_route_list_lock);
+
+ return rose->lci;
+}
+
/*
* Find a neighbour or a route given a ROSE address.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 111/686] ax25: dont create a second connection for a link on an incoming SABM
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (109 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 110/686] rose: dont give the same LCI to two calls placed at the same time Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 112/686] ax25: free a closed socket when its device goes down Greg Kroah-Hartman
` (574 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
When a SABM arrives for one of our interfaces and no socket listens,
ax25_rcv() looks the link up with ax25_find_cb(), creates a control
block if there is none, and adds it with ax25_cb_add() at the end.
The lookup and the add are not done under one lock. If
ax25_send_frame() opens the same link on another CPU in between, for
instance a ROSE restart request or a NetRom frame for that neighbour,
both control blocks end up on ax25_list. The one created by
ax25_send_frame() stays in state 1 with the frames queued on it and
never reaches state 3, as the peer's UA and its later frames go to
the other one.
ax25_send_frame() already adds its control block with
ax25_cb_add_unique() for the same reason. Do the same here before
the UA is sent: if a connection for the link exists by then, drop the
new control block and give the SABM to the existing one, which
answers it from state 1 like a SABM received after the lookup.
ax25_send_frame() may find the new control block before it reaches
state 3 and only queue its frames, so kick the queue once the
connection is up.
The listener path is left alone: the new socket is on the listener's
accept queue by then and the race needs a socket connecting from the
listening address.
On a QEMU bench with a delay widening the window between the lookup
and the add, an incoming SABM crossing a ROSE call to the same
neighbour left two connections for the link in 5 rounds out of 6
before, and one connection in state 3 in every round after.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit b87e40ffda58b9077925fd8170d912b868992733)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/ax25_in.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index 1bcb5e321467d..cb48a479ba3cc 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -201,7 +201,7 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
int type = 0, mine = 0, dama;
struct sock *make, *sk;
ax25_digi dp, reverse_dp;
- ax25_cb *ax25;
+ ax25_cb *ax25, *existing;
ax25_dev *ax25_dev;
/*
@@ -450,6 +450,24 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
ax25->window = ax25_dev->values[AX25_VALUES_WINDOW];
}
+ if (!sk) {
+ /*
+ * ax25_send_frame() may have created a connection for this
+ * link since the lookup above: add ours only if there is
+ * none, otherwise give the SABM to the existing one. Frames
+ * queued on ours before it reaches state 3 are sent by the
+ * ax25_kick() below.
+ */
+ existing = ax25_cb_add_unique(ax25);
+ if (existing) {
+ ax25_cb_put(ax25);
+ if (ax25_process_rx_frame(existing, skb, type, dama) == 0)
+ kfree_skb(skb);
+ ax25_cb_put(existing);
+ return 0;
+ }
+ }
+
ax25_send_control(ax25, AX25_UA, AX25_POLLON, AX25_RESPONSE);
#ifdef CONFIG_AX25_DAMA_SLAVE
@@ -459,12 +477,16 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
ax25->state = AX25_STATE_3;
- ax25_cb_add(ax25);
+ if (sk)
+ ax25_cb_add(ax25);
ax25_start_heartbeat(ax25);
ax25_start_t3timer(ax25);
ax25_start_idletimer(ax25);
+ if (!sk)
+ ax25_kick(ax25);
+
if (sk) {
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_data_ready(sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 112/686] ax25: free a closed socket when its device goes down
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (110 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 111/686] ax25: dont create a second connection for a link on an incoming SABM Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 113/686] mkiss: restart the transmit queue when the interface is opened Greg Kroah-Hartman
` (573 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
A SOCK_SEQPACKET socket closed by its owner is marked SOCK_DESTROY and
left to its heartbeat, which calls ax25_destroy_socket() once the link
is down. A connection that a listener never accepted gets the same
treatment when the listener is closed (TCP_LISTEN and SOCK_DEAD).
Neither socket has a struct socket left, so nothing else frees it.
If the device goes away during that time, ax25_kill_by_device() calls
ax25_disconnect() with ENETUNREACH, which since commit fc6d01ff9ef0
("ax25: Fix NULL pointer dereferences in ax25 timers") stops the
heartbeat with timer_delete_sync() whatever the socket state, and then
takes the control block off the list. The socket is never freed and
keeps a reference on the ax25 module, so ax25 can no longer be unloaded.
This shows up on a node that closes a connection and restarts
kissattach, or unloads bpqether, within the few seconds the heartbeat
needs: each such connection adds one to the ax25 module refcount for
good.
Free those sockets in ax25_kill_by_device() with ax25_destroy_socket(),
under the same condition the heartbeat uses.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link): three client connections closed and ax0 removed
one second later, then a connection left unaccepted by a closed
listener and ax0 removed one second later. ax25 refcount after each:
before after
3 closed clients +3 0
unaccepted connection +1 0
control (ax0 removed 0 0
25 s after close)
Same result over five runs, with no KASAN or lockdep report. Also seen
on two live nodes over bpqether, where ax25 could no longer be
reloaded until a reboot.
Fixes: fc6d01ff9ef0 ("ax25: Fix NULL pointer dereferences in ax25 timers")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 2e9cb81885fefea3690a9b94b9ff5ebf761bea73)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 5ce59d1ba8221..63fe99746d328 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -78,6 +78,7 @@ static void ax25_kill_by_device(struct net_device *dev)
ax25_dev *ax25_dev;
ax25_cb *s;
struct sock *sk;
+ bool orphan;
if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
return;
@@ -109,6 +110,16 @@ static void ax25_kill_by_device(struct net_device *dev)
sock_hold(sk);
spin_unlock_bh(&ax25_list_lock);
lock_sock(sk);
+ /*
+ * A socket closed by its owner, or a connection left
+ * unaccepted by a closed listener, is freed by its
+ * heartbeat once it is down. ax25_disconnect() below
+ * stops that heartbeat for good, so free the socket
+ * here, or it is never freed and pins the module.
+ */
+ orphan = sock_flag(sk, SOCK_DESTROY) ||
+ (sk->sk_state == TCP_LISTEN &&
+ sock_flag(sk, SOCK_DEAD));
ax25_disconnect(s, ENETUNREACH);
WRITE_ONCE(s->ax25_dev, NULL);
if (sk->sk_socket) {
@@ -116,7 +127,10 @@ static void ax25_kill_by_device(struct net_device *dev)
&s->dev_tracker);
ax25_dev_put(ax25_dev);
}
- ax25_cb_del(s);
+ if (orphan)
+ ax25_destroy_socket(s);
+ else
+ ax25_cb_del(s);
release_sock(sk);
spin_lock_bh(&ax25_list_lock);
sock_put(sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 113/686] mkiss: restart the transmit queue when the interface is opened
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (111 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 112/686] ax25: free a closed socket when its device goes down Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 114/686] 6pack: " Greg Kroah-Hartman
` (572 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
ax_close() stops the transmit queue, but ax_open_dev() never starts it
again, and the core does not do it either. After "ip link set ax0 down"
followed by "ip link set ax0 up" the queue stays stopped: the qdisc
never calls ax_xmit() any more, so the 20 s transmit timeout recovery
in ax_xmit() is never reached, and mkiss_write_wakeup() cannot wake the
queue because ax_close() cleared TTY_DO_WRITE_WAKEUP. The interface is
up but does not transmit a single frame until the line discipline is
detached and attached again.
Start the queue in ax_open_dev(), as network drivers do in ndo_open.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 76c8761457861c18de2d32607e5c7b19c49326ca)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/hamradio/mkiss.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index f11019d155764..8b0e2ca5d0ea3 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -589,6 +589,11 @@ static int ax_open_dev(struct net_device *dev)
if (ax->tty == NULL)
return -ENODEV;
+ /* ax_close() stopped the queue: restart it, or the interface
+ * never transmits again after it is set down and up.
+ */
+ netif_start_queue(dev);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 114/686] 6pack: restart the transmit queue when the interface is opened
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (112 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 113/686] mkiss: restart the transmit queue when the interface is opened Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 115/686] ax25: dont build a frame header from an uninitialised digipeater list Greg Kroah-Hartman
` (571 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
sp_close() stops the transmit queue, but sp_open_dev() never starts it
again. After the interface is set down and up the queue stays stopped,
sp_xmit() is never called again and sixpack_write_wakeup() cannot wake
it because sp_close() cleared TTY_DO_WRITE_WAKEUP: the interface no
longer transmits until the line discipline is detached and attached
again.
Start the queue in sp_open_dev(), as mkiss now does.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 0bcb990faaef028c18b553d416037efad044c81f)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/hamradio/6pack.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index c8b2dc5c1becc..549bd79d76365 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -256,6 +256,12 @@ static int sp_open_dev(struct net_device *dev)
if (sp->tty == NULL)
return -ENODEV;
+
+ /* sp_close() stopped the queue: restart it, or the interface
+ * never transmits again after it is set down and up.
+ */
+ netif_start_queue(dev);
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 115/686] ax25: dont build a frame header from an uninitialised digipeater list
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (113 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 114/686] 6pack: " Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 116/686] ax25: dont take a reference on a gone device in ax25_accept() Greg Kroah-Hartman
` (570 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25_sendmsg() reads the digipeaters given with the destination only
when the address is a full_sockaddr_ax25, but it then points dp at its
local ax25_digi whenever sax25_ndigis is not zero. sax25_ndigis is part
of the 16 byte struct sockaddr_ax25 as well, so a sendto() with that
short address and a non-zero sax25_ndigis makes ax25_sendmsg() build
the header from an ax25_digi that was never written: ax25_addr_size()
and ax25_addr_build() use whatever ndigi and calls[] the stack holds.
On a datagram socket the frame then goes out with kernel stack bytes as
digipeater calls, or skb_push() is asked for more than the headroom and
the kernel stops in skb_under_panic(). Any local user who can bind an
AX.25 socket can do it, and bind() is open to all with the default uid
policy. Kernels built with CONFIG_INIT_STACK_ALL_ZERO hide it, ndigi
is then 0.
Point dp at the local list only once the digipeaters have been read
into it. A short address now sends without digipeaters, as connect()
already does with the same address.
Tested on a QEMU bench (6.12.94 with KASAN, ax0 on mkiss, the frames
recorded on the serial line): ten sendto() with a full address and 8
digipeaters, each followed by one with a 16 byte address and
sax25_ndigis = 8, ax25 built with -ftrivial-auto-var-init=pattern as
with CONFIG_INIT_STACK_ALL_PATTERN:
before: skb_under_panic (put:1793), kernel BUG on the first short one
after: 20 frames, the short ones without digipeaters, the full ones
with their 8 digipeaters, no KASAN report
With the zero init used by most distribution kernels, and on this bench
without any init, the stack held 0 there and the short frames already
went out without digipeaters before the change.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 15f2d99ffa155d65e591fb171f3df048d3d3802c)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 63fe99746d328..6b43aaf31b252 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1569,7 +1569,7 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
struct sock *sk = sock->sk;
struct sockaddr_ax25 sax;
struct sk_buff *skb;
- ax25_digi dtmp, *dp;
+ ax25_digi dtmp, *dp = NULL;
ax25_cb *ax25;
size_t size;
int lv, err, addr_len = msg->msg_namelen;
@@ -1644,6 +1644,7 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
}
dtmp.lastrepeat = 0;
+ dp = &dtmp;
}
sax = *usax;
@@ -1652,10 +1653,6 @@ static int ax25_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
err = -EISCONN;
goto out;
}
- if (usax->sax25_ndigis == 0)
- dp = NULL;
- else
- dp = &dtmp;
} else {
/*
* FIXME: 1003.1g - if the socket is like this because
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 116/686] ax25: dont take a reference on a gone device in ax25_accept()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (114 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 115/686] ax25: dont build a frame header from an uninitialised digipeater list Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 117/686] ax25: dont copy an uninitialised address to recvmsg()s caller Greg Kroah-Hartman
` (569 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
A connection made on an incoming SABM waits on the listener's receive
queue until accept(). If its device goes down meanwhile,
ax25_kill_by_device() finds it on ax25_list, disconnects it and clears
its ax25_dev. It drops no device reference, since the socket has not
been grafted yet, but the skb stays on the listener's queue. The next
accept() then reads ax25->ax25_dev and passes NULL->dev to
netdev_hold():
KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017]
RIP: 0010:ax25_accept+0x58f/0x7e0 [ax25]
A listener bound to a device is itself closed by ax25_kill_by_device(),
so accept() returns -EINVAL unless it was already waiting and wakes up
in between. A listener bound to no device, which any user can create,
stays open, and the next accept() crashes every time.
ax25_accept() also grafts the socket and takes the device references
without the lock of the new socket, while ax25_kill_by_device() decides
under that lock, from sk->sk_socket, whether those references are there
to drop.
Graft the socket and take the references under its lock, and take none
when the device has already gone. accept() then returns the connection
closed, as it is: getpeername() and recv() give -ENOTCONN, and close()
frees it.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link). A listens on TESTA-9 bound to no device, B calls
it, A removes ax0 by detaching the N_AX25 line discipline, then calls
accept():
before: null-ptr-deref in ax25_accept(), kernel panic
after: accept() returns the socket, -ENOTCONN on it, ax25 refcount
back to its starting value once closed, no KASAN or lockdep
report, five runs out of five
A plain accept() run before that case behaves the same before and
after.
Fixes: 9fd75b66b8f6 ("ax25: Fix refcount leaks caused by ax25_cb_del()")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit b75827388dea3c54c44df39b003750b0849f9d31)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 6b43aaf31b252..4c5f82e2593c7 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1498,16 +1498,29 @@ static int ax25_accept(struct socket *sock, struct socket *newsock,
goto out;
newsk = skb->sk;
+
+ /*
+ * ax25_kill_by_device() detaches a connection from a device going
+ * down under the lock of its socket, clears its ax25_dev and drops
+ * the device references if the socket has been grafted by then.
+ * Graft the socket and take those references under the same lock,
+ * and take none if the device has already gone: the connection is
+ * closed then, and the socket is returned as such.
+ */
+ lock_sock_nested(newsk, SINGLE_DEPTH_NESTING);
sock_graft(newsk, newsock);
+ ax25 = sk_to_ax25(newsk);
+ ax25_dev = ax25->ax25_dev;
+ if (ax25_dev) {
+ netdev_hold(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC);
+ ax25_dev_hold(ax25_dev);
+ }
+ release_sock(newsk);
/* Now attach up the new socket */
kfree_skb(skb);
sk_acceptq_removed(sk);
newsock->state = SS_CONNECTED;
- ax25 = sk_to_ax25(newsk);
- ax25_dev = ax25->ax25_dev;
- netdev_hold(ax25_dev->dev, &ax25->dev_tracker, GFP_ATOMIC);
- ax25_dev_hold(ax25_dev);
out:
release_sock(sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 117/686] ax25: dont copy an uninitialised address to recvmsg()s caller
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (115 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 116/686] ax25: dont take a reference on a gone device in ax25_accept() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 118/686] ax25: free the old digipeater path of a listed socket under ax25_list_lock Greg Kroah-Hartman
` (568 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
When the caller asks for the sender's address, ax25_recvmsg() parses
the AX.25 header behind the mac header of the frame and copies out the
source and the digipeaters, without checking whether ax25_addr_parse()
succeeded. ax25_addr_parse() fills neither src nor digi when the header
is shorter than 14 bytes.
That is always the case for a message that ax25_rx_fragment() put back
together: the new skb has no address header and no mac header, so
skb->data - mac - 1 is negative. ax25_recvmsg() then copies an
uninitialised src, sets sax25_ndigis from an uninitialised digi.ndigi,
and copies that many entries of digi.calls[] into fsa_digipeater[],
reading past digi and writing past the caller's sockaddr_storage on the
kernel stack. Any AX.25 peer can send segmented I frames (PID 0x08) to
a SOCK_SEQPACKET socket whose owner reads them with recvfrom() or
recvmsg() and an address.
Only use the parsed address when there is a mac header and
ax25_addr_parse() succeeds, and give an empty AX.25 address otherwise.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link, PID 0x55, paclen 64 on the sender): B connects to
A and sends 20 bytes, then 200 bytes that go as fragments; A reads both
with recvfrom() and an address. ax25 built with
-ftrivial-auto-var-init=pattern, as with CONFIG_INIT_STACK_ALL_PATTERN:
before: 20 bytes from TESTB-1, then
BUG: KASAN: stack-out-of-bounds in ax25_recvmsg
stack-protector: Kernel stack is corrupted in: __sys_recvfrom
after: 20 bytes from TESTB-1, then 200 bytes with an empty address,
no KASAN report, five runs out of five
Built with the zero init used by most distribution kernels, the stack
held 0 there and the second address already came back empty.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit c87b940367ffe7952863d717797e156d3dbb57f0)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 41 ++++++++++++++++++++++++++---------------
1 file changed, 26 insertions(+), 15 deletions(-)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 4c5f82e2593c7..64a24543d7f42 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1803,25 +1803,36 @@ static int ax25_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
if (msg->msg_name) {
ax25_digi digi;
ax25_address src;
- const unsigned char *mac = skb_mac_header(skb);
+ const unsigned char *mac;
DECLARE_SOCKADDR(struct sockaddr_ax25 *, sax, msg->msg_name);
memset(sax, 0, sizeof(struct full_sockaddr_ax25));
- ax25_addr_parse(mac + 1, skb->data - mac - 1, &src, NULL,
- &digi, NULL, NULL);
sax->sax25_family = AF_AX25;
- /* We set this correctly, even though we may not let the
- application know the digi calls further down (because it
- did NOT ask to know them). This could get political... **/
- sax->sax25_ndigis = digi.ndigi;
- sax->sax25_call = src;
-
- if (sax->sax25_ndigis != 0) {
- int ct;
- struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)sax;
-
- for (ct = 0; ct < digi.ndigi; ct++)
- fsa->fsa_digipeater[ct] = digi.calls[ct];
+
+ /*
+ * A frame put together from fragments by ax25_rx_fragment()
+ * has no address header left, and no mac header: give no
+ * address then. ax25_addr_parse() fills neither src nor digi
+ * when it fails.
+ */
+ mac = skb_mac_header_was_set(skb) ? skb_mac_header(skb) : NULL;
+ if (mac && ax25_addr_parse(mac + 1, skb->data - mac - 1, &src,
+ NULL, &digi, NULL, NULL)) {
+ /*
+ * We set this correctly, even though we may not let the
+ * application know the digi calls further down (because
+ * it did NOT ask to know them). This could get political...
+ */
+ sax->sax25_ndigis = digi.ndigi;
+ sax->sax25_call = src;
+
+ if (sax->sax25_ndigis != 0) {
+ int ct;
+ struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)sax;
+
+ for (ct = 0; ct < digi.ndigi; ct++)
+ fsa->fsa_digipeater[ct] = digi.calls[ct];
+ }
}
msg->msg_namelen = sizeof(struct full_sockaddr_ax25);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 118/686] ax25: free the old digipeater path of a listed socket under ax25_list_lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (116 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 117/686] ax25: dont copy an uninitialised address to recvmsg()s caller Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 119/686] ax25: put an incoming connection on the listeners queue once it is set up Greg Kroah-Hartman
` (567 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25_connect() frees the digipeater path left by a previous connect()
with only the socket lock held. A bound socket is on ax25_list, where
__ax25_find_cb() on the receive path and ax25_info_show() for
/proc/net/ax25 read ax25->digipeat under ax25_list_lock, without the
socket lock. The path can thus be freed while one of them walks it.
Take the old path off the socket under ax25_list_lock before freeing
it, and set the new destination and path under the same lock, so that
a reader on the list never sees a freed path, nor a destination with
the path of another one.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, ax0 on mkiss):
a bound SOCK_SEQPACKET socket calls an absent station via 8
digipeaters six times, each new non-blocking connect() freeing the path
of the previous one, while a thread reads /proc/net/ax25 in a loop:
before: 18 reports such as
BUG: KASAN: slab-use-after-free in ax25_info_show
BUG: KASAN: slab-use-after-free in ax2asc
(90 with an mdelay(300) after the kfree())
after: no report, five runs out of five, and none with the mdelay
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 5aa967bbd20401af3415cd4fe056fca6624698f2)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 64a24543d7f42..e1a47489c601f 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1247,7 +1247,7 @@ static int __must_check ax25_connect(struct socket *sock,
struct sock *sk = sock->sk;
ax25_cb *ax25 = sk_to_ax25(sk), *ax25t;
struct full_sockaddr_ax25 *fsa = (struct full_sockaddr_ax25 *)uaddr;
- ax25_digi *digi = NULL;
+ ax25_digi *digi = NULL, *old_digi;
int ct = 0, err = 0;
/*
@@ -1299,8 +1299,16 @@ static int __must_check ax25_connect(struct socket *sock,
sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
- kfree(ax25->digipeat);
+ /*
+ * A bound socket is on ax25_list, where the receive path and
+ * /proc/net/ax25 read its digipeater path under ax25_list_lock:
+ * take the old path off under that lock before freeing it.
+ */
+ spin_lock_bh(&ax25_list_lock);
+ old_digi = ax25->digipeat;
ax25->digipeat = NULL;
+ spin_unlock_bh(&ax25_list_lock);
+ kfree(old_digi);
/*
* Handle digi-peaters to be used.
@@ -1360,8 +1368,10 @@ static int __must_check ax25_connect(struct socket *sock,
goto out_release;
}
+ spin_lock_bh(&ax25_list_lock);
ax25->dest_addr = fsa->fsa_ax25.sax25_call;
ax25->digipeat = digi;
+ spin_unlock_bh(&ax25_list_lock);
/* First the easy one */
if (sk->sk_type != SOCK_SEQPACKET) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 119/686] ax25: put an incoming connection on the listeners queue once it is set up
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (117 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 118/686] ax25: free the old digipeater path of a listed socket under ax25_list_lock Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 120/686] ax25: dont test the socket flags of a connection that has no socket Greg Kroah-Hartman
` (566 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
On a SABM for a listening socket, ax25_rcv() puts the skb on the
listener's receive queue as soon as the new socket is made, then
releases the listener and only afterwards fills in the connection:
addresses, digipeater path, modulus and window (read from the skb),
UA, state 3, ax25_cb_add() and the timers.
accept() can take the socket in between. If its owner closes it at
once, ax25_release() finds it in state 0 and frees it, and
ax25_rcv() goes on writing to the freed control block, adds it to
ax25_list and reads the freed skb.
Keep a place in the listener's backlog when the socket is made, and
put the skb on its queue once the connection is complete. If the
listener has been closed meanwhile, leave the connection to its
heartbeat, as ax25_destroy_socket() does with the connections that
were still waiting on its queue.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link). A listens on TESTA-9 and a thread calls accept()
in a loop on the non-blocking socket, closing each socket it gets at
once; B calls TESTA-9 five times:
before: BUG: KASAN: slab-use-after-free in ax25_rcv (write of 7
bytes), refcount_t: addition on 0, and a stale entry left in
/proc/net/ax25, without any delay added
after: no report, ax25 refcount back to its starting value,
/proc/net/ax25 empty, five runs out of five
With an mdelay(300) after the listener is released in ax25_rcv() the
results are the same. A third case closes the listener while
ax25_rcv() is held just before queueing the skb: the connection is
freed by its heartbeat, with no report and nothing left behind, three
runs out of three.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit d25d30927389f49e902185ef4647861f7654270e)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/ax25_in.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/net/ax25/ax25_in.c b/net/ax25/ax25_in.c
index cb48a479ba3cc..fd8669e5b7313 100644
--- a/net/ax25/ax25_in.c
+++ b/net/ax25/ax25_in.c
@@ -401,11 +401,12 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
}
}
- skb_set_owner_r(skb, make);
- skb_queue_head(&sk->sk_receive_queue, skb);
-
- make->sk_state = TCP_ESTABLISHED;
-
+ /*
+ * Keep a place in the backlog, but put the skb on the
+ * listener's queue only once the connection is set up
+ * below: accept() takes it from there, and close() on the
+ * new socket frees the connection.
+ */
sk_acceptq_added(sk);
bh_unlock_sock(sk);
} else {
@@ -488,8 +489,25 @@ static int ax25_rcv(struct sk_buff *skb, struct net_device *dev,
ax25_kick(ax25);
if (sk) {
- if (!sock_flag(sk, SOCK_DEAD))
+ bh_lock_sock(sk);
+ skb_set_owner_r(skb, make);
+ if (sk->sk_state == TCP_LISTEN && !sock_flag(sk, SOCK_DEAD)) {
+ skb_queue_head(&sk->sk_receive_queue, skb);
sk->sk_data_ready(sk);
+ } else {
+ /*
+ * The listener was closed meanwhile: leave the
+ * connection to its heartbeat, as
+ * ax25_destroy_socket() does with the connections
+ * that were still waiting on its queue.
+ */
+ sk_acceptq_removed(sk);
+ kfree_skb(skb);
+ sock_orphan(make);
+ make->sk_state = TCP_LISTEN;
+ ax25->state = AX25_STATE_0;
+ }
+ bh_unlock_sock(sk);
sock_put(sk);
} else {
free:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 120/686] ax25: dont test the socket flags of a connection that has no socket
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (118 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 119/686] ax25: put an incoming connection on the listeners queue once it is set up Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 121/686] ax25: free the copy of an IP packet that ax25_send_frame() turned down Greg Kroah-Hartman
` (565 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
When T1 runs out in state 2 (DISC sent, awaiting UA or DM), both
ax25_std_t1timer_expiry() and ax25_ds_t1_timeout() call
sock_flag(ax25->sk, SOCK_DESTROY) without checking ax25->sk. The
connections that ROSE, NET/ROM, IP in VC mode and incoming calls to the
port callsign make in the kernel have no socket, and reach state 2 when
their idle timer sends DISC. If the peer does not answer N2 times
before the heartbeat removes the connection, the timer dereferences a
NULL socket:
BUG: KASAN: null-ptr-deref in ax25_std_t1timer_expiry+0x3d9/0x4f0
Oops: general protection fault ... RIP: ax25_std_t1timer_expiry
With the default idle_timeout of 0 this cannot happen. With an idle
timeout set, it takes a short T1 and a small N2 on the standard path,
but on a DAMA slave ax25_ds_t1_timeout() runs on every poll.
A connection with no socket has nothing to destroy afterwards: test
the flag only when there is a socket, as ax25_disconnect() does.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link). A sets idle_timeout 1000 ms, t1_timeout 100 ms and
N2 1, with no listener; B calls NODEA-0, so A's kernel answers with a
connection without socket, then B removes its ax0 and stays silent:
before: null-ptr-deref in ax25_std_t1timer_expiry(), oops
after: the connection is disconnected and freed by its heartbeat,
ax25 refcount back to its starting value, /proc/net/ax25
empty, no report, five runs out of five
The DAMA path was not run on the bench.
Fixes: 4a7d99ea1b27 ("AX.25: Close socket connection on session completion")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit fa410516cbf02e38bd951f78cfa848b7ac22f5df)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/ax25_ds_timer.c | 2 +-
net/ax25/ax25_std_timer.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c
index 0c9e7775aa54e..a0d6e9c5ec9f3 100644
--- a/net/ax25/ax25_ds_timer.c
+++ b/net/ax25/ax25_ds_timer.c
@@ -211,7 +211,7 @@ void ax25_ds_t1_timeout(ax25_cb *ax25)
case AX25_STATE_2:
if (ax25->n2count == ax25->n2) {
ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
- if (!sock_flag(ax25->sk, SOCK_DESTROY))
+ if (!ax25->sk || !sock_flag(ax25->sk, SOCK_DESTROY))
ax25_disconnect(ax25, ETIMEDOUT);
return;
} else {
diff --git a/net/ax25/ax25_std_timer.c b/net/ax25/ax25_std_timer.c
index b17da41210cb1..05ff1032748f6 100644
--- a/net/ax25/ax25_std_timer.c
+++ b/net/ax25/ax25_std_timer.c
@@ -143,7 +143,7 @@ void ax25_std_t1timer_expiry(ax25_cb *ax25)
case AX25_STATE_2:
if (ax25->n2count == ax25->n2) {
ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
- if (!sock_flag(ax25->sk, SOCK_DESTROY))
+ if (!ax25->sk || !sock_flag(ax25->sk, SOCK_DESTROY))
ax25_disconnect(ax25, ETIMEDOUT);
return;
} else {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 121/686] ax25: free the copy of an IP packet that ax25_send_frame() turned down
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (119 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 120/686] ax25: dont test the socket flags of a connection that has no socket Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 122/686] ax25: dont leave half a message on a connection when fragmenting fails Greg Kroah-Hartman
` (564 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
In virtual circuit mode, ax25_ip_xmit() copies the IP packet, charges
the copy to the sending socket, frees the original and hands the copy
to ax25_send_frame(). When ax25_send_frame() gives up, because the
device is going down or the connection cannot be allocated, it returns
NULL and leaves the skb to its caller, as ROSE and NET/ROM expect.
ax25_ip_xmit() only handles the non-NULL case, so the copy is lost,
together with the send buffer space it holds on the socket.
Free it when ax25_send_frame() returns NULL.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, ax0 on mkiss
with IP 44.0.0.1, static ARP entries to DEST-1 and DEST-2,
ip_default_mode 1). The ax25 module of the bench has a parameter that
makes ax25_create_cb() fail, as on an allocation failure. A UDP socket
sends 300 datagrams to the station behind DEST-2 with that parameter
set, and its send queue (SIOCOUTQ) is read 4 s later:
before: 222 datagrams accepted, then the send buffer is full;
213120 bytes left in the send queue for good
after: 300 datagrams accepted, send queue back to 0, five runs out
of five
A control run to DEST-1 without the failure, where the connection
times out, empties the queue in both cases.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 4bb41115414921c65cad999bd7d7b84cc67360b3)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/ax25_ip.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/ax25/ax25_ip.c b/net/ax25/ax25_ip.c
index 215d4ccf12b91..b24cb88d75de7 100644
--- a/net/ax25/ax25_ip.c
+++ b/net/ax25/ax25_ip.c
@@ -176,9 +176,14 @@ netdev_tx_t ax25_ip_xmit(struct sk_buff *skb)
ax25_dev->values[AX25_VALUES_PACLEN],
&src_c,
&dst_c, digipeat, dev);
- if (ax25) {
+ /*
+ * ax25_send_frame() leaves the skb to its caller
+ * when it gives up, as ROSE and NET/ROM expect.
+ */
+ if (ax25)
ax25_cb_put(ax25);
- }
+ else
+ kfree_skb(ourskb);
goto put;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 122/686] ax25: dont leave half a message on a connection when fragmenting fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (120 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 121/686] ax25: free the copy of an IP packet that ax25_send_frame() turned down Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 123/686] ax25: make 16 the smallest maximum_packet_length of a port Greg Kroah-Hartman
` (563 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
ax25_output() puts each fragment on the write queue as soon as it is
built. If one allocation fails half way, it returns at once: the
fragments already queued go out and the peer gets the beginning of a
message whose end never comes, and the rest of the original skb is
never freed. That skb is charged to the sending socket, so
sk_has_allocations() stays true, ax25_destroy_timer() re-arms itself
every two seconds for good, and the socket, with its reference on the
ax25 module, is never freed.
Build the fragments on a list of our own, free that list and the
original skb if an allocation fails, and splice the fragments onto the
write queue once the message is complete. Two senders on the same
connection, as with several ROSE or NET/ROM circuits, also no longer
interleave the fragments of their messages.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link, PID 0x55, paclen 64 on the sender). The ax25 module
of the bench has a parameter that makes the allocation of a given
fragment fail. B sends 20 bytes, then 200 bytes in four fragments with
the third one failing, then 30 bytes, closes the socket and waits 30 s:
before: ax25 refcount left one above its value before the socket,
the socket is never freed
after: ax25 refcount back to its value before the socket, five
runs out of five
A receives the 20 and 30 byte messages in both cases. Without the
failure, the 200 byte message is put back together whole by A before
and after the change.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 801c45b8d6d552b4150f33e2d86fcf74ad0ea85c)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/ax25_out.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index 7c4ebef5ae6c2..50b014f7b0df5 100644
--- a/net/ax25/ax25_out.c
+++ b/net/ax25/ax25_out.c
@@ -137,7 +137,9 @@ EXPORT_SYMBOL(ax25_send_frame);
*/
void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
{
+ struct sk_buff_head frags;
struct sk_buff *skbn;
+ unsigned long flags;
unsigned char *p;
int frontlen, len, fragno, ka9qfrag, first = 1;
@@ -161,11 +163,20 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
frontlen = skb_headroom(skb); /* Address space + CTRL */
+ /*
+ * Build the fragments on a list of our own: a message that
+ * cannot be fragmented whole is not sent at all, and its
+ * fragments go on the write queue one after the other.
+ */
+ __skb_queue_head_init(&frags);
+
while (skb->len > 0) {
spin_lock_bh(&ax25_frag_lock);
if ((skbn = alloc_skb(paclen + 2 + frontlen, GFP_ATOMIC)) == NULL) {
spin_unlock_bh(&ax25_frag_lock);
printk(KERN_CRIT "AX.25: ax25_output - out of memory\n");
+ __skb_queue_purge(&frags);
+ kfree_skb(skb);
return;
}
@@ -200,10 +211,14 @@ void ax25_output(ax25_cb *ax25, int paclen, struct sk_buff *skb)
}
skb_pull(skb, len);
- skb_queue_tail(&ax25->write_queue, skbn); /* Throw it on the queue */
+ __skb_queue_tail(&frags, skbn);
}
kfree_skb(skb);
+
+ spin_lock_irqsave(&ax25->write_queue.lock, flags);
+ skb_queue_splice_tail_init(&frags, &ax25->write_queue);
+ spin_unlock_irqrestore(&ax25->write_queue.lock, flags);
} else {
skb_queue_tail(&ax25->write_queue, skb); /* Throw it on the queue */
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 123/686] ax25: make 16 the smallest maximum_packet_length of a port
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (121 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 122/686] ax25: dont leave half a message on a connection when fragmenting fails Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 124/686] ax25: keep the window below 8 when a socket goes back to modulo 8 Greg Kroah-Hartman
` (562 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
The per-port maximum_packet_length sysctl accepts values from 1, while
ax25_output() refuses a paclen below 16 with a WARN_ON_ONCE() and drops
the frame. A port set below 16 thus loses every frame sent with the
port's paclen: IP in virtual circuit mode, and connections whose
socket kept the default. AX25_PACLEN in setsockopt() and the
SIOCAX25CTLCON ioctl already refuse values below 16.
Raise the lower bound of the sysctl to 16.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, ax0 on mkiss,
IP in virtual circuit mode to a static ARP entry):
before: writing 10 is accepted, and the IP datagrams then sent give
WARNING at ax25_output+0x6d4 and are dropped
after: writing 10 gives -EINVAL and the value stays 256, writing 16
is accepted, and no warning
Fixes: f47b7257c736 ("[AX25] ax25_out: check skb for NULL in ax25_kick()")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 770beece44057f30cc873f72db809b4091c72916)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/sysctl_net_ax25.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c
index 68753aa303341..41a83e3a7e558 100644
--- a/net/ax25/sysctl_net_ax25.c
+++ b/net/ax25/sysctl_net_ax25.c
@@ -20,7 +20,7 @@ static int min_t2[] = {1}, max_t2[] = {20000};
static int min_t3[1], max_t3[] = {3600000};
static int min_idle[1], max_idle[] = {65535000};
static int min_n2[] = {1}, max_n2[] = {31};
-static int min_paclen[] = {1}, max_paclen[] = {512};
+static int min_paclen[] = {16}, max_paclen[] = {512};
static int min_proto[1], max_proto[] = { AX25_PROTO_MAX };
#ifdef CONFIG_AX25_DAMA_SLAVE
static int min_ds_timeout[1], max_ds_timeout[] = {65535000};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 124/686] ax25: keep the window below 8 when a socket goes back to modulo 8
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (122 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 123/686] ax25: make 16 the smallest maximum_packet_length of a port Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 125/686] ax25: let a socket connect again after a failed or ended connection Greg Kroah-Hartman
` (561 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
AX25_WINDOW accepts 1 to 63 on a socket in extended mode, but
AX25_EXTSEQ set back to 0 leaves the window as it was. With modulo 8,
ax25_kick() computes the end of the window as (V(A) + window) % 8: a
window of 8, 16, ... 56 gives V(A) itself, the window looks full, and
the connection never sends an I frame. Other values wrap round to a
smaller window.
Bring the window down to 7 when AX25_EXTSEQ selects modulo 8.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link). B sets AX25_EXTSEQ 1, AX25_WINDOW 16, AX25_EXTSEQ
0, calls A with a SABM and sends 5 messages:
before: window read back 16, A receives none of the 5 messages
after: window read back 7, A receives the 5 messages
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit bcd2f2d49b5af392504f29292cbd622d857507b6)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index e1a47489c601f..81616e8438ce4 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -708,6 +708,12 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname,
case AX25_EXTSEQ:
ax25->modulus = opt ? AX25_EMODULUS : AX25_MODULUS;
+ /*
+ * A window set for modulo 128 may not fit modulo 8:
+ * ax25_kick() would then find it full and send nothing.
+ */
+ if (ax25->modulus == AX25_MODULUS && ax25->window > 7)
+ ax25->window = 7;
break;
case AX25_PIDINCL:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 125/686] ax25: let a socket connect again after a failed or ended connection
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (123 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 124/686] ax25: keep the window below 8 when a socket goes back to modulo 8 Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 126/686] ax25: dont let connect() find its own socket when calling the same station Greg Kroah-Hartman
` (560 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
When a connection fails or ends, ax25_disconnect() sets SOCK_DEAD on
the socket and shuts it down for sending, although the socket is still
open and its owner may call connect() again. ax25_connect() resets the
socket states but leaves both:
- the new attempt changes the state under SOCK_DEAD, and both
ax25_disconnect() and the UA handling in state 1 skip
sk_state_change() on a SOCK_DEAD socket: a blocking connect() is
never woken up, whether the new link comes up or fails, and returns
only on a signal;
- once connected, every send() fails with -EPIPE, since sendmsg()
tests SEND_SHUTDOWN first.
Clear SOCK_DEAD and sk_shutdown when connect() starts a new attempt.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link). A listens on TESTA-9. B calls TESTA-8, where
nobody listens, then calls TESTA-9 with the same socket, a 20 s alarm
set, and sends a message:
before: the second connect() returns only when the alarm fires
20 s later, send() fails with -EPIPE, A receives nothing
after: the second connect() returns at once, send() succeeds and
A receives the message
Applications that open a new socket for each call are not affected.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit d3773f1e0b60711b93529c658b672633f55f19fc)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 81616e8438ce4..51a066ae4e89f 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1302,6 +1302,15 @@ static int __must_check ax25_connect(struct socket *sock,
goto out_release;
}
+ /*
+ * A connection that failed or ended through ax25_disconnect() left
+ * the socket SOCK_DEAD and shut down for sending. The socket is still
+ * its owner's: start afresh, or the state changes of the new attempt
+ * would wake no one and every send() would fail with -EPIPE.
+ */
+ sock_reset_flag(sk, SOCK_DEAD);
+ sk->sk_shutdown = 0;
+
sk->sk_state = TCP_CLOSE;
sock->state = SS_UNCONNECTED;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 126/686] ax25: dont let connect() find its own socket when calling the same station
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (124 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 125/686] ax25: let a socket connect again after a failed or ended connection Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 127/686] netrom: dont convert the maximum number of tries to jiffies Greg Kroah-Hartman
` (559 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
Before it starts a link, ax25_connect() looks on ax25_list for an
existing connection with the same source, destination, digipeater path
and device, and returns -EADDRINUSE if there is one. A bound socket is
on that list itself, with the destination of its previous attempt, and
its digipeater path was just freed. When a connect() failed or the
connection ended, a new connect() to the same station without
digipeaters thus finds the socket itself, and fails with -EADDRINUSE
every time.
Forget the previous destination before the lookup, under
ax25_list_lock, where the list readers compare it.
Tested on a QEMU bench (6.12.94 with KASAN and lockdep, two guests over
a KISS serial link). A starts listening on TESTA-9 after 7 s. B calls
TESTA-9 with one socket before that, which times out, then calls
TESTA-9 again with the same socket, non-blocking, and checks 3 s later:
before: -EADDRINUSE on the second call and on the check, A accepts
nothing
after: -EINPROGRESS, then the check returns 0 and A accepts the
connection, three runs out of three
send() on the new connection still fails with -EPIPE unless "ax25: let
a socket connect again after a failed or ended connection" is applied
as well; with both, and with "ax25: free the old digipeater path of a
listed socket under ax25_list_lock", A receives the message.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit efd5dce53a6bc296186212d4a16961174fd3df83)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ax25/af_ax25.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 51a066ae4e89f..d0ac09cc46e74 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -1374,6 +1374,15 @@ static int __must_check ax25_connect(struct socket *sock,
goto out_release;
}
+ /*
+ * The socket is on ax25_list with the destination of its previous
+ * attempt, if any: forget it, or the lookup below finds the socket
+ * itself when the same station is called again.
+ */
+ spin_lock_bh(&ax25_list_lock);
+ ax25->dest_addr = null_ax25_address;
+ spin_unlock_bh(&ax25_list_lock);
+
if (sk->sk_type == SOCK_SEQPACKET &&
(ax25t=ax25_find_cb(&ax25->source_addr, &fsa->fsa_ax25.sax25_call, digi,
ax25->ax25_dev->dev))) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 127/686] netrom: dont convert the maximum number of tries to jiffies
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (125 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 126/686] ax25: dont let connect() find its own socket when calling the same station Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 128/686] netrom: dont leak frames in nr_route_frame() Greg Kroah-Hartman
` (558 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_create() sets the number of transport retries of a new socket with
nr->n2 = msecs_to_jiffies(sysctl_netrom_transport_maximum_tries);
but transport_maximum_tries is a count, not a time in milliseconds. The
result depends on HZ: with the default of 3 tries, n2 is 3 with HZ=1000
but 1 with HZ=250 or HZ=100, below the minimum of 2 that the sysctl
itself enforces. Sockets accepted on a listener copy its n2, so every
NET/ROM circuit of such a kernel gives up after a single retry.
Seen on our nodes in /proc/net/nr: n2 is 01 on the Raspberry Pi kernels
(HZ=250 and HZ=100) and 03 on the x86 ones (HZ=1000), all with
transport_maximum_tries set to 3.
Use the count as is. The other transport values are times and keep
their conversion.
Fixes: 4d8937d0b113 ("[NETROM]: Eleminate HZ from NET/ROM kernel interfaces")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 16eb00a80bb05640ba628529fd258e4ddb100ecb)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/af_netrom.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 6de086082f71b..e3daae77e43e5 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -459,8 +459,7 @@ static int nr_create(struct net *net, struct socket *sock, int protocol,
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_timeout));
nr->t2 =
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_acknowledge_delay));
- nr->n2 =
- msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_maximum_tries));
+ nr->n2 = READ_ONCE(sysctl_netrom_transport_maximum_tries);
nr->t4 =
msecs_to_jiffies(READ_ONCE(sysctl_netrom_transport_busy_delay));
nr->idle =
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 128/686] netrom: dont leak frames in nr_route_frame()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (126 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 127/686] netrom: dont convert the maximum number of tries to jiffies Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 129/686] netrom: use the more flag of each frame taken from the resequencing queue Greg Kroah-Hartman
` (557 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_route_frame() leaks a frame in two cases.
When the frame comes from AX.25 and nr_add_node() fails, it returns the
error. AX.25 calls it as a protocol function and takes any non-zero
value as "frame consumed", so the frame is never freed. nr_add_node()
fails with -EINVAL when the source of the frame is one of our own
NET/ROM callsigns, which is what a node sees when its own frames come
back through a routing loop, and with -ENOMEM.
When the frame is forwarded, it is sent from a copy, nskb. If
ax25_send_frame() returns NULL (device going down, no memory), it has
not taken the copy, and nr_route_frame() only frees the original.
Return 0 when nr_add_node() fails, so that AX.25 frees the frame, and
free the copy when ax25_send_frame() returns NULL.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS: A
opens an AX.25 link to the NET/ROM callsign of B and sends 400 NET/ROM
frames with A's callsign as source, then 400 with B's own callsign as
source. Live skbs on B (skbuff_head_cache objects, KASAN quarantine
shrunk), 20 s after the last frame:
normal source B's own callsign
before the fix 12 412
after the fix 12 12
No kernel report in either run. The second leak (ax25_send_frame()
returning NULL) was checked by reading only.
Fixes: 58bc57471514 ("[AX.25]: Fix unchecked nr_add_node uses.")
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 51c59de17ab51364241f4b0bf4399b0f2c5dde5a)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/nr_route.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 288c4a91ea9b7..821697f222d6a 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -774,11 +774,16 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
nr_dest = (ax25_address *)(skb->data + 7);
if (ax25 != NULL) {
- ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
- ax25->ax25_dev->dev, 0,
- READ_ONCE(sysctl_netrom_obsolescence_count_initialiser));
- if (ret)
- return ret;
+ /*
+ * A frame that cannot be noted here (it claims to come from
+ * one of our own callsigns, or memory is short) is dropped.
+ * Return 0, not the error: AX.25 takes any other value as
+ * "frame consumed" and would never free it.
+ */
+ if (nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
+ ax25->ax25_dev->dev, 0,
+ READ_ONCE(sysctl_netrom_obsolescence_count_initialiser)))
+ return 0;
}
if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */
@@ -848,8 +853,14 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
spin_unlock_bh(&nr_route_lock);
nr_node_put(nr_node);
+ /*
+ * ax25_send_frame() only returns NULL before taking the frame:
+ * free our copy then; the caller frees the original.
+ */
if (ret)
kfree_skb(oskb);
+ else
+ kfree_skb(skb);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 129/686] netrom: use the more flag of each frame taken from the resequencing queue
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (127 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 128/686] netrom: dont leak frames in nr_route_frame() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 130/686] netrom: give a frame back intact when it cannot be delivered Greg Kroah-Hartman
` (556 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_state3_machine() puts every received INFO frame on reseq_queue and
then delivers, in sequence order, the frames found there. Each of them
is passed to nr_queue_rx_frame() with the more flag of the frame just
received, not with its own.
When frames arrive out of order, the frames taken from the queue are
not the one just received, and the boundaries of the messages are
wrong: the last fragment of a message can be held as if more followed,
so the message is joined to the next one, or a first fragment is
delivered as a whole message.
Take the more flag from the frame being delivered.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS: A
sends to a NET/ROM socket on B the second fragment of a message, then
its first fragment, then a one-frame message.
before: one message of 120 bytes read (both messages joined)
after: two messages of 80 and 40 bytes read
No kernel report in either run.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit f04ef49452f88b5a97039dc413cf86966470265f)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/nr_in.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index b90a47dcf165e..a2c839e3dfb66 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -176,7 +176,7 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
struct sk_buff *skbn;
unsigned short save_vr;
unsigned short nr, ns;
- int queued = 0;
+ int queued = 0, more;
nr = skb->data[18];
@@ -258,7 +258,9 @@ static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype
while ((skbn = skb_dequeue(&nrom->reseq_queue)) != NULL) {
ns = skbn->data[17];
if (ns == nrom->vr) {
- if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
+ /* The flags of this frame, not of the one just received */
+ more = skbn->data[19] & NR_MORE_FLAG;
+ if (nr_queue_rx_frame(sk, skbn, more) == 0) {
nrom->vr = (nrom->vr + 1) % NR_MODULUS;
} else {
nrom->condition |= NR_COND_OWN_RX_BUSY;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 130/686] netrom: give a frame back intact when it cannot be delivered
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (128 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 129/686] netrom: use the more flag of each frame taken from the resequencing queue Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 131/686] netrom: dont give the same circuit ID to two sockets Greg Kroah-Hartman
` (555 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
When nr_queue_rx_frame() cannot deliver a frame, it returns 1 and
nr_state3_machine() keeps the frame on reseq_queue, sets
NR_COND_OWN_RX_BUSY, and tries again later. But the frame given back is
not the frame it was given:
- the NET/ROM headers have already been pulled, so the frame is read
again later with a wrong N(S), and delivered without its first 20
bytes if that byte happens to match;
- for the last fragment of a message, the frame has been put on
frag_queue and freed while building the whole message: the caller
then queues a freed skb (use-after-free), or, when the allocation of
the whole message fails, an skb that is still on frag_queue.
This happens whenever the receive buffer is full, i.e. as soon as the
application reads more slowly than the peer sends.
Make nr_queue_rx_frame() all or nothing: build the whole message from
copies, leaving the fragments on frag_queue, and only free them once it
is queued. If the message cannot be queued, or allocated, free what was
built, push the headers back and return 1: the frame is given back as
it came and the earlier fragments are still there.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS. A
sends NET/ROM frames over a raw AX.25 link to a listening NET/ROM socket
on B, whose receive buffer is set to the minimum and which only starts
reading after 15 s: 10 messages of 2 fragments of 200 bytes, then the
next frame again every 6 s, as a peer retransmitting would.
before: KASAN slab-use-after-free in skb_queue_tail() called from
nr_process_rx_frame(), then a general protection fault in
nr_process_rx_frame() and a kernel panic; 2 messages read
after: 11 messages of 400, ..., 400, 40 bytes read, in order and
intact, no kernel report
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit e0c2041470f635cad936ac9abe04b01465105229)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/nr_in.c | 38 ++++++++++++++++++++++++++++----------
1 file changed, 28 insertions(+), 10 deletions(-)
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index a2c839e3dfb66..cf8844cd64b75 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -67,26 +67,44 @@ static int nr_queue_rx_frame(struct sock *sk, struct sk_buff *skb, int more)
return 0;
}
- if (!more && nr->fraglen > 0) { /* End of fragment */
- nr->fraglen += skb->len;
- skb_queue_tail(&nr->frag_queue, skb);
-
- if ((skbn = alloc_skb(nr->fraglen, GFP_ATOMIC)) == NULL)
- return 1;
+ if (nr->fraglen > 0) { /* End of fragment */
+ skbn = alloc_skb(nr->fraglen + skb->len, GFP_ATOMIC);
+ if (!skbn)
+ goto busy;
skb_reset_transport_header(skbn);
- while ((skbo = skb_dequeue(&nr->frag_queue)) != NULL) {
+ skb_queue_walk(&nr->frag_queue, skbo)
skb_copy_from_linear_data(skbo,
skb_put(skbn, skbo->len),
skbo->len);
- kfree_skb(skbo);
- }
+ skb_copy_from_linear_data(skb, skb_put(skbn, skb->len),
+ skb->len);
+ }
+
+ if (sock_queue_rcv_skb(sk, skbn) != 0) {
+ if (skbn != skb)
+ kfree_skb(skbn);
+ goto busy;
+ }
+ if (skbn != skb) {
+ /* The whole message is delivered: drop its pieces */
+ skb_queue_purge(&nr->frag_queue);
nr->fraglen = 0;
+ kfree_skb(skb);
}
- return sock_queue_rcv_skb(sk, skbn);
+ return 0;
+
+busy:
+ /*
+ * Not delivered: give the frame back as it came, headers included,
+ * and leave the earlier fragments where they are, so that the
+ * caller can keep it on reseq_queue and deliver it later.
+ */
+ skb_push(skb, NR_NETWORK_LEN + NR_TRANSPORT_LEN);
+ return 1;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 131/686] netrom: dont give the same circuit ID to two sockets
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (129 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 130/686] netrom: give a frame back intact when it cannot be delivered Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 132/686] netrom: return the peer node in the address given by recvmsg() Greg Kroah-Hartman
` (554 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_connect() and nr_rx_frame() pick a circuit ID with
nr_find_next_circuit(), which looks for an ID that no socket on nr_list
uses, and then store it in the socket and advance the global circuit
counter. The search and the assignment are not done under one lock, and
in nr_rx_frame() the new socket only goes on nr_list at the end. Two
sockets doing it at the same time can get the same ID.
The far end then answers both circuits with the same ID: the CONNACK of
one goes to the socket found first, the other connect() never
completes, and the frames of the two circuits are mixed up.
Pick the ID and give it to the socket under nr_list_lock, with the
socket already on nr_list: nr_connect() runs once the socket is bound,
and nr_rx_frame() now puts the new socket on nr_list under the same
lock. The global counter is then also only changed under that lock.
nr_list_lock is still not taken under a socket lock.
This is the same fix as rose_assign_lci() for ROSE.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS: A
starts eight connect() calls at the same time to a listening socket on
B, bound and unbound sockets alternately, six rounds, and looks for
duplicate circuit IDs in /proc/net/nr. The "slow" runs add mdelay(2)
between the choice of the ID and its assignment, to widen the window.
connected duplicate pairs rounds with duplicates
before, slow 25/48 37 6/6
after, slow 48/48 0 0/6
before 48/48 0 0/6
after 48/48 0 0/6
No kernel report in any run, and no lockdep report for the new
nr_list_lock taken in nr_rx_frame().
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 64166a6489d7eb3b7ba6bc8f534b008402a60fec)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/af_netrom.c | 55 ++++++++++++++++++++++++------------------
1 file changed, 32 insertions(+), 23 deletions(-)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index e3daae77e43e5..e3392e6dbc2eb 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -208,29 +208,40 @@ static struct sock *nr_find_peer(unsigned char index, unsigned char id,
}
/*
- * Find next free circuit ID.
+ * Give a socket the next free circuit ID. The search and the assignment
+ * are done under nr_list_lock, which the caller holds, with the socket
+ * already on nr_list: two sockets cannot pick the same ID.
*/
-static unsigned short nr_find_next_circuit(void)
+static void nr_assign_circuit(struct nr_sock *nr)
{
unsigned short id = circuit;
unsigned char i, j;
- struct sock *sk;
+ struct sock *s;
+ bool used;
+
+ lockdep_assert_held(&nr_list_lock);
for (;;) {
i = id / 256;
j = id % 256;
if (i != 0 && j != 0) {
- sk = nr_find_socket(i, j, NULL);
- if (!sk)
+ used = false;
+ sk_for_each(s, &nr_list)
+ if (nr_sk(s)->my_index == i && nr_sk(s)->my_id == j) {
+ used = true;
+ break;
+ }
+ if (!used)
break;
- sock_put(sk);
}
id++;
}
- return id;
+ nr->my_index = i;
+ nr->my_id = j;
+ circuit = id + 1;
}
/*
@@ -709,14 +720,10 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr,
nr->dest_addr = addr->sax25_call;
- release_sock(sk);
- circuit = nr_find_next_circuit();
- lock_sock(sk);
-
- nr->my_index = circuit / 256;
- nr->my_id = circuit % 256;
-
- circuit++;
+ /* The socket is on nr_list now, so others see the ID it gets */
+ spin_lock_bh(&nr_list_lock);
+ nr_assign_circuit(nr);
+ spin_unlock_bh(&nr_list_lock);
/* Move to connecting socket, start sending Connect Requests */
sock->state = SS_CONNECTING;
@@ -1013,15 +1020,19 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
nr_make->your_index = circuit_index;
nr_make->your_id = circuit_id;
+ /*
+ * Put the new socket on nr_list as it gets its circuit ID, under the
+ * same lock, so that no other socket can be given the same ID.
+ * nr_list_lock is not taken under a socket lock (nr_info_show() takes
+ * them the other way round).
+ */
bh_unlock_sock(sk);
- circuit = nr_find_next_circuit();
+ spin_lock_bh(&nr_list_lock);
+ nr_assign_circuit(nr_make);
+ sk_add_node(make, &nr_list);
+ spin_unlock_bh(&nr_list_lock);
bh_lock_sock(sk);
- nr_make->my_index = circuit / 256;
- nr_make->my_id = circuit % 256;
-
- circuit++;
-
/* Window negotiation */
if (window < nr_make->window)
nr_make->window = window;
@@ -1056,8 +1067,6 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
bh_unlock_sock(sk);
sock_put(sk);
- nr_insert_socket(make);
-
nr_start_heartbeat(make);
nr_start_idletimer(make);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 132/686] netrom: return the peer node in the address given by recvmsg()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (130 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 131/686] netrom: dont give the same circuit ID to two sockets Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 133/686] netrom: keep the selected route when a route of a node is removed Greg Kroah-Hartman
` (553 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_recvmsg() fills the source address with the 7 bytes found at offset 7
of the frame, where the destination of the NET/ROM network header once
was. But nr_queue_rx_frame() pulls the network and transport headers
before queueing the frame, so these bytes are user data, and for a
message shorter than 14 bytes they are read past its end: the caller
gets a few bytes of kernel memory as a callsign.
Give the node at the other end of the circuit, nr->dest_addr, which is
also what getpeername() returns with the user callsign.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS: A
sends "hello" (5 bytes) then a message of 30 'q' to a NET/ROM socket on
B, which reads them with recvfrom().
before: address bytes 16 eb 70 19 f7 91 5d (past the 5 bytes of
data), then 71 71 71 71 71 71 71 ('q' of the message)
after: TESTA-1 for both messages
No kernel report in either run.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 33171475c68078aebc88f87f35f5b9b4d50db0f5)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/af_netrom.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index e3392e6dbc2eb..d2b374dbc92fd 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1225,10 +1225,13 @@ static int nr_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
}
if (sax != NULL) {
+ /*
+ * The NET/ROM headers were pulled when the frame was queued:
+ * give the node at the other end of the circuit.
+ */
memset(sax, 0, sizeof(*sax));
sax->sax25_family = AF_NETROM;
- skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call,
- AX25_ADDR_LEN);
+ sax->sax25_call = nr_sk(sk)->dest_addr;
msg->msg_namelen = sizeof(*sax);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 133/686] netrom: keep the selected route when a route of a node is removed
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (131 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 132/686] netrom: return the peer node in the address given by recvmsg() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 134/686] netrom: drop a frame received with a TTL of 0 Greg Kroah-Hartman
` (552 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
A node has up to three routes, best first, and which selects the one in
use: nr_link_failed() moves it to the next route when the link to a
neighbour fails, and which >= count means that no route is left.
nr_dec_obs(), nr_del_node() and nr_rt_device_down() remove a route by
moving the routes after it up, but leave which alone. When the removed
route was before the selected one, which now selects the route after
it, or nothing at all: a node still reachable through its last route is
then dropped by nr_route_frame() as unreachable, until a NODES broadcast
happens to reset which.
nr_dec_obs() also moves on to the next index after removing a route, so
the route that has just moved up into that slot is skipped and its
obsolescence count is not decremented in this round.
Remove a route in one helper that moves the routes up and decrements
which when the removed route was before the selected one; if it was the
selected route, which now selects the next one, as after a link failure.
In the loops, only move on when the route stays.
Tested in a QEMU guest (6.12.94, KASAN, lockdep) whose KISS port leads
nowhere, so that every AX.25 link fails, with link_fails_count 1:
- node X through N1 (quality 200, obsolescence 1) and N2 (100, 6); a
connect() to X makes the link to N1 fail and which select N2 (w 2 in
/proc/net/nr_nodes); then SIOCNRDECOBS:
before: "w 2 n 1", obsolescence of N2 still 6; a new connect() to X
makes no attempt at all
after: "w 1 n 1", obsolescence 5; a new connect() opens a link to N2
- node Y through M1 (obsolescence 1) and M2 (2); after one SIOCNRDECOBS:
before: M2 still at 2
after: M2 at 1
No kernel report in either run.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 9957ac8b7a8af9cb48dd9758ee910e5b70935422)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/nr_route.c | 71 ++++++++++++++++++-------------------------
1 file changed, 29 insertions(+), 42 deletions(-)
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 821697f222d6a..8397a319932c1 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -344,6 +344,24 @@ static void nr_remove_neigh_locked(struct nr_neigh *nr_neigh)
nr_neigh_put(nr_neigh);
}
+/*
+ * Remove route i of a node: move the routes after it up, and keep which on
+ * the route it selected. If that route is the one removed, which now
+ * selects the next one, as after a link failure. The caller drops the
+ * route's use of its neighbour. Called with nr_route_lock held.
+ */
+static void nr_node_remove_route_locked(struct nr_node *nr_node, int i)
+{
+ lockdep_assert_held(&nr_route_lock);
+
+ if (i < nr_node->which)
+ nr_node->which--;
+
+ nr_node->count--;
+ for (; i < nr_node->count; i++)
+ nr_node->routes[i] = nr_node->routes[i + 1];
+}
+
/*
* "Delete" a node. Strictly speaking remove a route to a node. The node
* is only deleted if no routes are left to it.
@@ -373,22 +391,10 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n
nr_neigh_route_put_locked(nr_neigh);
nr_neigh_put(nr_neigh);
- nr_node->count--;
+ nr_node_remove_route_locked(nr_node, i);
- if (nr_node->count == 0) {
+ if (nr_node->count == 0)
nr_remove_node_locked(nr_node);
- } else {
- switch (i) {
- case 0:
- nr_node->routes[0] = nr_node->routes[1];
- fallthrough;
- case 1:
- nr_node->routes[1] = nr_node->routes[2];
- fallthrough;
- case 2:
- break;
- }
- }
/* Drop the reference taken by __nr_node_get() */
nr_node_put(nr_node);
ret = 0;
@@ -472,34 +478,24 @@ static int nr_dec_obs(void)
spin_lock_bh(&nr_route_lock);
nr_node_for_each_safe(s, nodet, &nr_node_list) {
- for (i = 0; i < s->count; i++) {
+ /* i only moves on when route i stays: the next one moves up */
+ for (i = 0; i < s->count; ) {
switch (s->routes[i].obs_count) {
case 0: /* A locked entry */
+ i++;
break;
case 1: /* From 1 -> 0 */
nr_neigh = s->routes[i].neighbour;
nr_neigh_route_put_locked(nr_neigh);
-
- s->count--;
-
- switch (i) {
- case 0:
- s->routes[0] = s->routes[1];
- fallthrough;
- case 1:
- s->routes[1] = s->routes[2];
- break;
- case 2:
- break;
- }
+ nr_node_remove_route_locked(s, i);
break;
default:
s->routes[i].obs_count--;
+ i++;
break;
-
}
}
@@ -525,23 +521,14 @@ void nr_rt_device_down(struct net_device *dev)
nr_neigh_for_each_safe(s, nodet, &nr_neigh_list) {
if (s->dev == dev) {
nr_node_for_each_safe(t, node2t, &nr_node_list) {
- for (i = 0; i < t->count; i++) {
+ for (i = 0; i < t->count; ) {
if (t->routes[i].neighbour == s) {
s->count--;
nr_neigh_put(s);
- t->count--;
-
- switch (i) {
- case 0:
- t->routes[0] = t->routes[1];
- fallthrough;
- case 1:
- t->routes[1] = t->routes[2];
- break;
- case 2:
- break;
- }
+ nr_node_remove_route_locked(t, i);
+ } else {
+ i++;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 134/686] netrom: drop a frame received with a TTL of 0
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (132 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 133/686] netrom: keep the selected route when a route of a node is removed Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 135/686] netrom: check the window size given by the peer Greg Kroah-Hartman
` (551 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_route_frame() drops a frame to forward when its time to live is 1,
then decrements the TTL of the copy it sends on. A frame that arrives
with a TTL of 0 passes the test and leaves with a TTL of 255: in a
routing loop it can then go round up to 255 more times instead of
dying.
Drop frames with a TTL of 0 as well.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS: A
sends B three NET/ROM frames for nodes that B routes through neighbour
TESTC, with TTL 0, 1 and 2, and listens as TESTC to see what B sends
on.
before: TTL 0 sent on with TTL 255, TTL 1 dropped, TTL 2 sent on with 1
after: TTL 0 dropped, TTL 1 dropped, TTL 2 sent on with 1
No kernel report in either run.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 303f110f8f2adc6f8b313fbfd4d53a1fc56c29e6)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/nr_route.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 8397a319932c1..7fbacc5fee84f 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -785,10 +785,12 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
if (!READ_ONCE(sysctl_netrom_routing_control) && ax25 != NULL)
return 0;
- /* Its Time-To-Live has expired */
- if (skb->data[14] == 1) {
+ /*
+ * Its Time-To-Live has expired. A frame received with a TTL of 0
+ * has expired too: decremented below, it would leave with 255.
+ */
+ if (skb->data[14] <= 1)
return 0;
- }
nr_node = nr_node_get(nr_dest);
if (nr_node == NULL)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 135/686] netrom: check the window size given by the peer
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (133 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 134/686] netrom: drop a frame received with a TTL of 0 Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 136/686] netrom: dont send part of a message that cannot be fragmented whole Greg Kroah-Hartman
` (550 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
The window size of a circuit is negotiated in its CONNREQ and CONNACK.
On a CONNREQ received, nr_rx_frame() keeps the smaller of ours and the
peer's; on a CONNACK, nr_state1_machine() takes the peer's as is.
So a window of 0 from the peer, in either frame, becomes the window of
the circuit, and nr_kick() then never sends anything: the circuit is
established but stuck. And a CONNACK can raise the window above the
one we asked for, even above NR_MAX_WINDOW_SIZE.
Negotiate both in one helper: take a window of 0 as 1 and keep the
smaller of ours and the peer's.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS. A
speaks NET/ROM itself over a raw AX.25 link and answers B's calls; after
each circuit is up, B sends two messages and A counts the INFO frames
(A does not acknowledge them):
before after
CONNREQ with window 0 wnd 0, 0 frame sent wnd 1, 1 frame sent
CONNACK with window 0 wnd 0, 0 frame sent wnd 1, 1 frame sent
CONNACK with window 200 wnd 200, 2 frames wnd 4 (ours), 2 frames
No kernel report in either run.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit ce7485c6c0e52acdef785adfc46541c20beb55ed)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/netrom.h | 13 +++++++++++++
net/netrom/af_netrom.c | 3 +--
net/netrom/nr_in.c | 2 +-
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/include/net/netrom.h b/include/net/netrom.h
index 2b4685d52bd81..b8f2e324962ba 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -87,6 +87,19 @@ struct nr_sock {
#define nr_sk(sk) ((struct nr_sock *)(sk))
+/*
+ * Window negotiation, for a CONNREQ received or a CONNACK: use the smaller
+ * of our window and the peer's. A window of 0 would never let a frame
+ * out: take it as 1.
+ */
+static inline void nr_negotiate_window(struct nr_sock *nr, unsigned char window)
+{
+ if (window == 0)
+ window = 1;
+ if (window < nr->window)
+ nr->window = window;
+}
+
struct nr_neigh {
struct hlist_node neigh_node;
ax25_address callsign;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index d2b374dbc92fd..ff7f6ba9754cc 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1034,8 +1034,7 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
bh_lock_sock(sk);
/* Window negotiation */
- if (window < nr_make->window)
- nr_make->window = window;
+ nr_negotiate_window(nr_make, window);
/*
* L4 timeout negotiation. Ignore a proposal shorter than the
diff --git a/net/netrom/nr_in.c b/net/netrom/nr_in.c
index cf8844cd64b75..805881e5d6c01 100644
--- a/net/netrom/nr_in.c
+++ b/net/netrom/nr_in.c
@@ -129,7 +129,7 @@ static int nr_state1_machine(struct sock *sk, struct sk_buff *skb,
nr->vl = 0;
nr->state = NR_STATE_3;
nr->n2count = 0;
- nr->window = skb->data[20];
+ nr_negotiate_window(nr, skb->data[20]);
sk->sk_state = TCP_ESTABLISHED;
if (!sock_flag(sk, SOCK_DEAD))
sk->sk_state_change(sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 136/686] netrom: dont send part of a message that cannot be fragmented whole
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (134 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 135/686] netrom: check the window size given by the peer Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 137/686] netrom: disconnect sockets under their lock when a device goes down Greg Kroah-Hartman
` (549 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_output() cuts a message longer than one frame into fragments and puts
each one on the write queue as soon as it is built, the more flag set on
all but the last. If allocating a fragment fails, it frees the rest of
the message and returns, and nr_sendmsg() still reports the whole
length as sent. The allocation waits for send buffer space, so this
happens not only when memory is short but whenever a signal interrupts
that wait.
The fragments already queued then go out ending with the more flag set:
the peer joins them to the next message. If the first allocation fails,
nothing is sent and the caller is told the message went.
Build the fragments on a list of our own and only put them on the write
queue once all of them exist; on failure, drop them and return the
error, which nr_sendmsg() passes on. This is what ax25_output() does
since #56.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS. A
speaks NET/ROM itself and never acknowledges; on the circuit it accepted,
B sends a 4000-byte message with SIGALRM set to interrupt it after 3 s,
then the 4-byte message "fin.":
SO_SNDBUF 6000:
before: send() = 4000; A receives 4 fragments of 236 bytes, all with
the more flag, and "fin." is queued behind them
after: send() = -1 EINTR; A receives "fin." alone
SO_SNDBUF at the minimum:
before: send() = 4000 but nothing of it is sent
after: send() = -1 EINTR
No kernel report in any run.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 6ab9b08cf19bef1a63c92bc030ae80d5f8e9c40a)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/netrom.h | 2 +-
net/netrom/af_netrom.c | 6 +++---
net/netrom/nr_out.c | 23 ++++++++++++++++++++---
3 files changed, 24 insertions(+), 7 deletions(-)
diff --git a/include/net/netrom.h b/include/net/netrom.h
index b8f2e324962ba..3f6fd2f894344 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -202,7 +202,7 @@ void nr_loopback_clear(void);
int nr_loopback_queue(struct sk_buff *);
/* nr_out.c */
-void nr_output(struct sock *, struct sk_buff *);
+int nr_output(struct sock *sk, struct sk_buff *skb);
void nr_send_nak_frame(struct sock *);
void nr_kick(struct sock *);
void nr_transmit_buffer(struct sock *, struct sk_buff *);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index ff7f6ba9754cc..77a8f4d6a59b4 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1173,9 +1173,9 @@ static int nr_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
goto out;
}
- nr_output(sk, skb); /* Shove it onto the queue */
-
- err = len;
+ err = nr_output(sk, skb); /* Shove it onto the queue */
+ if (!err)
+ err = len;
out:
release_sock(sk);
return err;
diff --git a/net/netrom/nr_out.c b/net/netrom/nr_out.c
index 2b3cbceb0b52d..150cb4263d314 100644
--- a/net/netrom/nr_out.c
+++ b/net/netrom/nr_out.c
@@ -28,11 +28,19 @@
/*
* This is where all NET/ROM frames pass, except for IP-over-NET/ROM which
* cannot be fragmented in this manner.
+ *
+ * A message too long for one frame is cut into fragments built on a list
+ * of our own, and only put on the write queue once all of them exist: a
+ * message that cannot be fragmented whole (no memory, or a signal while
+ * waiting for send buffer space) is not sent at all, and the error is
+ * returned. Consumes skb in all cases.
*/
-void nr_output(struct sock *sk, struct sk_buff *skb)
+int nr_output(struct sock *sk, struct sk_buff *skb)
{
+ struct sk_buff_head frags;
struct sk_buff *skbn;
unsigned char transport[NR_TRANSPORT_LEN];
+ unsigned long flags;
int err, frontlen, len;
if (skb->len - NR_TRANSPORT_LEN > NR_MAX_PACKET_SIZE) {
@@ -42,10 +50,13 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
frontlen = skb_headroom(skb);
+ __skb_queue_head_init(&frags);
+
while (skb->len > 0) {
if ((skbn = sock_alloc_send_skb(sk, frontlen + NR_MAX_PACKET_SIZE, 0, &err)) == NULL) {
+ __skb_queue_purge(&frags);
kfree_skb(skb);
- return;
+ return err;
}
skb_reserve(skbn, frontlen);
@@ -63,15 +74,21 @@ void nr_output(struct sock *sk, struct sk_buff *skb)
if (skb->len > 0)
skbn->data[4] |= NR_MORE_FLAG;
- skb_queue_tail(&sk->sk_write_queue, skbn); /* Throw it on the queue */
+ __skb_queue_tail(&frags, skbn);
}
kfree_skb(skb);
+
+ spin_lock_irqsave(&sk->sk_write_queue.lock, flags);
+ skb_queue_splice_tail_init(&frags, &sk->sk_write_queue);
+ spin_unlock_irqrestore(&sk->sk_write_queue.lock, flags);
} else {
skb_queue_tail(&sk->sk_write_queue, skb); /* Throw it on the queue */
}
nr_kick(sk);
+
+ return 0;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 137/686] netrom: disconnect sockets under their lock when a device goes down
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (135 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 136/686] netrom: dont send part of a message that cannot be fragmented whole Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 138/686] netrom: only update the BPQ extension flag on circuit set-up frames Greg Kroah-Hartman
` (548 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
nr_kill_by_device() disconnects every socket bound to the device going
down while holding only nr_list_lock. nr_disconnect() stops the timers,
purges the queues and changes the state of the socket, but its timers
and nr_rx_frame() work on the same socket under bh_lock_sock() only, on
other CPUs, and are not kept out by nr_list_lock: a timer can be
retransmitting from a queue being purged, or a frame received can move
the socket back to another state.
Take the socket lock around nr_disconnect(). nr_info_show() already
nests the socket lock inside nr_list_lock in the same way.
The race was not reproduced. Tested for regressions on two QEMU guests
(6.12.94, KASAN, lockdep) linked by KISS: A opens eight circuits to B
and keeps sending on them; B reads /proc/net/nr in a loop and takes nr0
down. Before and after, all eight circuits on B end with ENETUNREACH and
there is no kernel report, lockdep included.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 8ed753bc28c482baca2ac0ccfc3e2dbeda6a72a1)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/af_netrom.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 77a8f4d6a59b4..d9b2d74d44c8d 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -96,16 +96,22 @@ static void nr_remove_socket(struct sock *sk)
}
/*
- * Kill all bound sockets on a dropped device.
+ * Kill all bound sockets on a dropped device. Each socket is disconnected
+ * under its lock, which its timers and nr_rx_frame() hold while they work
+ * on it; nr_info_show() takes the two locks in the same order.
*/
static void nr_kill_by_device(struct net_device *dev)
{
struct sock *s;
spin_lock_bh(&nr_list_lock);
- sk_for_each(s, &nr_list)
- if (nr_sk(s)->device == dev)
- nr_disconnect(s, ENETUNREACH);
+ sk_for_each(s, &nr_list) {
+ if (nr_sk(s)->device != dev)
+ continue;
+ bh_lock_sock(s);
+ nr_disconnect(s, ENETUNREACH);
+ bh_unlock_sock(s);
+ }
spin_unlock_bh(&nr_list_lock);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 138/686] netrom: only update the BPQ extension flag on circuit set-up frames
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (136 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 137/686] netrom: disconnect sockets under their lock when a device goes down Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 139/686] rose: hold the listener while a Call Request is queued on it Greg Kroah-Hartman
` (547 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
For a frame received on an existing circuit, nr_rx_frame() sets bpqext
when the frame is a CONNACK of 22 bytes and clears it for any other
frame. Yet only the set-up frames tell whether the peer uses the BPQ
extension: a CONNACK of 22 bytes, or a CONNREQ of 37 bytes. The first
INFO frame of an accepted circuit therefore clears the flag set from
the peer's CONNREQ.
When a BPQ peer then repeats its CONNREQ, because our CONNACK was lost,
nr_state3_machine() answers with a CONNACK built with bpqext clear,
without the TTL byte that the first CONNACK had.
Only change bpqext on a CONNACK or a CONNREQ, from its length.
Tested on two QEMU guests (6.12.94, KASAN, lockdep) linked by KISS: A
speaks NET/ROM itself, opens a circuit to a listening socket on B with a
37-byte CONNREQ, sends an INFO frame on it, then repeats the CONNREQ.
before: first CONNACK 22 bytes, second one 21 bytes (no BPQ byte)
after: both CONNACK 22 bytes
No kernel report in either run.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit e0950e6b8432455e36dcdd4fcdcdf51b27e7404c)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netrom/af_netrom.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index d9b2d74d44c8d..86c0fca779051 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -961,10 +961,16 @@ int nr_rx_frame(struct sk_buff *skb, struct net_device *dev)
bh_lock_sock(sk);
skb_reset_transport_header(skb);
- if (frametype == NR_CONNACK && skb->len == 22)
- nr_sk(sk)->bpqext = 1;
- else
- nr_sk(sk)->bpqext = 0;
+ /*
+ * Only the circuit set-up frames tell whether the peer uses
+ * the BPQ extension: a CONNACK of 22 bytes, or a CONNREQ of
+ * 37 bytes (repeated, for a circuit already accepted). The
+ * other frames say nothing about it.
+ */
+ if (frametype == NR_CONNACK)
+ nr_sk(sk)->bpqext = (skb->len == 22);
+ else if (frametype == NR_CONNREQ)
+ nr_sk(sk)->bpqext = (skb->len == 37);
ret = nr_process_rx_frame(sk, skb);
bh_unlock_sock(sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 139/686] rose: hold the listener while a Call Request is queued on it
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (137 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 138/686] netrom: only update the BPQ extension flag on circuit set-up frames Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 140/686] rose: hold the socket a received frame is delivered to Greg Kroah-Hartman
` (546 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
rose_rx_call_request() runs in softirq context for every Call Request
addressed to us. It finds the listening socket with
rose_find_listener(), which returns it without a reference once
rose_list_lock is dropped, then creates the new socket, queues it on
the listener's receive queue and wakes the listener up. Nothing stops
the process owning the listener from closing it meanwhile:
rose_release() destroys a listening socket at once, and the Call
Request writes into freed memory. A node daemon that restarts while
calls come in does exactly this.
Take a reference in rose_find_listener(), lock the listener in
rose_rx_call_request() and refuse the call if it has been closed in the
meantime. rose_release() marks the socket dead with sock_orphan()
before rose_destroy_socket() empties its queue under the socket lock,
so a listener found alive once locked will see the new socket on its
queue, either in rose_accept() or when it is destroyed.
On a QEMU bench with two 4-CPU guests (KASAN, lockdep), six threads on
A calling B without a break while B opens a listening socket, keeps it
0 to 30 ms and closes it, for 40 s: before, KASAN reports a
slab-use-after-free in rose_rx_call_request() a few seconds in, the
socket having been freed by close() on B; with a 20 ms delay after
rose_find_listener() the corrupted socket list then panics B in
rose_neigh_put(). After, no report in either case, with about 400
calls connected as before.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 8bd85552e2ae1a606eda4b6c096a7e3bd0bcff62)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rose/af_rose.c | 32 +++++++++++++++++++++++++++-----
1 file changed, 27 insertions(+), 5 deletions(-)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 614d033410fa3..8d0878cf2b01c 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -278,7 +278,7 @@ static void rose_insert_socket(struct sock *sk)
/*
* Find a socket that wants to accept the Call Request we just
- * received.
+ * received. A reference is taken on the socket found.
*/
static struct sock *rose_find_listener(rose_address *addr, ax25_address *call)
{
@@ -304,6 +304,8 @@ static struct sock *rose_find_listener(rose_address *addr, ax25_address *call)
}
s = NULL;
found:
+ if (s)
+ sock_hold(s);
spin_unlock_bh(&rose_list_lock);
return s;
}
@@ -1103,12 +1105,31 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
}
sk = rose_find_listener(&facilities.source_addr, &facilities.source_call);
+ if (!sk) {
+ rose_transmit_clear_request(neigh, lci, ROSE_NETWORK_CONGESTION, 120);
+ return 0;
+ }
+
+ /*
+ * The listener may be closed by rose_release() at any time. It is
+ * marked dead before rose_destroy_socket() empties its queue, so
+ * once it is locked a listener that is not dead will see the new
+ * socket on its queue, either in rose_accept() or when it is
+ * destroyed.
+ */
+ bh_lock_sock(sk);
/*
* We can't accept the Call Request.
*/
- if (sk == NULL || sk_acceptq_is_full(sk) ||
- (make = rose_make_new(sk)) == NULL) {
+ if (sock_flag(sk, SOCK_DEAD) || sk->sk_state != TCP_LISTEN ||
+ sk_acceptq_is_full(sk))
+ make = NULL;
+ else
+ make = rose_make_new(sk);
+ if (!make) {
+ bh_unlock_sock(sk);
+ sock_put(sk);
rose_transmit_clear_request(neigh, lci, ROSE_NETWORK_CONGESTION, 120);
return 0;
}
@@ -1164,8 +1185,9 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
rose_start_heartbeat(make);
- if (!sock_flag(sk, SOCK_DEAD))
- sk->sk_data_ready(sk);
+ sk->sk_data_ready(sk);
+ bh_unlock_sock(sk);
+ sock_put(sk);
return 1;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 140/686] rose: hold the socket a received frame is delivered to
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (138 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 139/686] rose: hold the listener while a Call Request is queued on it Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 141/686] rose: report a timed out call to connect() Greg Kroah-Hartman
` (545 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
rose_route_frame() and rose_loopback_timer() find the socket a frame
belongs to with rose_find_socket(), which returns it without a
reference once rose_list_lock is dropped, then hand the frame to
rose_rcv_frame(), which locks the socket and runs its state machine.
The socket can be destroyed in between: by rose_release() on another
CPU, or by its heartbeat, which reaps a dead socket in state 0 that
nobody owns, such as an incoming call left on the queue of a listener
that has been closed. Its LCI is not cleared then, so frames from the
neighbour still find it until it is reaped, and the reaping frees it
under the frame being delivered.
Take a reference in rose_find_socket() and drop it in its callers once
the frame has been handled. rose_new_lci() only needs to know whether
an LCI is in use: let it walk the socket list under rose_list_lock
itself instead of taking references.
A Call Request that arrives on the LCI of an existing socket tears the
old socket down. With the reference held, the socket may by then have
been disconnected or reaped, its neighbour reference dropped and
rose->neighbour cleared: lock the socket and only tear it down if it
still holds that LCI on that neighbour.
On a QEMU bench with two 4-CPU guests (KASAN, lockdep), A places eight
calls to B and sends a 100-byte message per second on each; B listens
without ever accepting, closes the listener after 10 s, and the calls
left on its queue are reaped 5 s later while A's messages keep coming.
With frames for sockets in state 0 held 2 s after rose_find_socket(),
before: KASAN reports a slab-use-after-free in rose_rcv_frame(), called
from rose_route_frame(), on the socket freed by the heartbeat timer;
after: no report in two runs, and no report without the delay either.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 294cfbca864a2cf9d458fa1e8ee51f2cd8284b95)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rose/af_rose.c | 42 ++++++++++++++++++++++++++++++----------
net/rose/rose_loopback.c | 1 +
net/rose/rose_route.c | 37 +++++++++++++++++++++--------------
3 files changed, 56 insertions(+), 24 deletions(-)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 8d0878cf2b01c..87e7d938e6db7 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -312,20 +312,35 @@ static struct sock *rose_find_listener(rose_address *addr, ax25_address *call)
/*
* Find a connected ROSE socket given my LCI and device.
+ * The caller holds rose_list_lock.
*/
-struct sock *rose_find_socket(unsigned int lci, struct rose_neigh *neigh)
+static struct sock *__rose_find_socket(unsigned int lci, struct rose_neigh *neigh)
{
struct sock *s;
- spin_lock_bh(&rose_list_lock);
sk_for_each(s, &rose_list) {
struct rose_sock *rose = rose_sk(s);
if (rose->lci == lci && rose->neighbour == neigh)
- goto found;
+ return s;
}
- s = NULL;
-found:
+
+ return NULL;
+}
+
+/*
+ * Find a connected ROSE socket given my LCI and device. A reference is
+ * taken on the socket found: it can be released and destroyed as soon
+ * as rose_list_lock is dropped.
+ */
+struct sock *rose_find_socket(unsigned int lci, struct rose_neigh *neigh)
+{
+ struct sock *s;
+
+ spin_lock_bh(&rose_list_lock);
+ s = __rose_find_socket(lci, neigh);
+ if (s)
+ sock_hold(s);
spin_unlock_bh(&rose_list_lock);
return s;
}
@@ -336,19 +351,26 @@ struct sock *rose_find_socket(unsigned int lci, struct rose_neigh *neigh)
*/
unsigned int rose_new_lci(struct rose_neigh *neigh)
{
+ unsigned int res = 0;
int lci;
+ spin_lock_bh(&rose_list_lock);
if (neigh->dce_mode) {
for (lci = 1; lci <= sysctl_rose_maximum_vcs; lci++)
- if (rose_find_socket(lci, neigh) == NULL && rose_route_free_lci(lci, neigh) == NULL)
- return lci;
+ if (!__rose_find_socket(lci, neigh) && !rose_route_free_lci(lci, neigh)) {
+ res = lci;
+ break;
+ }
} else {
for (lci = sysctl_rose_maximum_vcs; lci > 0; lci--)
- if (rose_find_socket(lci, neigh) == NULL && rose_route_free_lci(lci, neigh) == NULL)
- return lci;
+ if (!__rose_find_socket(lci, neigh) && !rose_route_free_lci(lci, neigh)) {
+ res = lci;
+ break;
+ }
}
+ spin_unlock_bh(&rose_list_lock);
- return 0;
+ return res;
}
/*
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
index 4e4a473910cc8..6c5c35030e67b 100644
--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -109,6 +109,7 @@ static void rose_loopback_timer(struct timer_list *unused)
if (sk) {
if (rose_rcv_frame(sk, skb) == 0)
kfree_skb(skb);
+ sock_put(sk);
continue;
}
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 87a33f5c65d8a..84d628a826b79 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -1054,25 +1054,34 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
if (frametype == ROSE_CALL_REQUEST) {
struct rose_sock *rose = rose_sk(sk);
- /* Remove an existing unused socket */
- rose_clear_queues(sk);
- rose->cause = ROSE_NETWORK_CONGESTION;
- rose->diagnostic = 0;
- rose_neigh_put(rose->neighbour);
- rose->neighbour = NULL;
- rose->lci = 0;
- rose->state = ROSE_STATE_0;
- sk->sk_state = TCP_CLOSE;
- sk->sk_err = 0;
- sk->sk_shutdown |= SEND_SHUTDOWN;
- if (!sock_flag(sk, SOCK_DEAD)) {
- sk->sk_state_change(sk);
- sock_set_flag(sk, SOCK_DEAD);
+ /*
+ * Remove an existing unused socket, unless it was
+ * disconnected or reaped since it was found.
+ */
+ bh_lock_sock(sk);
+ if (rose->lci == lci && rose->neighbour == rose_neigh) {
+ rose_clear_queues(sk);
+ rose->cause = ROSE_NETWORK_CONGESTION;
+ rose->diagnostic = 0;
+ rose_neigh_put(rose->neighbour);
+ rose->neighbour = NULL;
+ rose->lci = 0;
+ rose->state = ROSE_STATE_0;
+ sk->sk_state = TCP_CLOSE;
+ sk->sk_err = 0;
+ sk->sk_shutdown |= SEND_SHUTDOWN;
+ if (!sock_flag(sk, SOCK_DEAD)) {
+ sk->sk_state_change(sk);
+ sock_set_flag(sk, SOCK_DEAD);
+ }
}
+ bh_unlock_sock(sk);
+ sock_put(sk);
}
else {
skb_reset_transport_header(skb);
res = rose_rcv_frame(sk, skb);
+ sock_put(sk);
goto out;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 141/686] rose: report a timed out call to connect()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (139 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 140/686] rose: hold the socket a received frame is delivered to Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 142/686] rose: drop the neighbour reference once when a cleared socket is closed Greg Kroah-Hartman
` (544 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
When the Call Request of a connecting socket gets no answer within T1,
rose_timer_expiry() sends a Clear Request and moves the socket to
state 2, leaving sk_state at TCP_SYN_SENT. The neighbour then confirms
the clearing, or clears the call itself, and rose_state2_machine()
calls rose_disconnect() with a reason of 0. sk_err stays 0, so a
blocking connect() leaves its wait with sock_error() returning 0 and
reports success on a call that never got through, and a non-blocking
caller reads 0 from SO_ERROR. The first send() then fails with EPIPE.
Report ETIMEDOUT when the socket is cleared from state 2 while it is
still connecting, as rose_timer_expiry() already does when T3 runs
out. A socket that was released or timed out while connected goes on
being cleared without an error.
On a QEMU bench with two guests, B listening with ROSE_DEFER and never
accepting, A calling it with T1 set to 3 s, twice blocking and twice
non-blocking: before, connect() or SO_ERROR returned 0 in all four
calls; after, ETIMEDOUT in all four. A call to nobody still gets
ECONNREFUSED at once.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit fc29d2c97f98f96d371e20d9b36b5ba08a914ff3)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rose/rose_in.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/net/rose/rose_in.c b/net/rose/rose_in.c
index 4eec54b24afb0..befb4c55e4597 100644
--- a/net/rose/rose_in.c
+++ b/net/rose/rose_in.c
@@ -75,17 +75,24 @@ static int rose_state1_machine(struct sock *sk, struct sk_buff *skb, int framety
static int rose_state2_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
struct rose_sock *rose = rose_sk(sk);
+ /*
+ * A call whose Call Request timed out (T1) is cleared from state 2
+ * while connect() is still waiting for it: report the timeout, or
+ * connect() and SO_ERROR would find no error on a call that never
+ * got through.
+ */
+ int reason = sk->sk_state == TCP_SYN_SENT ? ETIMEDOUT : 0;
switch (frametype) {
case ROSE_CLEAR_REQUEST:
rose_write_internal(sk, ROSE_CLEAR_CONFIRMATION);
- rose_disconnect(sk, 0, skb->data[3], skb->data[4]);
+ rose_disconnect(sk, reason, skb->data[3], skb->data[4]);
rose_neigh_put(rose->neighbour);
rose->neighbour = NULL;
break;
case ROSE_CLEAR_CONFIRMATION:
- rose_disconnect(sk, 0, -1, -1);
+ rose_disconnect(sk, reason, -1, -1);
rose_neigh_put(rose->neighbour);
rose->neighbour = NULL;
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 142/686] rose: drop the neighbour reference once when a cleared socket is closed
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (140 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 141/686] rose: report a timed out call to connect() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 143/686] rose: swap the AX.25 connection of a neighbour under a lock Greg Kroah-Hartman
` (543 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
rose_release() of a socket in state 2, awaiting the Clear Confirmation
of its call, drops the neighbour reference but leaves rose->neighbour
set, then releases the socket lock before disconnecting the socket.
release_sock() runs the frames put on the socket backlog while the
lock was held: a Clear Confirmation among them goes through
rose_state2_machine() with the socket still in state 2 and drops the
same reference again. rose_kill_by_neigh(), which does not take the
socket lock, can do the same if the link restarts or fails at that
moment. The neighbour refcount then goes below the number of users,
and the neighbour is freed while it is still in the tables.
Disconnect the socket before its lock is dropped, so that the frames
on the backlog find it in state 0, and take the neighbour off the
socket under rose_list_lock, as rose_kill_by_neigh() looks at it, so
that only one of them drops the reference.
On a QEMU bench with two guests (KASAN, lockdep), A calls B with T1 set
to 2 s, B never accepts, and A closes the socket 200 ms after T1
expired, while the Clear Confirmation is on its way. With 1 s of delay
in rose_release() and 500 ms before B sends the Clear Confirmation:
before, the "use" count of the neighbour in /proc/net/rose_neigh goes
to -1 on the first close, then KASAN reports a slab-use-after-free on
the freed neighbour and A panics; after, it stays at 0 over five calls,
with or without the delays.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit bf135eb205f09dbb9581f9bf2c9c8cd62d4ea9f2)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rose/af_rose.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 87e7d938e6db7..fbf0e27ce898b 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -698,6 +698,7 @@ static struct sock *rose_make_new(struct sock *osk)
static int rose_release(struct socket *sock)
{
struct sock *sk = sock->sk;
+ struct rose_neigh *neigh;
struct rose_sock *rose;
if (sk == NULL) return 0;
@@ -716,10 +717,21 @@ static int rose_release(struct socket *sock)
break;
case ROSE_STATE_2:
- rose_neigh_put(rose->neighbour);
- release_sock(sk);
+ /*
+ * Disconnect before the socket lock is dropped: frames put on
+ * the backlog meanwhile, a Clear Confirmation for one, then
+ * find it in state 0 instead of dropping the neighbour
+ * reference a second time. rose_kill_by_neigh() does not take
+ * the socket lock: take the neighbour under rose_list_lock, as
+ * it does, so that only one of them drops the reference.
+ */
rose_disconnect(sk, 0, -1, -1);
- lock_sock(sk);
+ spin_lock_bh(&rose_list_lock);
+ neigh = rose->neighbour;
+ rose->neighbour = NULL;
+ spin_unlock_bh(&rose_list_lock);
+ if (neigh)
+ rose_neigh_put(neigh);
rose_destroy_socket(sk);
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 143/686] rose: swap the AX.25 connection of a neighbour under a lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (141 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 142/686] rose: drop the neighbour reference once when a cleared socket is closed Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 144/686] rose: give the sysctl timer limits in milliseconds Greg Kroah-Hartman
` (542 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
Each holder of neigh->ax25 owns a reference on the ax25_cb.
rose_send_frame() and rose_link_up() replace it by reading the old
pointer, storing the new connection and dropping the reference on the
old one. They run from process context (sendmsg, connect, release),
from softirq (frames routed or answered on receipt) and from the
neighbour timers, under no common lock, and rose_link_failed() clears
the pointer under rose_neigh_list_lock alone. When two of them run at
the same time for one neighbour, both drop the reference on the same
old ax25_cb, which is freed while still in use, and the reference taken
by one of them on the new connection is lost.
Do the swap under a spinlock of its own and drop the reference taken
off after it, so that it is dropped once; rose_link_failed() only
clears the pointer if it still holds the failed connection.
On a QEMU bench with two 4-CPU guests (KASAN, lockdep), four threads on
A placing calls to B and sending a message every 20 ms, each echoed by
a thread on B: with 50 ms between the read and the update of
neigh->ax25, before: KASAN reports a slab-use-after-free in
rose_send_frame(), from rose_sendmsg() on B, and refcount_t reports an
underflow on the ax25_cb; after: no report. Without the delay, no
report either way and the same traffic, 1220 messages.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit 2d8b7bf0ceb1ceffa4b19906b70b8b412292e531)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/rose.h | 1 +
net/rose/rose_link.c | 61 ++++++++++++++++++++++++++++++++++---------
net/rose/rose_route.c | 5 ++--
3 files changed, 52 insertions(+), 15 deletions(-)
diff --git a/include/net/rose.h b/include/net/rose.h
index 7ee480e0a64e7..30b0809dd0a65 100644
--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -232,6 +232,7 @@ int rose_backlog_rcv(struct sock *sk, struct sk_buff *skb);
/* rose_link.c */
void rose_neigh_init_timers(struct rose_neigh *neigh);
+bool rose_neigh_clear_ax25(struct rose_neigh *neigh, ax25_cb *ax25);
void rose_start_ftimer(struct rose_neigh *);
void rose_stop_ftimer(struct rose_neigh *);
void rose_stop_t0timer(struct rose_neigh *);
diff --git a/net/rose/rose_link.c b/net/rose/rose_link.c
index 49a45936eb2bd..912d26f1fe359 100644
--- a/net/rose/rose_link.c
+++ b/net/rose/rose_link.c
@@ -27,6 +27,47 @@
static void rose_ftimer_expiry(struct timer_list *);
static void rose_t0timer_expiry(struct timer_list *);
+/*
+ * neigh->ax25 is replaced when a frame is sent or the link is looked up,
+ * from process context, softirq and the neighbour timers, and cleared by
+ * rose_link_failed(). Each holder of the pointer owns a reference on the
+ * ax25_cb: swap the pointer under this lock, then drop the reference that
+ * was taken off, so that it is dropped once and none is lost.
+ */
+static DEFINE_SPINLOCK(rose_neigh_ax25_lock);
+
+static void rose_neigh_set_ax25(struct rose_neigh *neigh, ax25_cb *ax25)
+{
+ ax25_cb *old;
+
+ spin_lock_bh(&rose_neigh_ax25_lock);
+ old = neigh->ax25;
+ neigh->ax25 = ax25;
+ spin_unlock_bh(&rose_neigh_ax25_lock);
+
+ if (old)
+ ax25_cb_put(old);
+}
+
+/*
+ * Clear neigh->ax25 if it still is @ax25, and drop its reference.
+ */
+bool rose_neigh_clear_ax25(struct rose_neigh *neigh, ax25_cb *ax25)
+{
+ bool found;
+
+ spin_lock_bh(&rose_neigh_ax25_lock);
+ found = neigh->ax25 == ax25;
+ if (found)
+ neigh->ax25 = NULL;
+ spin_unlock_bh(&rose_neigh_ax25_lock);
+
+ if (found)
+ ax25_cb_put(ax25);
+
+ return found;
+}
+
static void rose_transmit_restart_confirmation(struct rose_neigh *neigh);
static void rose_transmit_restart_request(struct rose_neigh *neigh);
@@ -91,19 +132,17 @@ static void rose_t0timer_expiry(struct timer_list *t)
static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
{
const ax25_address *rose_call;
- ax25_cb *ax25s;
+ ax25_cb *ax25;
if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
rose_call = (const ax25_address *)neigh->dev->dev_addr;
else
rose_call = &rose_callsign;
- ax25s = neigh->ax25;
- neigh->ax25 = ax25_send_frame(skb, 260, rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
- if (ax25s)
- ax25_cb_put(ax25s);
+ ax25 = ax25_send_frame(skb, 260, rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
+ rose_neigh_set_ax25(neigh, ax25);
- return neigh->ax25 != NULL;
+ return !!ax25;
}
/*
@@ -114,19 +153,17 @@ static int rose_send_frame(struct sk_buff *skb, struct rose_neigh *neigh)
static int rose_link_up(struct rose_neigh *neigh)
{
const ax25_address *rose_call;
- ax25_cb *ax25s;
+ ax25_cb *ax25;
if (ax25cmp(&rose_callsign, &null_ax25_address) == 0)
rose_call = (const ax25_address *)neigh->dev->dev_addr;
else
rose_call = &rose_callsign;
- ax25s = neigh->ax25;
- neigh->ax25 = ax25_find_cb(rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
- if (ax25s)
- ax25_cb_put(ax25s);
+ ax25 = ax25_find_cb(rose_call, &neigh->callsign, neigh->digipeat, neigh->dev);
+ rose_neigh_set_ax25(neigh, ax25);
- return neigh->ax25 != NULL;
+ return !!ax25;
}
/*
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 84d628a826b79..00fbe47fffe04 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -936,14 +936,13 @@ void rose_link_failed(ax25_cb *ax25, int reason)
spin_lock_bh(&rose_neigh_list_lock);
rose_neigh = rose_neigh_list;
while (rose_neigh != NULL) {
- if (rose_neigh->ax25 == ax25)
+ if (READ_ONCE(rose_neigh->ax25) == ax25)
break;
rose_neigh = rose_neigh->next;
}
if (rose_neigh != NULL) {
- rose_neigh->ax25 = NULL;
- ax25_cb_put(ax25);
+ rose_neigh_clear_ax25(rose_neigh, ax25);
rose_del_route_by_neigh(rose_neigh);
rose_kill_by_neigh(rose_neigh);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 144/686] rose: give the sysctl timer limits in milliseconds
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (142 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 143/686] rose: swap the AX.25 connection of a neighbour under a lock Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 145/686] mm: page_alloc: make defrag_mode retries follow the promoted order Greg Kroah-Hartman
` (541 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Bernard Pidoux, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bernard Pidoux <bernard.f6bvp@gmail.com>
Since commit 82e84249f0ee ("[ROSE]: Eleminate HZ from ROSE kernel
interfaces") the ROSE timer sysctls hold milliseconds, converted with
msecs_to_jiffies() where they are used, but their limits were left in
jiffies: 1 * HZ to 300 * HZ for T0 to T3 and the holdback, 60 * HZ to
600 * HZ for the link fail timeout, up to 65535 * HZ for the idle
timeout. They only match with HZ=1000. With HZ=100, the largest T1 that
can be written is 30 s while the default is 200 s, and the default link
fail timeout of 120 s is refused: once changed, a default can no longer
be put back. With HZ=250 the limit on T0 to T3 is 75 s.
Seen on a Raspberry Pi node (HZ=100): writing back 200000 to
call_request_timeout or 120000 to link_fail_timeout fails with EINVAL,
and 30000 is the largest call_request_timeout accepted.
Give the limits in milliseconds. With HZ=1000 nothing changes: on a
QEMU bench the defaults are accepted, and 999/300001 (T0 to T3),
59999/600001 (link fail) and 65535001 (idle) are refused, as before.
Fixes: 82e84249f0ee ("[ROSE]: Eleminate HZ from ROSE kernel interfaces")
Signed-off-by: Bernard Pidoux <bernard.f6bvp@gmail.com>
Assisted-by: Claude:claude-opus-5-5
(cherry picked from commit adb6f95e07482fb8aade33a20454b8a2a0fc7953)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rose/sysctl_net_rose.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/net/rose/sysctl_net_rose.c b/net/rose/sysctl_net_rose.c
index d801315b70839..a82735c34871c 100644
--- a/net/rose/sysctl_net_rose.c
+++ b/net/rose/sysctl_net_rose.c
@@ -9,13 +9,14 @@
#include <net/ax25.h>
#include <net/rose.h>
-static int min_timer[] = {1 * HZ};
-static int max_timer[] = {300 * HZ};
-static int min_idle[] = {0 * HZ};
-static int max_idle[] = {65535 * HZ};
+/* The timers are given in milliseconds */
+static int min_timer[] = {1 * MSEC_PER_SEC};
+static int max_timer[] = {300 * MSEC_PER_SEC};
+static int min_idle[] = {0 * MSEC_PER_SEC};
+static int max_idle[] = {65535 * MSEC_PER_SEC};
static int min_route[1], max_route[] = {1};
-static int min_ftimer[] = {60 * HZ};
-static int max_ftimer[] = {600 * HZ};
+static int min_ftimer[] = {60 * MSEC_PER_SEC};
+static int max_ftimer[] = {600 * MSEC_PER_SEC};
static int min_maxvcs[] = {1}, max_maxvcs[] = {254};
static int min_window[] = {1}, max_window[] = {7};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 145/686] mm: page_alloc: make defrag_mode retries follow the promoted order
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (143 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 144/686] rose: give the sysctl timer limits in milliseconds Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 146/686] devtmpfs: make devtmpfs_context_ops static Greg Kroah-Hartman
` (540 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiryl Shutsemau (Meta),
Andrew Morton, Vlastimil Babka (SUSE), Johannes Weiner,
David Hildenbrand, Harry Yoo, Usama Arif, Suren Baghdasaryan,
Michal Hocko, Brendan Jackman, Zi Yan, Shakeel Butt, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiryl Shutsemau (Meta) <kas@kernel.org>
commit 4cd78a2dcfbb13f049f841b98763896a3d1d7750 upstream.
Since commit 7e8756d7ad22 ("mm: page_alloc: fix non-movable reclaim storm
in defrag_mode"), direct reclaim and compaction for non-movable requests
under defrag_mode run at pageblock_order, to produce the whole blocks that
ALLOC_NOFRAGMENT needs. The retry decisions that follow still use the
request order. An order-0 request can therefore retry indefinitely
without ever reaching the ALLOC_NOFRAGMENT fallback:
- Reclaim at pageblock_order gives up after one pass as soon as a zone
looks compaction_ready(), and do_try_to_free_pages() then returns 1
even though nothing was reclaimed. It returns before the retry that
would reclaim memory.low-protected cgroups, so when most memory is
protected, the pass that did run finds next to nothing.
- Compaction at pageblock_order fails or is deferred.
- should_reclaim_retry() takes the reported progress as progress for
the order-0 request and resets no_progress_loops. The request
retries.
Order 1-3 requests loop the same way, and should_compact_retry() also
checks their pageblock_order compaction result against the request order.
On a production host (64G, defrag_mode, memory.low covering most of the
workload), 95% of direct reclaim runs were order-9 runs that returned 1
with nothing reclaimed, at up to 60k runs per second. Across ~200M
should_reclaim_retry() calls in a day, no_progress_loops never left 0.
The spinning allocations were SLUB slab refills for inode and dentry
caches. The time spent registers as memory pressure, and pressure-based
OOM killing takes down both workloads and system services.
For promoted requests:
- Reclaim progress does not reset no_progress_loops, as for costly
orders.
- should_compact_retry() checks the compaction result at the promoted
order and does not retry COMPACT_SKIPPED, since the request can fall
back. The compaction priority floor and the COMPACT_SUCCESS retry
limit stay those of the request order, so a non-costly request still
gets its COMPACT_PRIO_SYNC_FULL pass before it falls back.
When a promoted request takes the fallback, reset the retry counters, so
that the fallback attempt gets a full retry budget before the OOM killer
is considered. A request whose reclaim was not promoted spent its budget
on the request itself and keeps its counters, as Usama Arif pointed out.
__alloc_pages_slowpath() computes the promoted order once per iteration
and keeps it in alloc_context for direct reclaim, direct compaction and
the two retry helpers, so no callee has to recompute it. Harry Yoo asked
for the promoted order to be explicit rather than derived in each callee,
and Vlastimil Babka suggested alloc_context over new function parameters.
In a VM reproducer (32G, defrag_mode, inode churn under memory.low):
before after
should_reclaim_retry() calls 63M 293k
peak memory pressure (PSI some avg10) 99% 12%
File creation runs 5.7x faster.
[kas@kernel.org: s/order_nofrag_promoted/order_defrag_promoted/, per hannes]
Link: https://lore.kernel.org/atDL-nSFP2KVU7cI@thinkstation
Link: https://lore.kernel.org/as5q14OsbK2CmOrh@thinkstation
Fixes: 7e8756d7ad22 ("mm: page_alloc: fix non-movable reclaim storm in defrag_mode")
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Assisted-by: LLM
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Harry Yoo <harry@kernel.org>
Cc: Usama Arif <usama.arif@linux.dev>
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: Shakeel Butt <shakeel.butt@linux.dev>
Cc: <stable@vger.kernel.org>
[ kas: alloc_context is in mm/internal.h and compaction_zonelist_suitable()
takes no gfp_mask in 6.18. 6.18 also tries compaction once before the
retry loop; set reclaim_compact_order there as well, or that attempt
sees order 0 and is skipped. ]
Signed-off-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/internal.h | 2 ++
mm/page_alloc.c | 68 +++++++++++++++++++++++++++++++------------------
2 files changed, 45 insertions(+), 25 deletions(-)
diff --git a/mm/internal.h b/mm/internal.h
index ef42eee87c7be..e0adafc45c8c3 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -594,6 +594,8 @@ struct alloc_context {
*/
enum zone_type highest_zoneidx;
bool spread_dirty_pages;
+ /* Set by __alloc_pages_slowpath() before reclaim and compaction */
+ unsigned int reclaim_compact_order;
};
/*
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 8bdc35efad26b..8d608699bf508 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4130,6 +4130,12 @@ __alloc_pages_may_oom(gfp_t gfp_mask, unsigned int order,
return page;
}
+static inline bool order_defrag_promoted(unsigned int order,
+ const struct alloc_context *ac)
+{
+ return ac->reclaim_compact_order != order;
+}
+
/*
* Maximum number of compaction retries with a progress before OOM
* killer is consider as the only way to move forward.
@@ -4152,22 +4158,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order,
.order = order,
.page = NULL,
};
- int compact_order = order;
-
- /*
- * If fallbacks are not permitted (defrag_mode), we either
- * need to reclaim space in a block of matching type, or clear
- * out an entire block to allow __rmqueue_claim() to convert.
- *
- * Reclaim by itself is primarily freeing space in movable
- * blocks, since that's where the LRU pages live. So this
- * works for movable requests, but not for others.
- *
- * For those, promote the order to help make blocks, instead
- * of spinning in reclaim alone unproductively.
- */
- if ((alloc_flags & ALLOC_NOFRAGMENT) && ac->migratetype != MIGRATE_MOVABLE)
- compact_order = max(order, pageblock_order);
+ int compact_order = ac->reclaim_compact_order;
if (!compact_order)
return NULL;
@@ -4258,7 +4249,7 @@ should_compact_retry(struct alloc_context *ac, int order, int alloc_flags,
int retries = *compaction_retries;
enum compact_priority priority = *compact_priority;
- if (!order)
+ if (!ac->reclaim_compact_order)
return false;
if (fatal_signal_pending(current))
@@ -4267,9 +4258,11 @@ should_compact_retry(struct alloc_context *ac, int order, int alloc_flags,
/*
* Compaction was skipped due to a lack of free order-0
* migration targets. Continue if reclaim can help.
+ * Promoted requests fall back instead.
*/
if (compact_result == COMPACT_SKIPPED) {
- ret = compaction_zonelist_suitable(ac, order, alloc_flags);
+ if (!order_defrag_promoted(order, ac))
+ ret = compaction_zonelist_suitable(ac, order, alloc_flags);
goto out;
}
@@ -4467,11 +4460,7 @@ __alloc_pages_direct_reclaim(gfp_t gfp_mask, unsigned int order,
struct page *page = NULL;
unsigned long pflags;
bool drained = false;
- int reclaim_order = order;
-
- /* Match the slowpath compaction promotion in __alloc_pages_direct_compact */
- if ((alloc_flags & ALLOC_NOFRAGMENT) && ac->migratetype != MIGRATE_MOVABLE)
- reclaim_order = max(order, pageblock_order);
+ int reclaim_order = ac->reclaim_compact_order;
psi_memstall_enter(&pflags);
*did_some_progress = __perform_reclaim(gfp_mask, reclaim_order, ac);
@@ -4639,9 +4628,12 @@ should_reclaim_retry(gfp_t gfp_mask, unsigned order,
/*
* Costly allocations might have made a progress but this doesn't mean
* their order will become available due to high fragmentation so
- * always increment the no progress counter for them
+ * always increment the no progress counter for them. The same goes for
+ * promoted requests: their reclaim reports progress when it backs off
+ * for compaction without freeing anything.
*/
- if (did_some_progress && order <= PAGE_ALLOC_COSTLY_ORDER)
+ if (did_some_progress && order <= PAGE_ALLOC_COSTLY_ORDER &&
+ !order_defrag_promoted(order, ac))
*no_progress_loops = 0;
else
(*no_progress_loops)++;
@@ -4838,6 +4830,11 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
(costly_order ||
(order > 0 && ac->migratetype != MIGRATE_MOVABLE))
&& !gfp_pfmemalloc_allowed(gfp_mask)) {
+ /* Promote as the retry loop below does */
+ ac->reclaim_compact_order = order;
+ if ((alloc_flags & ALLOC_NOFRAGMENT) &&
+ ac->migratetype != MIGRATE_MOVABLE)
+ ac->reclaim_compact_order = max(order, pageblock_order);
page = __alloc_pages_direct_compact(gfp_mask, order,
alloc_flags, ac,
INIT_COMPACT_PRIORITY,
@@ -4936,6 +4933,22 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
if (current->flags & PF_MEMALLOC)
goto nopage;
+ /*
+ * If fallbacks are not permitted (defrag_mode), we either
+ * need to reclaim space in a block of matching type, or clear
+ * out an entire block to allow __rmqueue_claim() to convert.
+ *
+ * Reclaim by itself is primarily freeing space in movable
+ * blocks, since that's where the LRU pages live. So this
+ * works for movable requests, but not for others.
+ *
+ * For those, promote the order to help make blocks, instead
+ * of spinning in reclaim alone unproductively.
+ */
+ ac->reclaim_compact_order = order;
+ if ((alloc_flags & ALLOC_NOFRAGMENT) && ac->migratetype != MIGRATE_MOVABLE)
+ ac->reclaim_compact_order = max(order, pageblock_order);
+
/* Try direct reclaim and then allocating */
page = __alloc_pages_direct_reclaim(gfp_mask, order, alloc_flags, ac,
&did_some_progress);
@@ -4979,6 +4992,11 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
/* Reclaim/compaction failed to prevent the fallback */
if (defrag_mode && (alloc_flags & ALLOC_NOFRAGMENT)) {
alloc_flags &= ~ALLOC_NOFRAGMENT;
+ /* Retries went into making blocks, start the fallback afresh */
+ if (order_defrag_promoted(order, ac)) {
+ no_progress_loops = 0;
+ compaction_retries = 0;
+ }
goto retry;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 146/686] devtmpfs: make devtmpfs_context_ops static
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (144 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 145/686] mm: page_alloc: make defrag_mode retries follow the promoted order Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 147/686] devtmpfs: restore mount option reconfiguration on get_tree Greg Kroah-Hartman
` (539 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ben Dooks, Simon Liebold,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks <ben.dooks@codethink.co.uk>
[ Upstream commit 99aa03f98ce56804f2e8936f9dabf8c4f117a661 ]
The 'devtmpfs_context_ops' object is not exported outside the
devtmpfs.c file nor defined anywhere for use outside. Make this
static to remove the following sparse warning:
drivers/base/devtmpfs.c:88:30: warning: symbol 'devtmpfs_context_ops' was not declared. Should it be static?
Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
Link: https://patch.msgid.link/20260116150745.1330145-1-ben.dooks@codethink.co.uk
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 1c7df6fa838a ("devtmpfs: restore mount option reconfiguration on get_tree")
Signed-off-by: Simon Liebold <simonlie@amazon.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/devtmpfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 9d4e46ad83522..0bf3232b3ec14 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -85,7 +85,7 @@ static int devtmpfs_get_tree(struct fs_context *fc)
}
/* Ops are filled in during init depending on underlying shmem or ramfs type */
-struct fs_context_operations devtmpfs_context_ops = {};
+static struct fs_context_operations devtmpfs_context_ops = {};
/* Call the underlying initialization and set to our ops */
static int devtmpfs_init_fs_context(struct fs_context *fc)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 147/686] devtmpfs: restore mount option reconfiguration on get_tree
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (145 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 146/686] devtmpfs: make devtmpfs_context_ops static Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 148/686] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once Greg Kroah-Hartman
` (538 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Simon Liebold, Al Viro, Eric Sandeen,
Christian Brauner (Amutable), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Sandeen <sandeen@redhat.com>
[ Upstream commit 1c7df6fa838a46f0d5090ef134f67511f0592f33 ]
commit cb0e0a8bf4e1 ("devtmpfs: replace ->mount with ->get_tree in
public instance") converted the public devtmpfs instance to the new
mount API but broke the ability to reconfigure the shared superblock
options via subsequent mount() calls, as had been fixed once in
a6097180d884 ("devtmpfs regression fix: reconfigure on each mount")
This makes boot-time defaults permanent.
Fix this using an approach suggested by Al Viro: at init_fs_context
time, create a reconfigure-mode context via fs_context_for_reconfigure()
and save it in fc->fs_private. The devtmpfs parse ops can then use
this context to parse options appropriately for the underlying filesystem.
This also removes the devtmpfs_configure_context() one-time ops-copying
approach and the global mutable ops table it required.
Fixes: cb0e0a8bf4e1 ("devtmpfs: replace ->mount with ->get_tree in public instance")
Reported-by: Simon Liebold <simonlie@amazon.de>
Cc: stable@vger.kernel.org
Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Link: https://patch.msgid.link/b1bd3b15-78ea-4487-b6a8-aad0b05dd3bb@redhat.com
Tested-by: Simon Liebold <simonlie@amazon.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Simon Liebold <simonlie@amazon.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/devtmpfs.c | 108 ++++++++++++++++++++++++----------------
1 file changed, 64 insertions(+), 44 deletions(-)
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 0bf3232b3ec14..645c9f2674e99 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -73,39 +73,90 @@ static struct file_system_type internal_fs_type = {
.kill_sb = kill_litter_super,
};
-/* Simply take a ref on the existing mount */
+struct devtmpfs_context {
+ struct fs_context *fc;
+};
+
+static void devtmpfs_free(struct fs_context *fc)
+{
+ struct devtmpfs_context *ctx = fc->fs_private;
+
+ if (ctx) {
+ put_fs_context(ctx->fc);
+ kfree(ctx);
+ }
+}
+
+static int devtmpfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
+{
+ struct devtmpfs_context *ctx = fc->fs_private;
+
+ return ctx->fc->ops->parse_param(ctx->fc, param);
+}
+
+static int devtmpfs_parse_monolithic(struct fs_context *fc, void *data)
+{
+ struct devtmpfs_context *ctx = fc->fs_private;
+
+ if (ctx->fc->ops->parse_monolithic)
+ return ctx->fc->ops->parse_monolithic(ctx->fc, data);
+ return generic_parse_monolithic(ctx->fc, data);
+}
+
static int devtmpfs_get_tree(struct fs_context *fc)
{
+ struct devtmpfs_context *ctx = fc->fs_private;
struct super_block *sb = mnt->mnt_sb;
+ int err;
atomic_inc(&sb->s_active);
down_write(&sb->s_umount);
+
+ if (ctx->fc->ops->reconfigure) {
+ err = ctx->fc->ops->reconfigure(ctx->fc);
+ if (err) {
+ deactivate_locked_super(sb);
+ return err;
+ }
+ }
+
fc->root = dget(sb->s_root);
return 0;
}
-/* Ops are filled in during init depending on underlying shmem or ramfs type */
-static struct fs_context_operations devtmpfs_context_ops = {};
+static const struct fs_context_operations devtmpfs_context_ops = {
+ .free = devtmpfs_free,
+ .parse_param = devtmpfs_parse_param,
+ .parse_monolithic = devtmpfs_parse_monolithic,
+ .get_tree = devtmpfs_get_tree,
+};
-/* Call the underlying initialization and set to our ops */
static int devtmpfs_init_fs_context(struct fs_context *fc)
{
- int ret;
-#ifdef CONFIG_TMPFS
- ret = shmem_init_fs_context(fc);
-#else
- ret = ramfs_init_fs_context(fc);
-#endif
- if (ret < 0)
- return ret;
+ struct devtmpfs_context *ctx;
+ int err;
+
+ ctx = kzalloc_obj(struct devtmpfs_context);
+ if (!ctx)
+ return -ENOMEM;
+
+ /* Each mount will reconfigure the shared superblock w/ new options */
+ ctx->fc = fs_context_for_reconfigure(mnt->mnt_root,
+ mnt->mnt_sb->s_flags, MS_RMT_MASK);
+ if (IS_ERR(ctx->fc)) {
+ err = PTR_ERR(ctx->fc);
+ kfree(ctx);
+ return err;
+ }
+ fc->fs_private = ctx;
fc->ops = &devtmpfs_context_ops;
return 0;
}
static struct file_system_type dev_fs_type = {
- .name = "devtmpfs",
+ .name = "devtmpfs",
.init_fs_context = devtmpfs_init_fs_context,
};
@@ -443,31 +494,6 @@ static int __ref devtmpfsd(void *p)
return 0;
}
-/*
- * Get the underlying (shmem/ramfs) context ops to build ours
- */
-static int devtmpfs_configure_context(void)
-{
- struct fs_context *fc;
-
- fc = fs_context_for_reconfigure(mnt->mnt_root, mnt->mnt_sb->s_flags,
- MS_RMT_MASK);
- if (IS_ERR(fc))
- return PTR_ERR(fc);
-
- /* Set up devtmpfs_context_ops based on underlying type */
- devtmpfs_context_ops.free = fc->ops->free;
- devtmpfs_context_ops.dup = fc->ops->dup;
- devtmpfs_context_ops.parse_param = fc->ops->parse_param;
- devtmpfs_context_ops.parse_monolithic = fc->ops->parse_monolithic;
- devtmpfs_context_ops.get_tree = &devtmpfs_get_tree;
- devtmpfs_context_ops.reconfigure = fc->ops->reconfigure;
-
- put_fs_context(fc);
-
- return 0;
-}
-
/*
* Create devtmpfs instance, driver-core devices will add their device
* nodes here.
@@ -483,12 +509,6 @@ int __init devtmpfs_init(void)
return PTR_ERR(mnt);
}
- err = devtmpfs_configure_context();
- if (err) {
- pr_err("unable to configure devtmpfs type %d\n", err);
- return err;
- }
-
err = register_filesystem(&dev_fs_type);
if (err) {
pr_err("unable to register devtmpfs type %d\n", err);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 148/686] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (146 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 147/686] devtmpfs: restore mount option reconfiguration on get_tree Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 149/686] media: microchip-isc: fix WB offset and gain register field masking Greg Kroah-Hartman
` (537 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton,
Brendan Higgins, David Gow, Usama Arif, Sasha Levin
6.18-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 e95cddca0a10d..952e12fd6dbf7 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -2493,12 +2493,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] 687+ messages in thread
* [PATCH 6.18 149/686] media: microchip-isc: fix WB offset and gain register field masking
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (147 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 148/686] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 150/686] media: require two-byte Cypress type 04 records Greg Kroah-Hartman
` (536 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eugen Hristev, Balakrishnan Sambath,
Hans Verkuil, Sasha Levin
6.18-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 21d108eb93c7b..85cd86bed7ba9 100644
--- a/drivers/media/platform/microchip/microchip-isc-base.c
+++ b/drivers/media/platform/microchip/microchip-isc-base.c
@@ -62,17 +62,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 e77e1d9a1db87..166f57e6ed5d7 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] 687+ messages in thread
* [PATCH 6.18 150/686] media: require two-byte Cypress type 04 records
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (148 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 149/686] media: microchip-isc: fix WB offset and gain register field masking Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 151/686] media: adv748x: Fix endpoint reference leaks on probe failure Greg Kroah-Hartman
` (535 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Pengpeng Hou, Hans Verkuil,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit e22872703386c3885d8c6bd595124587bc4e5081 ]
Both Cypress Intel HEX parsers read two address bytes from type 04
records. Generic record framing permits any record length, so a short
record can make the parser consume the checksum or bytes beyond the
firmware record. A longer record also violates the Intel HEX type 04
layout.
Require the type 04 payload length to be exactly two bytes in both
implementations.
Fixes: 79a63c60a6a2 ("[media] media: move dvb-usb-v2/cypress_firmware.c to media/common")
Fixes: 776338e121b9 ("[PATCH] dvb: Add generalized dvb-usb driver")
Cc: stable@kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/common/cypress_firmware.c | 2 ++
drivers/media/usb/dvb-usb/dvb-usb-firmware.c | 2 ++
2 files changed, 4 insertions(+)
diff --git a/drivers/media/common/cypress_firmware.c b/drivers/media/common/cypress_firmware.c
index cdc7050ed3ac8..3468eff508b02 100644
--- a/drivers/media/common/cypress_firmware.c
+++ b/drivers/media/common/cypress_firmware.c
@@ -59,6 +59,8 @@ static int cypress_get_hexline(const struct firmware *fw,
if (hx->type == 0x04) {
/* b[4] and b[5] are the Extended linear address record data
* field */
+ if (hx->len != 2)
+ return -EINVAL;
hx->addr |= (b[4] << 24) | (b[5] << 16);
}
diff --git a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
index 0fb3fa6100e4a..675d9d1d4f472 100644
--- a/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
+++ b/drivers/media/usb/dvb-usb/dvb-usb-firmware.c
@@ -141,6 +141,8 @@ int dvb_usb_get_hexline(const struct firmware *fw, struct hexline *hx,
if (hx->type == 0x04) {
/* b[4] and b[5] are the Extended linear address record data field */
+ if (hx->len != 2)
+ return -EINVAL;
hx->addr |= (b[4] << 24) | (b[5] << 16);
/* hx->len -= 2;
data_offs += 2; */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 151/686] media: adv748x: Fix endpoint reference leaks on probe failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (149 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 150/686] media: require two-byte Cypress type 04 records Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 152/686] hwmon: (lm70) Fix rounding of negative temperatures Greg Kroah-Hartman
` (534 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hans Verkuil, Ruoyu Wang,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruoyu Wang <ruoyuw560@gmail.com>
[ Upstream commit 359db09cf055497075a668b192f4578a0ed00955 ]
adv748x_parse_dt() takes an extra reference for every endpoint saved in
state->endpoints. If parsing later fails, adv748x_probe() skips
adv748x_dt_cleanup(), so the saved references remain held. A CSI-2 lane
parsing error also returns from for_each_endpoint_of_node() without
dropping the iterator's reference.
Save the endpoint reference only after lane parsing succeeds. Drop the
iterator reference before returning a lane parsing error and route all
parse failures through the endpoint cleanup path to release any saved
references. This retains the endpoints only for a successful probe.
This issue was found by a static analysis checker and confirmed by
manual source review.
Fixes: 6a18865da8e3 ("media: i2c: adv748x: store number of CSI-2 lanes described in device tree")
Fixes: eccf442ce156 ("media: i2c: adv748x: Support probing a single output")
Cc: stable@vger.kernel.org
Suggested-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/adv748x/adv748x-core.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/media/i2c/adv748x/adv748x-core.c b/drivers/media/i2c/adv748x/adv748x-core.c
index 3eb6d5e8f0826..70594d0018048 100644
--- a/drivers/media/i2c/adv748x/adv748x-core.c
+++ b/drivers/media/i2c/adv748x/adv748x-core.c
@@ -675,9 +675,6 @@ static int adv748x_parse_dt(struct adv748x_state *state)
continue;
}
- of_node_get(ep_np);
- state->endpoints[ep.port] = ep_np;
-
/*
* At least one input endpoint and one output endpoint shall
* be defined.
@@ -689,8 +686,13 @@ static int adv748x_parse_dt(struct adv748x_state *state)
/* Store number of CSI-2 lanes used for TXA and TXB. */
ret = adv748x_parse_csi2_lanes(state, ep.port, ep_np);
- if (ret)
+ if (ret) {
+ of_node_put(ep_np);
return ret;
+ }
+
+ of_node_get(ep_np);
+ state->endpoints[ep.port] = ep_np;
}
return in_found && out_found ? 0 : -ENODEV;
@@ -739,7 +741,7 @@ static int adv748x_probe(struct i2c_client *client)
ret = adv748x_parse_dt(state);
if (ret) {
adv_err(state, "Failed to parse device tree");
- goto err_free_mutex;
+ goto err_cleanup_dt;
}
/* Configure IO Regmap region */
@@ -809,7 +811,6 @@ static int adv748x_probe(struct i2c_client *client)
adv748x_unregister_clients(state);
err_cleanup_dt:
adv748x_dt_cleanup(state);
-err_free_mutex:
mutex_destroy(&state->mutex);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 152/686] hwmon: (lm70) Fix rounding of negative temperatures
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (150 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 151/686] media: adv748x: Fix endpoint reference leaks on probe failure Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 153/686] iio: pressure: dps310: fix CFG_REG bit definitions Greg Kroah-Hartman
` (533 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ridham Khurana, Guenter Roeck,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridham Khurana <khurana.ridham222@gmail.com>
[ Upstream commit eddb0aaacce4baa9d8176eb2f4bd9e99e867f8fc ]
temp1_input_show() drops the low bits of the temperature register by
dividing the raw value (raw / 32 on the LM70). These bits are not part
of the temperature: the LM70, LM71, LM74 and TMP122/TMP124 always
return some of them as 1, and the TMP125 fills them with copies of the
temperature LSB. Division rounds toward zero, so a negative temperature
with any of these bits set is reported one LSB too high.
For example, the TMP122 returns 0xffff for -0.0625 degrees C, which the
driver reports as 0. The LM70 returns 0xf39f for -25 degrees C, which
the driver reports as -24750.
Use an arithmetic right shift instead, which drops the low bits and
rounds down.
Fixes: e1a8e913f97e ("[PATCH] lm70: New hardware monitoring driver")
Fixes: a86e94dc946d ("hwmon: (lm70) Add support for LM71 and LM74")
Fixes: cd929672a9ef ("hwmon: (lm70) Add ti,tmp125 support")
Cc: stable@vger.kernel.org
Signed-off-by: Ridham Khurana <khurana.ridham222@gmail.com>
Link: https://patch.msgid.link/20260924205326.1739229-1-khurana.ridham222@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/lm70.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c
index 0d5a250cb6722..ee06c5641870a 100644
--- a/drivers/hwmon/lm70.c
+++ b/drivers/hwmon/lm70.c
@@ -97,21 +97,21 @@ static ssize_t temp1_input_show(struct device *dev,
*/
switch (p_lm70->chip) {
case LM70_CHIP_LM70:
- val = ((int)raw / 32) * 250;
+ val = ((int)raw >> 5) * 250;
break;
case LM70_CHIP_TMP121:
case LM70_CHIP_TMP122:
case LM70_CHIP_LM74:
- val = ((int)raw / 8) * 625 / 10;
+ val = ((int)raw >> 3) * 625 / 10;
break;
case LM70_CHIP_LM71:
- val = ((int)raw / 4) * 3125 / 100;
+ val = ((int)raw >> 2) * 3125 / 100;
break;
case LM70_CHIP_TMP125:
- val = (sign_extend32(raw, 14) / 32) * 250;
+ val = (sign_extend32(raw, 14) >> 5) * 250;
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 153/686] iio: pressure: dps310: fix CFG_REG bit definitions
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (151 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 152/686] hwmon: (lm70) Fix rounding of negative temperatures Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 154/686] media: mediatek: jpeg: Avoid context access after job finish Greg Kroah-Hartman
` (532 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rupesh Majhi, Jonathan Cameron,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rupesh Majhi <zoone.rupert@gmail.com>
[ Upstream commit 4334dc4092c271e6cd010c2ee70b7f4415c4c199 ]
Driver defines them as BIT(4), BIT(5) and BIT(6). Per datasheet P_SHIFT
is bit 2, FIFO_EN is bit 1 and SPI_MODE is bit 0.
Only P_SHIFT has a user. dps310_set_pres_precision() sets it at
oversampling 16 or above, so with wrong bit the result register is never
shifted and stops matching the scale factor compensation divides by.
in_pressure_input returns -ERANGE at oversampling 16, 32 and 64.
FIFO_EN needed by FIFO support later in this series.
Fixes: ba6ec48e76bc ("iio: Add driver for Infineon DPS310")
Fixes: d711a3c7dc82 ("iio: dps310: Add pressure sensing capability")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Rupesh Majhi <zoone.rupert@gmail.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/pressure/dps310.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/pressure/dps310.c b/drivers/iio/pressure/dps310.c
index 41b2d0b014e18..a617f26eeb300 100644
--- a/drivers/iio/pressure/dps310.c
+++ b/drivers/iio/pressure/dps310.c
@@ -50,9 +50,9 @@
#define DPS310_CFG_REG 0x09
#define DPS310_INT_HL BIT(7)
#define DPS310_TMP_SHIFT_EN BIT(3)
-#define DPS310_PRS_SHIFT_EN BIT(4)
-#define DPS310_FIFO_EN BIT(5)
-#define DPS310_SPI_EN BIT(6)
+#define DPS310_PRS_SHIFT_EN BIT(2)
+#define DPS310_FIFO_EN BIT(1)
+#define DPS310_SPI_EN BIT(0)
#define DPS310_RESET 0x0c
#define DPS310_RESET_MAGIC 0x09
#define DPS310_COEF_BASE 0x10
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 154/686] media: mediatek: jpeg: Avoid context access after job finish
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (152 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 153/686] iio: pressure: dps310: fix CFG_REG bit definitions Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 155/686] PCI/AER: Fix memory leak in aer_recover_work_func() when pci_dev is missing Greg Kroah-Hartman
` (531 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kazuki Hanai, Nicolas Dufresne,
Hans Verkuil, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kazuki Hanai <hnkz.64@gmail.com>
[ Upstream commit 7c7f31405b76acd95a628c834ee8a2d6da439782 ]
v4l2_m2m_job_finish() publishes job completion and wakes waiters
before it returns. A concurrent file release can therefore finish
v4l2_m2m_ctx_release() and free the context while the single-core IRQ
handler continues with its tail.
Both handlers only need the device for the matching runtime PM put.
Use the IRQ-owned jpeg pointer instead of dereferencing ctx after
completion has been published. This preserves the get/put pairing and
removes the post-completion context access.
Fixes: 45f13a57d813 ("media: platform: Add jpeg enc feature")
Fixes: 5827e4b14ee7 ("media: platform: Improve power on and power off flow")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5
Signed-off-by: Kazuki Hanai <hnkz.64@gmail.com>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
index 8e52b40e2423b..f4eebd7575493 100644
--- a/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
+++ b/drivers/media/platform/mediatek/jpeg/mtk_jpeg_core.c
@@ -1581,7 +1581,7 @@ static irqreturn_t mtk_jpeg_enc_done(struct mtk_jpeg_dev *jpeg)
v4l2_m2m_buf_done(src_buf, buf_state);
v4l2_m2m_buf_done(dst_buf, buf_state);
v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
- pm_runtime_put(ctx->jpeg->dev);
+ pm_runtime_put(jpeg->dev);
return IRQ_HANDLED;
}
@@ -1869,7 +1869,7 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv)
v4l2_m2m_buf_done(src_buf, buf_state);
v4l2_m2m_buf_done(dst_buf, buf_state);
v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx);
- pm_runtime_put(ctx->jpeg->dev);
+ pm_runtime_put(jpeg->dev);
return IRQ_HANDLED;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 155/686] PCI/AER: Fix memory leak in aer_recover_work_func() when pci_dev is missing
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (153 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 154/686] media: mediatek: jpeg: Avoid context access after job finish Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 156/686] mm/memcontrol: fix data-race on reading jiffies_64 Greg Kroah-Hartman
` (530 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Priyank Rathod, Bjorn Helgaas,
Kuppuswamy Sathyanarayanan, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Priyank Rathod <rathodpriyank@google.com>
[ Upstream commit d4c842c3af5bc52b3ca0b8a7f116114e43b6ba44 ]
When ACPI APEI/GHES processes PCIe AER error records, it allocates memory
for aer_capability_regs (entry.regs) from ghes_estatus_pool and queues the
entry into aer_recover_ring.
In aer_recover_work_func(), items are popped from aer_recover_ring via
kfifo_get(). If pci_get_domain_bus_and_slot() fails to find a matching
pci_dev, the code previously executed 'continue', bypassing the call to
ghes_estatus_pool_region_free(). As a result, the memory allocated for
entry.regs from ghes_estatus_pool was leaked.
This is reachable whenever the device reported by firmware is not (or is no
longer) present in the PCI device tree, e.g. after hot-removal or when
firmware reports an error for a device the kernel never enumerated.
Refactor aer_recover_work_func() to ensure ghes_estatus_pool_region_free()
is called unconditionally for every dequeued entry, releasing the pool
memory even when pci_dev is missing.
Fixes: e2abc47a5a1a ("ACPI: APEI: Fix AER info corruption when error status data has multiple sections")
Signed-off-by: Priyank Rathod <rathodpriyank@google.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260928-b4-fix-aer-memleaks-v5-2-ba6b94c9c9a6@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/pcie/aer.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/drivers/pci/pcie/aer.c b/drivers/pci/pcie/aer.c
index ad3fea4b56f88..9ded8dacb62c9 100644
--- a/drivers/pci/pcie/aer.c
+++ b/drivers/pci/pcie/aer.c
@@ -1330,14 +1330,13 @@ static void aer_recover_work_func(struct work_struct *work)
while (kfifo_get(&aer_recover_ring, &entry)) {
pdev = pci_get_domain_bus_and_slot(entry.domain, entry.bus,
entry.devfn);
- if (!pdev) {
+ if (!pdev)
pr_err_ratelimited("%04x:%02x:%02x.%x: no pci_dev found\n",
entry.domain, entry.bus,
PCI_SLOT(entry.devfn),
PCI_FUNC(entry.devfn));
- continue;
- }
- pci_print_aer(pdev, entry.severity, entry.regs);
+ else
+ pci_print_aer(pdev, entry.severity, entry.regs);
/*
* Memory for aer_capability_regs(entry.regs) is being
@@ -1349,13 +1348,15 @@ static void aer_recover_work_func(struct work_struct *work)
ghes_estatus_pool_region_free((unsigned long)entry.regs,
sizeof(struct aer_capability_regs));
- if (entry.severity == AER_NONFATAL)
- pcie_do_recovery(pdev, pci_channel_io_normal,
- aer_root_reset);
- else if (entry.severity == AER_FATAL)
- pcie_do_recovery(pdev, pci_channel_io_frozen,
- aer_root_reset);
- pci_dev_put(pdev);
+ if (pdev) {
+ if (entry.severity == AER_NONFATAL)
+ pcie_do_recovery(pdev, pci_channel_io_normal,
+ aer_root_reset);
+ else if (entry.severity == AER_FATAL)
+ pcie_do_recovery(pdev, pci_channel_io_frozen,
+ aer_root_reset);
+ pci_dev_put(pdev);
+ }
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 156/686] mm/memcontrol: fix data-race on reading jiffies_64
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (154 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 155/686] PCI/AER: Fix memory leak in aer_recover_work_func() when pci_dev is missing Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 157/686] KVM: arm64: timers: Compute an offset-applied CVAL from the current count Greg Kroah-Hartman
` (529 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Andrew Morton,
syzbot+ced4d9a8cadb5ef3adae, Muchun Song, Johannes Weiner,
Michal Hocko, Chris Li, Jan Kara, Jens Axboe, Roman Gushchin,
Shakeel Butt, Tejun Heo, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit c20cf1c3c8cdd98618d6fcc794003a0e003ae858 ]
KCSAN reported a data-race between tick_do_update_jiffies64() updating
jiffies_64 and mem_cgroup_flush_stats_ratelimited() reading it directly.
Unlike jiffies, jiffies_64 is not volatile, so raw reads are plain
accesses and can even be torn on 32-bit. Use get_jiffies_64() instead,
and fix the same pattern in mem_cgroup_flush_foreign().
Link: https://lore.kernel.org/20260827025457.116191-1-jiayuan.chen@linux.dev
Fixes: 508bed884767 ("mm: memcg: change flush_next_time to flush_last_time")
Fixes: 97b27821b485 ("writeback, memcg: Implement foreign dirty flushing")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: syzbot+ced4d9a8cadb5ef3adae@syzkaller.appspotmail.com
Acked-by: Muchun Song <muchun.song@linux.dev>
Acked-by: Johannes Weiner <hannes@cmpxchg.org>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: Chris Li <chrisl@kernel.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Jens Axboe <axboe@kernel.dk>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Tejun Heo <tj@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memcontrol.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 2aa741316b49f..eec89dcb7801b 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -604,7 +604,7 @@ static void __mem_cgroup_flush_stats(struct mem_cgroup *memcg, bool force)
return;
if (mem_cgroup_is_root(memcg))
- WRITE_ONCE(flush_last_time, jiffies_64);
+ WRITE_ONCE(flush_last_time, get_jiffies_64());
css_rstat_flush(&memcg->css);
}
@@ -632,7 +632,7 @@ void mem_cgroup_flush_stats(struct mem_cgroup *memcg)
void mem_cgroup_flush_stats_ratelimited(struct mem_cgroup *memcg)
{
/* Only flush if the periodic flusher is one full cycle late */
- if (time_after64(jiffies_64, READ_ONCE(flush_last_time) + 2*FLUSH_TIME))
+ if (time_after64(get_jiffies_64(), READ_ONCE(flush_last_time) + 2 * FLUSH_TIME))
mem_cgroup_flush_stats(memcg);
}
@@ -3512,7 +3512,7 @@ void mem_cgroup_flush_foreign(struct bdi_writeback *wb)
{
struct mem_cgroup *memcg = mem_cgroup_from_css(wb->memcg_css);
unsigned long intv = msecs_to_jiffies(dirty_expire_interval * 10);
- u64 now = jiffies_64;
+ u64 now = get_jiffies_64();
int i;
for (i = 0; i < MEMCG_CGWB_FRN_CNT; i++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 157/686] KVM: arm64: timers: Compute an offset-applied CVAL from the current count
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (155 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 156/686] mm/memcontrol: fix data-race on reading jiffies_64 Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 158/686] wifi: mt76: take rcu_read_lock in the USB/SDIO tx completion path Greg Kroah-Hartman
` (528 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zenghui Yu, Fuad Tabba, Marc Zyngier,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <fuad.tabba@linux.dev>
[ Upstream commit 49930b1b557ceb698e0ab7f985ea41c99dc8bf22 ]
When the hardware won't apply a timer's offset, KVM programs CVAL +
offset and lets it compare that against the raw counter. The compare is
unsigned (IsTimerConditionMet, DDI0487M_c J1.4.3.29):
condition_met = (UInt(PhysicalCountInt() - offset) -
UInt(compare_value)) >= 0;
so adding the offset to both sides holds only while both sums wrap or
neither does. A guest whose counter is ahead of the host's by more than
CVAL has an expired timer that never fires, and one behind it can have
a far-future timer fire at once.
On a CNTPOFF_EL2 host the first case livelocks: each entry reloads the
guest's CVAL, the timer fires, and the exit rewrites it as CVAL + offset
before the host can take the interrupt. Without CNTPOFF_EL2 the timer
hangs until the vCPU is next loaded, which is what Zenghui reported on
a Kunpeng920.
Program the value from the current count instead: CVAL + offset while
the deadline is ahead, 0 once the timer has expired for the guest, ~0
past the counter's wrap. KVM recomputes it at load, at exit and on a
trapped CVAL write, and an expired timer stays expired in between. The
value can't be inverted, so with an offset timer_save_state() keeps the
memory copy, and kvm_hyp_handle_timer() returns that copy for a guest
hypervisor's read of its physical CVAL rather than subtracting the
offset back out.
Fixes: c605ee245097 ("KVM: arm64: timers: Allow physical offset without CNTPOFF_EL2")
Fixes: 9404673293b0 ("KVM: arm64: timers: Correctly handle TGE flip with CNTPOFF_EL2")
Fixes: 0bc9a9e85fcf ("KVM: arm64: Work around x1e's CNTVOFF_EL2 bogosity")
Reported-by: Zenghui Yu <yuzenghui@huawei.com>
Closes: https://lore.kernel.org/r/460258be-0102-e922-c342-4e87cd94b9e5@huawei.com
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20261007074343.324269-2-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/arch_timer.c | 27 ++++++++++++---------------
arch/arm64/kvm/hyp/vhe/switch.c | 11 ++++++-----
include/kvm/arm_arch_timer.h | 15 +++++++++++++++
3 files changed, 33 insertions(+), 20 deletions(-)
diff --git a/arch/arm64/kvm/arch_timer.c b/arch/arm64/kvm/arch_timer.c
index 3f675875abea2..e3348cfe74dba 100644
--- a/arch/arm64/kvm/arch_timer.c
+++ b/arch/arm64/kvm/arch_timer.c
@@ -502,17 +502,11 @@ static void timer_save_state(struct arch_timer_context *ctx)
goto out;
switch (index) {
- u64 cval;
-
case TIMER_VTIMER:
case TIMER_HVTIMER:
timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTV_CTL));
- cval = read_sysreg_el0(SYS_CNTV_CVAL);
-
- if (has_broken_cntvoff())
- cval -= timer_get_offset(ctx);
-
- timer_set_cval(ctx, cval);
+ if (!has_broken_cntvoff() || !timer_get_offset(ctx))
+ timer_set_cval(ctx, read_sysreg_el0(SYS_CNTV_CVAL));
/* Disable the timer */
write_sysreg_el0(0, SYS_CNTV_CTL);
@@ -538,11 +532,12 @@ static void timer_save_state(struct arch_timer_context *ctx)
case TIMER_PTIMER:
case TIMER_HPTIMER:
timer_set_ctl(ctx, read_sysreg_el0(SYS_CNTP_CTL));
- cval = read_sysreg_el0(SYS_CNTP_CVAL);
-
- cval -= timer_get_offset(ctx);
-
- timer_set_cval(ctx, cval);
+ /*
+ * With an offset, memory already holds the guest's CVAL (the
+ * trap handler or __deactivate_traps() wrote it).
+ */
+ if (!timer_get_offset(ctx))
+ timer_set_cval(ctx, read_sysreg_el0(SYS_CNTP_CVAL));
/* Disable the timer */
write_sysreg_el0(0, SYS_CNTP_CTL);
@@ -621,7 +616,8 @@ static void timer_restore_state(struct arch_timer_context *ctx)
offset = timer_get_offset(ctx);
if (has_broken_cntvoff()) {
set_cntvoff(0);
- cval += offset;
+ if (offset)
+ cval = timer_apply_offset(cval, offset, kvm_phys_timer_read());
} else {
set_cntvoff(offset);
}
@@ -634,7 +630,8 @@ static void timer_restore_state(struct arch_timer_context *ctx)
cval = timer_get_cval(ctx);
offset = timer_get_offset(ctx);
set_cntpoff(offset);
- cval += offset;
+ if (offset)
+ cval = timer_apply_offset(cval, offset, kvm_phys_timer_read());
write_sysreg_el0(cval, SYS_CNTP_CVAL);
isb();
write_sysreg_el0(timer_get_ctl(ctx), SYS_CNTP_CTL);
diff --git a/arch/arm64/kvm/hyp/vhe/switch.c b/arch/arm64/kvm/hyp/vhe/switch.c
index 552f39d913be1..7a69bc0b6ea81 100644
--- a/arch/arm64/kvm/hyp/vhe/switch.c
+++ b/arch/arm64/kvm/hyp/vhe/switch.c
@@ -169,7 +169,8 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
offset = read_sysreg_s(SYS_CNTPOFF_EL2);
if (map.direct_ptimer && offset) {
- write_sysreg_el0(val + offset, SYS_CNTP_CVAL);
+ val = timer_apply_offset(val, offset, arch_timer_read_cntpct_el0());
+ write_sysreg_el0(val, SYS_CNTP_CVAL);
isb();
}
}
@@ -290,10 +291,10 @@ static bool kvm_hyp_handle_timer(struct kvm_vcpu *vcpu, u64 *exit_code)
break;
case SYS_CNTP_CVAL_EL0:
if (vcpu_el2_e2h_is_set(vcpu)) {
- val = read_sysreg_el0(SYS_CNTP_CVAL);
-
- if (!has_cntpoff())
- val -= timer_get_offset(vcpu_hptimer(vcpu));
+ if (!has_cntpoff() && timer_get_offset(vcpu_hptimer(vcpu)))
+ val = __vcpu_sys_reg(vcpu, CNTHP_CVAL_EL2);
+ else
+ val = read_sysreg_el0(SYS_CNTP_CVAL);
} else {
val = __vcpu_sys_reg(vcpu, CNTP_CVAL_EL0);
}
diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h
index 7310841f45121..080096df87c76 100644
--- a/include/kvm/arm_arch_timer.h
+++ b/include/kvm/arm_arch_timer.h
@@ -186,4 +186,19 @@ static inline void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
WRITE_ONCE(*ctxt->offset.vm_offset, offset);
}
+/*
+ * CVAL to program when the hardware won't apply the timer's offset, so that
+ * its compare against the raw counter matches the guest's at 'now'. An
+ * expired timer stays expired; one past the wrap never fires.
+ */
+static inline u64 timer_apply_offset(u64 cval, u64 offset, u64 now)
+{
+ u64 hw = cval + offset;
+
+ if (now - offset >= cval)
+ return 0;
+
+ return hw > now ? hw : U64_MAX;
+}
+
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 158/686] wifi: mt76: take rcu_read_lock in the USB/SDIO tx completion path
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (156 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 157/686] KVM: arm64: timers: Compute an offset-applied CVAL from the current count Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 159/686] mm/page_counter: avoid integer overflow in effective_protection() Greg Kroah-Hartman
` (527 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Devin Wittmayer, Felix Fietkau,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devin Wittmayer <lucid_duck@justthetip.ca>
[ Upstream commit a7871a7ae5a8625f0ba0a89454ac734c383dd538 ]
The USB and SDIO completion path reads a station pointer that RCU
protects, without holding the read lock. Lockdep catches it on the
first association:
mt76.h:1305 suspicious rcu_dereference_check() usage!
no locks held by mt76-usb-status/1254.
mt7925_usb_sdio_tx_complete_skb+0x119/0x130 [mt7925_common]
mt76_queue_tx_complete+0x27/0x60 [mt76]
mt76u_status_worker+0xed/0x1e0 [mt76_usb]
mt7925/mac.c:856 suspicious rcu_dereference_check() usage!
mt7925_tx_check_aggr.part.0+0xc2/0xe0 [mt7925_common]
mt7925_usb_sdio_tx_complete_skb+0xa0/0x130 [mt7925_common]
mt7921 does the same, and warns once instead of twice because its
aggregation check reads the default link directly. The DMA path makes
the same reads but completes from softirq, so it stays quiet.
Take the read lock around the lookup and the check.
Tested on 7.2-rc5 with lockdep, fresh module load per arm, 4000
packets each and no change to the link:
splats before after
MT7925 Netgear A9000 2 0
MT7921 Alfa 1 0
mt7921e same kernel 0 0
Fixes: dc66a129adf1 ("wifi: mt76: add a wrapper for wcid access with validation")
Fixes: c22769de2509 ("wifi: mt76: mt7925u: use connac3 tx aggr check in tx complete")
Cc: stable@vger.kernel.org
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20261003233056.94497-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 3 +++
drivers/net/wireless/mediatek/mt76/mt7925/mac.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 0d48dbb2354f3..2af061a987f20 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -826,11 +826,14 @@ void mt7921_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
u16 idx;
idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
+
+ rcu_read_lock();
wcid = __mt76_wcid_ptr(mdev, idx);
sta = wcid_to_sta(wcid);
if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
mt76_connac2_tx_check_aggr(sta, txwi);
+ rcu_read_unlock();
skb_pull(e->skb, headroom);
mt76_tx_complete_skb(mdev, e->wcid, e->skb);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
index ce81ac1c2c635..4e41ef92d6239 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/mac.c
@@ -1476,11 +1476,14 @@ void mt7925_usb_sdio_tx_complete_skb(struct mt76_dev *mdev,
u16 idx;
idx = le32_get_bits(txwi[1], MT_TXD1_WLAN_IDX);
+
+ rcu_read_lock();
wcid = __mt76_wcid_ptr(mdev, idx);
sta = wcid_to_sta(wcid);
if (sta && likely(e->skb->protocol != cpu_to_be16(ETH_P_PAE)))
mt7925_tx_check_aggr(sta, e->skb, wcid);
+ rcu_read_unlock();
skb_pull(e->skb, headroom);
mt76_tx_complete_skb(mdev, e->wcid, e->skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 159/686] mm/page_counter: avoid integer overflow in effective_protection()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (157 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 158/686] wifi: mt76: take rcu_read_lock in the USB/SDIO tx completion path Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 160/686] ACPI: APEI: accumulate the queued flag across error sections Greg Kroah-Hartman
` (526 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Barry Song, Johannes Weiner,
Ridong Chen, Andrew Morton, Axel Rasmussen, Chris Down,
David Hildenbrand, Kairui Song, Lorenzo Stoakes, Michal Hocko,
Muchun Song, Roman Gushchin, Shakeel Butt, Tejun Heo, Wei Xu,
Yuanchu Xie, Yu Zhao, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridong Chen <chenridong@xiaomi.com>
[ Upstream commit 7809ce47b05671e1fa6d74bead892d6ad6c1403b ]
Patch series "mm/mglru: fix ineffective memory protection for non-kswapd
reclaim", v4.
For MGLRU, memory.min/low is not honored during non-kswapd global reclaim
(global direct reclaim and root-level memory.reclaim), because these paths
shrink memcgs using stale protection (emin/elow).
Patch 2 is the actual fix. Patch 1 is a prerequisite: an integer overflow
in effective_protection(), spotted by the sashiko review tool, which patch
2's new caller would also be exposed to.
This patch (of 2):
effective_protection() scales a parent's protection by a ratio of page
counts, e.g. for recursive protection:
(parent_effective - siblings_protected) * (usage - protected)
/ (parent_usage - siblings_protected)
The multiply is done at unsigned long width before dividing. On systems
with >= 16TB RAM the product can exceed 2^64 and wrap, giving a bogus
protection value and silently breaking memory.min/low enforcement.
Use mul_u64_u64_div_u64() to multiply in a 128-bit intermediate. Because
usage and parent_usage are not read atomically (a child is charged before
its parent), usage - protected can briefly exceed the divisor, making the
quotient overflow 64 bits and trap (#DE on x86). Cap it so the ratio
stays <= 1.
Reported by the sashiko review tool [1].
Link: https://lore.kernel.org/20260907025445.1836238-1-ridong.chen@linux.dev
Link: https://lore.kernel.org/20260907025445.1836238-2-ridong.chen@linux.dev
Link: https://sashiko.dev/#/patchset/20260826133054.88529-1-ridong.chen@linux.dev?part=1 [1]
Fixes: bc50bcc6e00b ("mm: memcontrol: clean up and document effective low/min calculations")
Fixes: 8a931f801340 ("mm: memcontrol: recursive memory.low protection")
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Assisted-by: Claude:claude-opus-4-8
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Chris Down <chris@chrisdown.name>
Cc: David Hildenbrand <david@kernel.org>
Cc: Kairui Song <kasong@tencent.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Tejun Heo <tj@kernel.org>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Yu Zhao <yuzhao@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page_counter.c | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/mm/page_counter.c b/mm/page_counter.c
index 661e0f2a5127a..ea0d1646cff85 100644
--- a/mm/page_counter.c
+++ b/mm/page_counter.c
@@ -8,6 +8,7 @@
#include <linux/page_counter.h>
#include <linux/atomic.h>
#include <linux/kernel.h>
+#include <linux/math64.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/bug.h>
@@ -356,7 +357,8 @@ static unsigned long effective_protection(unsigned long usage,
* otherwise get a smaller chunk than what they claimed.
*/
if (siblings_protected > parent_effective)
- return protected * parent_effective / siblings_protected;
+ return mul_u64_u64_div_u64(protected, parent_effective,
+ siblings_protected);
/*
* Ok, utilized protection of all children is within what the
@@ -397,13 +399,20 @@ static unsigned long effective_protection(unsigned long usage,
if (parent_effective > siblings_protected &&
parent_usage > siblings_protected &&
usage > protected) {
- unsigned long unclaimed;
+ unsigned long parent_unclaimed, parent_unprotected, unprotected;
- unclaimed = parent_effective - siblings_protected;
- unclaimed *= usage - protected;
- unclaimed /= parent_usage - siblings_protected;
+ parent_unclaimed = parent_effective - siblings_protected;
+ parent_unprotected = parent_usage - siblings_protected;
- ep += unclaimed;
+ /*
+ * The usages aren't read atomically, so a child can transiently
+ * appear to use more than its parent, making the ratio exceed 1
+ * and the quotient overflow 64 bits (#DE on x86). Cap it.
+ */
+ unprotected = min(usage - protected, parent_unprotected);
+
+ ep += mul_u64_u64_div_u64(parent_unclaimed, unprotected,
+ parent_unprotected);
}
return ep;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 160/686] ACPI: APEI: accumulate the queued flag across error sections
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (158 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 159/686] mm/page_counter: avoid integer overflow in effective_protection() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 161/686] fbdev: core: Initialize modelist in framebuffer_alloc() Greg Kroah-Hartman
` (525 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Shuai Xue,
Rafael J. Wysocki, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <leitao@debian.org>
[ Upstream commit f341307a14895e5da056fb419a31ef7fb534ab18 ]
ghes_do_proc() walks every error section of a CPER record, and
ghes_handle_arm_hw_error() walks every error-info entry of an ARM
processor section. Both assign to "queued" instead of OR-ing into it,
so only the last iteration counts: a later section or entry that queues
no memory-failure work clears the flag an earlier one set.
Instead of reassigning the variable at every time, just do an `OR`, so,
if there was a single match, it will return "queued" as set.
The comment above the check says "If no memory failure
work is queued", which is the semantics this patch implements. I.e, only
SIGBUS if there are queue was not handled at all. If we want to SIGBUS
if any event was not handled/queued at all, we will need something more
sophisticated.
Fixes: 7f17b4a121d0 ("ACPI: APEI: Kick the memory_failure() queue for synchronous errors")
Fixes: ccb5ecdc2dde ("ACPI: APEI: fix synchronous external aborts in user-mode")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
Link: https://patch.msgid.link/20260925-ghes-queued-accumulate-v1-1-df50553957d4@debian.org
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/acpi/apei/ghes.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index 1a77aba0475be..f301bee643318 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -608,7 +608,7 @@ static bool ghes_handle_arm_hw_error(struct acpi_hest_generic_data *gdata,
* and don't filter out 'corrected' error here.
*/
if (is_cache && has_pa) {
- queued = ghes_do_memory_failure(err_info->physical_fault_addr, flags);
+ queued |= ghes_do_memory_failure(err_info->physical_fault_addr, flags);
p += err_info->length;
continue;
}
@@ -925,11 +925,11 @@ static void ghes_do_proc(struct ghes *ghes,
atomic_notifier_call_chain(&ghes_report_chain, sev, mem_err);
arch_apei_report_mem_error(sev, mem_err);
- queued = ghes_handle_memory_failure(gdata, sev, sync);
+ queued |= ghes_handle_memory_failure(gdata, sev, sync);
} else if (guid_equal(sec_type, &CPER_SEC_PCIE)) {
ghes_handle_aer(gdata);
} else if (guid_equal(sec_type, &CPER_SEC_PROC_ARM)) {
- queued = ghes_handle_arm_hw_error(gdata, sev, sync);
+ queued |= ghes_handle_arm_hw_error(gdata, sev, sync);
} else if (guid_equal(sec_type, &CPER_SEC_CXL_PROT_ERR)) {
struct cxl_cper_sec_prot_err *prot_err = acpi_hest_get_payload(gdata);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 161/686] fbdev: core: Initialize modelist in framebuffer_alloc()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (159 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 160/686] ACPI: APEI: accumulate the queued flag across error sections Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 162/686] mfd: ab8500: Fix child device leaks on probe failure Greg Kroah-Hartman
` (524 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrey Misiurov, Helge Deller,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Misiurov <andrey.misyrov@gmail.com>
[ Upstream commit 0c9cb9321cb3863b52bdea4b8ae5a27705762c9e ]
framebuffer_alloc() returns zeroed memory, so info->modelist starts out
with NULL next and prev pointers. The list head is initialized only
later, by fb_videomode_to_modelist() or by do_register_framebuffer().
The "fix potential memory leak" commits listed below added
fb_destroy_modelist(&info->modelist) to the probe error paths of s3fb,
tdfxfb, tridentfb, i740fb and carminefb. These paths can run before
the list head is initialized:
- s3fb, tdfxfb, tridentfb and i740fb call fb_videomode_to_modelist()
only after a successful EDID read, and tridentfb can also hit the
error path on an ioremap() or kmalloc() failure before that;
- carminefb jumps to the error path when fb_find_mode() fails, before
its fb_videomode_to_modelist() call.
fb_destroy_modelist() then dereferences the NULL head. Reproduced on
Debian 12 (6.1.180) by binding s3fb to a VGA device without EDID and
forcing fb_alloc_cmap() to fail:
s3fb 0000:00:03.0: cannot allocate colormap
BUG: kernel NULL pointer dereference, address: 0000000000000000
RIP: 0010:fb_destroy_modelist+0x10/0x80
Call Trace:
s3_pci_probe.cold+0x12b/0x2bf [s3fb]
local_pci_probe+0x41/0x80
pci_device_probe+0xc3/0x240
really_probe+0xde/0x380
__driver_probe_device+0x84/0x150
driver_probe_device+0x1f/0x90
__driver_attach+0xce/0x1c0
bus_for_each_dev+0x87/0xd0
bus_add_driver+0x1ae/0x200
driver_register+0x89/0xe0
do_one_initcall+0x59/0x220
do_init_module+0x4a/0x1f0
Initialize the list head in framebuffer_alloc(), so info->modelist is
always a valid, possibly empty, list and fb_destroy_modelist() is safe
on every error path. Keep the lazy initialization in
do_register_framebuffer(), as drivers that embed struct fb_info rather
than calling framebuffer_alloc() still depend on it.
Fixes: 3b0ed04bc852 ("fbdev: s3fb: fix potential memory leak in s3_pci_probe()")
Fixes: bb019d755366 ("fbdev: tdfxfb: fix potential memory leak in tdfxfb_probe()")
Fixes: 7a35ec619d9a ("fbdev: tridentfb: fix potential memory leak in trident_pci_probe()")
Fixes: 5936063409af ("fbdev: i740fb: fix potential memory leak in i740fb_probe()")
Fixes: 6fcca16a2b19 ("fbdev: carminefb: fix potential memory leak in alloc_carmine_fb()")
Cc: stable@vger.kernel.org
Signed-off-by: Andrey Misiurov <andrey.misyrov@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/video/fbdev/core/fb_info.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/fbdev/core/fb_info.c b/drivers/video/fbdev/core/fb_info.c
index 52f9bd2c5417a..05988a936bebb 100644
--- a/drivers/video/fbdev/core/fb_info.c
+++ b/drivers/video/fbdev/core/fb_info.c
@@ -43,6 +43,7 @@ struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
info->device = dev;
info->fbcon_rotate_hint = -1;
info->blank = FB_BLANK_UNBLANK;
+ INIT_LIST_HEAD(&info->modelist);
#if IS_ENABLED(CONFIG_FB_BACKLIGHT)
mutex_init(&info->bl_curve_mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 162/686] mfd: ab8500: Fix child device leaks on probe failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (160 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 161/686] fbdev: core: Initialize modelist in framebuffer_alloc() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 163/686] Bluetooth: selftest: Pin module for selftest debugfs file operations Greg Kroah-Hartman
` (523 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Lee Jones, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
[ Upstream commit 5bf2ae8b131d4ae9c0ed5f7aa02532645f512022 ]
ab8500_probe() registers MFD child devices before completing the
remaining device initialization. If a later MFD registration or sysfs
group creation fails, previously registered child devices are not
removed.
Use devm_mfd_add_devices() so registered MFD child devices are removed
when probe fails.
The issue was identified by a static analysis tool I developed and
confirmed by manual review.
Fixes: cca69b67b3ba ("mfd: Export ab8500 chip id to sysfs")
Fixes: 9c717cf3fa16 ("mfd: ab8500-core: Add device for new RTC version for AB8540 cut2")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Link: https://patch.msgid.link/20260924144355.1604369-1-lgs201920130244@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mfd/ab8500-core.c | 44 ++++++++++++++++++++-------------------
1 file changed, 23 insertions(+), 21 deletions(-)
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 86fa99022cb35..44fc2ce83cdd7 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -1194,39 +1194,41 @@ static int ab8500_probe(struct platform_device *pdev)
return ret;
if (is_ab9540(ab8500))
- ret = mfd_add_devices(ab8500->dev, 0, ab9540_devs,
- ARRAY_SIZE(ab9540_devs), NULL,
- 0, ab8500->domain);
+ ret = devm_mfd_add_devices(ab8500->dev, 0, ab9540_devs,
+ ARRAY_SIZE(ab9540_devs), NULL,
+ 0, ab8500->domain);
else if (is_ab8540(ab8500)) {
- ret = mfd_add_devices(ab8500->dev, 0, ab8540_devs,
- ARRAY_SIZE(ab8540_devs), NULL,
- 0, ab8500->domain);
+ ret = devm_mfd_add_devices(ab8500->dev, 0, ab8540_devs,
+ ARRAY_SIZE(ab8540_devs), NULL,
+ 0, ab8500->domain);
if (ret)
return ret;
if (is_ab8540_1p2_or_earlier(ab8500))
- ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut1_devs,
- ARRAY_SIZE(ab8540_cut1_devs), NULL,
- 0, ab8500->domain);
+ ret = devm_mfd_add_devices(ab8500->dev, 0,
+ ab8540_cut1_devs,
+ ARRAY_SIZE(ab8540_cut1_devs),
+ NULL, 0, ab8500->domain);
else /* ab8540 >= cut2 */
- ret = mfd_add_devices(ab8500->dev, 0, ab8540_cut2_devs,
- ARRAY_SIZE(ab8540_cut2_devs), NULL,
- 0, ab8500->domain);
+ ret = devm_mfd_add_devices(ab8500->dev, 0,
+ ab8540_cut2_devs,
+ ARRAY_SIZE(ab8540_cut2_devs),
+ NULL, 0, ab8500->domain);
} else if (is_ab8505(ab8500))
- ret = mfd_add_devices(ab8500->dev, 0, ab8505_devs,
- ARRAY_SIZE(ab8505_devs), NULL,
- 0, ab8500->domain);
+ ret = devm_mfd_add_devices(ab8500->dev, 0, ab8505_devs,
+ ARRAY_SIZE(ab8505_devs), NULL,
+ 0, ab8500->domain);
else
- ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
- ARRAY_SIZE(ab8500_devs), NULL,
- 0, ab8500->domain);
+ ret = devm_mfd_add_devices(ab8500->dev, 0, ab8500_devs,
+ ARRAY_SIZE(ab8500_devs), NULL,
+ 0, ab8500->domain);
if (ret)
return ret;
/* Add battery management devices */
- ret = mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
- ARRAY_SIZE(ab8500_bm_devs), NULL,
- 0, ab8500->domain);
+ ret = devm_mfd_add_devices(ab8500->dev, 0, ab8500_bm_devs,
+ ARRAY_SIZE(ab8500_bm_devs), NULL,
+ 0, ab8500->domain);
if (ret)
dev_err(ab8500->dev, "error adding bm devices\n");
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 163/686] Bluetooth: selftest: Pin module for selftest debugfs file operations
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (161 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 162/686] mfd: ab8500: Fix child device leaks on probe failure Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 164/686] cxl/events: Test CME counter expiry with equality, not bitwise AND Greg Kroah-Hartman
` (522 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bui Viet Dung,
Luiz Augusto von Dentz, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bui Viet Dung <dungvn2345@gmail.com>
[ Upstream commit 64aabf94ecccb1120a63b4ee5a6761871a181a41 ]
An open debugfs file retains its file_operations pointer in the
debugfs proxy state. However, test_smp_fops in net/bluetooth/smp.c and
test_ecdh_fops in net/bluetooth/selftest.c have no .owner set to
THIS_MODULE.
As a result, full_proxy_open_regular() calls fops_get() which succeeds
without taking a reference to the bluetooth module. When CONFIG_BT=m
and selftests are enabled, a userspace process can open either
/sys/kernel/debug/bluetooth/selftest_smp or
/sys/kernel/debug/bluetooth/selftest_ecdh and keep the file descriptor
open while the module is unloaded (rmmod bluetooth).
When the userspace process subsequently closes the descriptor,
full_proxy_release() accesses the already unmapped file_operations
structure, triggering a kernel oops in full_proxy_release():
BUG: unable to handle page fault for address: fffffbfff8056f03
#PF: supervisor read access in kernel mode
Oops: 0000 [#1] SMP KASAN NOPTI
RIP: 0010:full_proxy_release+0x8e/0x140
Call Trace:
<TASK>
__fput+0x39f/0xa60
fput_close_sync+0xff/0x200
__x64_sys_close+0x8c/0xf0
do_syscall_64+0x115/0x6a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
The issue was discovered via manual code audit of net/bluetooth/smp.c
and net/bluetooth/selftest.c.
Set .owner = THIS_MODULE on test_smp_fops and test_ecdh_fops so that
debugfs keeps the module pinned until the file descriptors are closed.
Fixes: 64dd374eac15 ("Bluetooth: Export SMP selftest result in debugfs")
Fixes: 6de50f9fdb60 ("Bluetooth: Export ECDH selftest result in debugfs")
Cc: stable@vger.kernel.org
Signed-off-by: Bui Viet Dung <dungvn2345@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/selftest.c | 1 +
net/bluetooth/smp.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/net/bluetooth/selftest.c b/net/bluetooth/selftest.c
index f49604d44b877..6abf70c14f598 100644
--- a/net/bluetooth/selftest.c
+++ b/net/bluetooth/selftest.c
@@ -191,6 +191,7 @@ static ssize_t test_ecdh_read(struct file *file, char __user *user_buf,
}
static const struct file_operations test_ecdh_fops = {
+ .owner = THIS_MODULE,
.open = simple_open,
.read = test_ecdh_read,
.llseek = default_llseek,
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 81bf67af87fcb..e4cdbb7df16a7 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -3735,6 +3735,7 @@ static ssize_t test_smp_read(struct file *file, char __user *user_buf,
}
static const struct file_operations test_smp_fops = {
+ .owner = THIS_MODULE,
.open = simple_open,
.read = test_smp_read,
.llseek = default_llseek,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 164/686] cxl/events: Test CME counter expiry with equality, not bitwise AND
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (162 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 163/686] Bluetooth: selftest: Pin module for selftest debugfs file operations Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 165/686] tracing: Add the bucket size to expr_field_str() Greg Kroah-Hartman
` (521 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guixin Liu, Dave Jiang,
Jonathan Cameron, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guixin Liu <kanie@linux.alibaba.com>
[ Upstream commit b94ba9a1f2d5c57f2eec67d502bb8fdd1e53c87a ]
The Memory Event Type field in the General Media and DRAM event records
is an enumeration, not a bitmask. The validity checks for the advanced
programmable CME counter expiration event (05h) test the field with a
bitwise AND, so types 01h, 03h, 04h and 06h match it as well.
A device reporting one of those types trips WARN_ON_ONCE once the
general media or DRAM tracepoint is enabled, which is the case anywhere
rasdaemon collects CXL events. Under panic_on_warn=1 that kills the
machine.
Compare the type field for equality instead. Type 05h records that do
violate the spec conditions still warn.
Fixes: cd3b36cfc659 ("cxl/events: Add extra validity checks for corrected memory error count in General Media Event Record")
Fixes: d8145bb8af5c ("cxl/events: Add extra validity checks for CVME count in DRAM Event Record")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Guixin Liu <kanie@linux.alibaba.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Link: https://patch.msgid.link/20260922082214.3526355-1-kanie@linux.alibaba.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cxl/core/mbox.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/cxl/core/mbox.c b/drivers/cxl/core/mbox.c
index 76731576ebfcc..161a56169f878 100644
--- a/drivers/cxl/core/mbox.c
+++ b/drivers/cxl/core/mbox.c
@@ -934,11 +934,11 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
if (evt->gen_media.media_hdr.descriptor &
CXL_GMER_EVT_DESC_THRESHOLD_EVENT)
- WARN_ON_ONCE((evt->gen_media.media_hdr.type &
+ WARN_ON_ONCE((evt->gen_media.media_hdr.type ==
CXL_GMER_MEM_EVT_TYPE_AP_CME_COUNTER_EXPIRE) &&
!get_unaligned_le24(evt->gen_media.cme_count));
else
- WARN_ON_ONCE(evt->gen_media.media_hdr.type &
+ WARN_ON_ONCE(evt->gen_media.media_hdr.type ==
CXL_GMER_MEM_EVT_TYPE_AP_CME_COUNTER_EXPIRE);
trace_cxl_general_media(cxlmd, type, cxlr, hpa,
@@ -949,11 +949,11 @@ void cxl_event_trace_record(const struct cxl_memdev *cxlmd,
if (evt->dram.media_hdr.descriptor &
CXL_GMER_EVT_DESC_THRESHOLD_EVENT)
- WARN_ON_ONCE((evt->dram.media_hdr.type &
+ WARN_ON_ONCE((evt->dram.media_hdr.type ==
CXL_DER_MEM_EVT_TYPE_AP_CME_COUNTER_EXPIRE) &&
!get_unaligned_le24(evt->dram.cvme_count));
else
- WARN_ON_ONCE(evt->dram.media_hdr.type &
+ WARN_ON_ONCE(evt->dram.media_hdr.type ==
CXL_DER_MEM_EVT_TYPE_AP_CME_COUNTER_EXPIRE);
trace_cxl_dram(cxlmd, type, cxlr, hpa, hpa_alias,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 165/686] tracing: Add the bucket size to expr_field_str()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (163 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 164/686] cxl/events: Test CME counter expiry with equality, not bitwise AND Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 166/686] net: erspan: set lltx to avoid sch_direct_xmit deadlock Greg Kroah-Hartman
` (520 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
[ Upstream commit c027ed03bc03a0e82fc368eaad657584a4480c7a ]
expr_field_str() renders a HIST_FIELD_FL_BUCKET field as "pid.buckets",
dropping the count, and parse_field() rejects that spelling.
get_hist_field_flags() returns the bare string "buckets" and keeps the
count in hist_field->buckets. hist_field_print() appends it,
expr_field_str() never did. Nothing reaches it today, since .buckets is
refused on a value and no expression can carry one, but the next patch
renders histogram keys with expr_field_str(), where a .buckets key is
legal.
Append the count, as hist_field_print() does.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260914053443.981201-3-donggeunyoo.kernel@gmail.com
Fixes: de9a48a360b7 ("tracing: Add linear buckets to histogram logic")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Assisted-by: Claude:claude-fable-5
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/trace_events_hist.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/trace/trace_events_hist.c b/kernel/trace/trace_events_hist.c
index 882e10e776fe4..93afc706e4029 100644
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -1757,6 +1757,9 @@ static bool expr_field_str(struct hist_field *field, struct seq_buf *s)
seq_buf_printf(s, ".%s", flags_str);
}
+ if (field->buckets)
+ seq_buf_printf(s, "=%lu", field->buckets);
+
return !seq_buf_has_overflowed(s);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 166/686] net: erspan: set lltx to avoid sch_direct_xmit deadlock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (164 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 165/686] tracing: Add the bucket size to expr_field_str() Greg Kroah-Hartman
@ 2026-11-13 15:44 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 167/686] rds: fix out-of-bounds conn_path walks via handshake exthdrs Greg Kroah-Hartman
` (519 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:44 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+9bda1b9fbb7fbdf9b62b,
Yun Zhou, Ido Schimmel, Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yun Zhou <yun.zhou@windriver.com>
[ Upstream commit 2d36ec73836e83175deb467fd494c61006107e5d ]
The ERSPAN xmit path re-enters the network stack, causing nested
acquisition of _xmit_lock on the underlay device while already holding
the ERSPAN device's _xmit_lock, creating an ABBA deadlock. This happens
for both IPv4 ERSPAN (erspan_xmit() -> ip_tunnel_xmit()) and IPv6 ERSPAN
(ip6erspan_tunnel_xmit() -> ip6_tnl_xmit()):
sch_direct_xmit [lock erspan] -> erspan_xmit -> ip_tunnel_xmit ->
ip_output -> __dev_queue_xmit -> sch_direct_xmit [lock underlay]
sch_direct_xmit [lock erspan] -> ip6erspan_tunnel_xmit -> ip6_tnl_xmit ->
ip6_output -> __dev_queue_xmit -> sch_direct_xmit [lock underlay]
Set dev->lltx = true so HARD_TX_LOCK() skips the spinlock for ERSPAN.
This is safe as the ERSPAN xmit path has no shared mutable state: o_seqno
is atomic, TX stats are per-CPU u64_stats, dst_cache is per-CPU, and
o_flags is no longer modified in the xmit path since commit 9958e69b9893
("gre: fix ERSPAN o_flags race/corruption in xmit and fill_info").
GRETAP, the sibling device with identical xmit structure, already sets
lltx.
Reported-by: syzbot+9bda1b9fbb7fbdf9b62b@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=9bda1b9fbb7fbdf9b62b
Fixes: 84e54fe0a5ea ("gre: introduce native tunnel support for ERSPAN")
Fixes: 5a963eb61b7c ("ip6_gre: Add ERSPAN native tunnel support")
Cc: stable@vger.kernel.org # 9958e69b9893 ("gre: fix ERSPAN o_flags race/corruption in xmit and fill_info")
Cc: stable@vger.kernel.org
Signed-off-by: Yun Zhou <yun.zhou@windriver.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20261008093824.119453-1-yun.zhou@windriver.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ip_gre.c | 1 +
net/ipv6/ip6_gre.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index b1ec4f92d3462..7df1ada13c2a1 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -1366,6 +1366,7 @@ static int erspan_tunnel_init(struct net_device *dev)
dev->features |= GRE_FEATURES;
dev->hw_features |= GRE_FEATURES;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ dev->lltx = true;
netif_keep_dst(dev);
return ip_tunnel_init(dev);
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index c14c76b78b984..17c5e9440bfa3 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -1863,6 +1863,7 @@ static int ip6erspan_tap_init(struct net_device *dev)
dev->mtu -= 8;
dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ dev->lltx = true;
ip6erspan_tnl_link_config(tunnel, 1);
netdev_hold(dev, &tunnel->dev_tracker, GFP_KERNEL);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 167/686] rds: fix out-of-bounds conn_path walks via handshake exthdrs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (165 preceding siblings ...)
2026-11-13 15:44 ` [PATCH 6.18 166/686] net: erspan: set lltx to avoid sch_direct_xmit deadlock Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 168/686] gpio: pca953x: Preserve wakeup accounting on parent IRQ failure Greg Kroah-Hartman
` (518 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Henry Martin, Allison Henderson,
Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin <bsdhenrymartin@gmail.com>
[ Upstream commit 50f2103fce43922b6e562937b2d2fc62089ff7ec ]
Both the lane and the connection-generation negotiation are driven by
extension headers in handshake packets, and both are processed
unconditionally, even on transports that are not multipath capable.
A non-MP connection (t_mp_capable unset) owns exactly one
rds_conn_path slot, so a peer claiming up to RDS_MPATH_WORKERS lanes
makes every subsequent fan-out walk conn->c_path[0..7] at 504-byte
strides past the single allocated slot (KASAN: "Read of size 8 in
rds_conn_path_connect_if_down"); the generation negotiation opens a
similar out-of-bounds walk on the same array.
Only process handshake extension headers when the connection's
transport is multipath capable, so a peer can never make us walk
lanes that do not exist. Both call sites in rds_recv_incoming() are
gated.
This is a port of the Oracle UEK fix for the same issue, picked up
where Paula's series of the same change left off.
This issue was discovered by Tencent CodeBuddy Security.
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/netdev/20260825120132.51636-1-pamoutafpro@gmail.com/
Link: https://github.com/oracle/linux-uek/commit/2fdeb0513f18
Fixes: 840df162b3eb ("rds: reduce memory footprint for RDS when transport is RDMA")
Fixes: 905dd4184e07 ("RDS: TCP: Track peer's connection generation number")
Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
Reviewed-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20261012025336.54756-1-bsdhenrymartin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/recv.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/rds/recv.c b/net/rds/recv.c
index 4b12fa4f1e786..c400cc5ea3605 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -343,7 +343,8 @@ void rds_recv_incoming(struct rds_connection *conn, struct in6_addr *saddr,
rds_stats_inc(s_recv_ping);
rds_send_pong(cp, inc->i_hdr.h_sport);
/* if this is a handshake ping, start multipath if necessary */
- if (RDS_HS_PROBE(be16_to_cpu(inc->i_hdr.h_sport),
+ if (conn->c_trans->t_mp_capable &&
+ RDS_HS_PROBE(be16_to_cpu(inc->i_hdr.h_sport),
be16_to_cpu(inc->i_hdr.h_dport))) {
rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn);
rds_start_mprds(cp->cp_conn);
@@ -351,7 +352,8 @@ void rds_recv_incoming(struct rds_connection *conn, struct in6_addr *saddr,
goto out;
}
- if (be16_to_cpu(inc->i_hdr.h_dport) == RDS_FLAG_PROBE_PORT &&
+ if (conn->c_trans->t_mp_capable &&
+ be16_to_cpu(inc->i_hdr.h_dport) == RDS_FLAG_PROBE_PORT &&
inc->i_hdr.h_sport == 0) {
rds_recv_hs_exthdrs(&inc->i_hdr, cp->cp_conn);
/* if this is a handshake pong, start multipath if necessary */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 168/686] gpio: pca953x: Preserve wakeup accounting on parent IRQ failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (166 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 167/686] rds: fix out-of-bounds conn_path walks via handshake exthdrs Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 169/686] f2fs: dont use truncate_inode_pages_final() on live inodes Greg Kroah-Hartman
` (517 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sahaj Chaudhari, Geert Uytterhoeven,
Bartosz Golaszewski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sahaj Chaudhari <sahaj123.sc@gmail.com>
[ Upstream commit a38bf551726a21c9bcc001b02164f30378b64b64 ]
pca953x_irq_set_wake() updates wakeup_path before asking the parent
IRQ controller to change its wake state. If irq_set_irq_wake() fails,
the IRQ core rolls back its wake state but the driver's counter remains
changed.
A failed enable can therefore leave the expander marked as part of the
wakeup path when no child IRQ has successfully enabled wakeup. A failed
disable can make the driver stop retaining power even though wakeup is
still enabled. The suspend and resume paths use this counter to decide
whether to disable or enable the regulator.
Update wakeup_path only after the parent operation succeeds, leaving it
unchanged on error.
Fixes: f70fbc15bae2 ("gpio: pca953x: Configure wake-up path when wake-up is enabled")
Cc: stable@vger.kernel.org
Signed-off-by: Sahaj Chaudhari <sahaj123.sc@gmail.com>
Fixes: f70fbc15bae2c89f ("gpio: pca953x: Configure wake-up path when wake-up is enabled")
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/20261018161042.3298045-1-sahaj123.sc@gmail.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpio/gpio-pca953x.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
index 7ebc4f9662c91..99b7bc2629580 100644
--- a/drivers/gpio/gpio-pca953x.c
+++ b/drivers/gpio/gpio-pca953x.c
@@ -839,13 +839,18 @@ static int pca953x_irq_set_wake(struct irq_data *d, unsigned int on)
{
struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
struct pca953x_chip *chip = gpiochip_get_data(gc);
+ int ret;
+
+ ret = irq_set_irq_wake(chip->client->irq, on);
+ if (ret)
+ return ret;
if (on)
atomic_inc(&chip->wakeup_path);
else
atomic_dec(&chip->wakeup_path);
- return irq_set_irq_wake(chip->client->irq, on);
+ return 0;
}
static void pca953x_irq_bus_lock(struct irq_data *d)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 169/686] f2fs: dont use truncate_inode_pages_final() on live inodes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (167 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 168/686] gpio: pca953x: Preserve wakeup accounting on parent IRQ failure Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 170/686] scsi: ufs: bsg: Validate request_len before accessing request Greg Kroah-Hartman
` (516 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Daeho Jeong, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daeho Jeong <daehojeong@google.com>
[ Upstream commit 74bbd6ada01f91fcad60608e0417bf45a9fa99e6 ]
truncate_inode_pages_final() is meant to be called from ->evict_inode.
It sets AS_EXITING on the mapping, and nothing ever clears it, to tell
the VM that the inode is going away.
f2fs calls it in two places where the inode stays live:
- F2FS_IOC_START_ATOMIC_REPLACE uses it to drop the page cache of the
original inode before setting i_size to 0. The atomic write then
goes on through this inode.
- f2fs_abort_atomic_write() uses it to drop the uncommitted data. It
is called on eviction, but also on the last writer's close in
f2fs_release_file(), from f2fs_file_flush() when the atomic writer
exits, from F2FS_IOC_ABORT_ATOMIC_WRITE and when
F2FS_IOC_COMMIT_ATOMIC_WRITE fails.
Other processes may still have the file open or mapped in all of these
cases. The mapping then stays marked as exiting for as long as the
inode is in memory. This stops reclaim from storing workingset shadow
entries for it and breaks any code that assumes an exiting mapping has
no users left.
All we need in both places is to drop the page cache, so use
truncate_inode_pages(mapping, 0) instead. The eviction path is not
affected, because f2fs_pre_evict_inode() still calls
truncate_inode_pages_final() after f2fs_abort_atomic_write().
Cc: stable@kernel.org
Fixes: 3db1de0e582c ("f2fs: change the current atomic write way")
Fixes: 41e8f85a75fc ("f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE")
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/file.c | 2 +-
fs/f2fs/segment.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index 8211ee75fb8f7..d6798d795e3d3 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -2431,7 +2431,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp, bool truncate)
fi->original_i_size = isize;
if (truncate) {
set_inode_flag(inode, FI_ATOMIC_REPLACE);
- truncate_inode_pages_final(inode->i_mapping);
+ truncate_inode_pages(inode->i_mapping, 0);
f2fs_i_size_write(inode, 0);
isize = 0;
}
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 46f14f891843c..c0ec2715408e8 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -193,7 +193,7 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean)
return;
if (clean)
- truncate_inode_pages_final(inode->i_mapping);
+ truncate_inode_pages(inode->i_mapping, 0);
release_atomic_write_cnt(inode);
clear_inode_flag(inode, FI_ATOMIC_COMMITTED);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 170/686] scsi: ufs: bsg: Validate request_len before accessing request
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (168 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 169/686] f2fs: dont use truncate_inode_pages_final() on live inodes Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 171/686] scsi: ufs: bsg: Reject UIC commands with a non-zero result byte Greg Kroah-Hartman
` (515 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bean Huo, Stanley Jhu, Peter Wang,
Bart Van Assche, Martin K. Petersen (Oracle), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanley Jhu <stanleyjhu@google.com>
[ Upstream commit 42aa443718104d10dbdb6f258810b425eb2451f8 ]
ufs_bsg_request() and ufs_bsg_exec_advanced_rpmb_req() read the request
buffer without checking job->request_len, which userspace controls. A short
request causes an out-of-bounds read. Found by syzkaller.
Reject requests shorter than the structure each path reads.
Fixes: 64d4864714c2 ("scsi: ufs: bsg: Remove unnecessary length checkup")
Fixes: 6ff265fc5ef6 ("scsi: ufs: core: bsg: Add advanced RPMB support in ufs_bsg")
Cc: stable@vger.kernel.org
Reviewed-by: Bean Huo <beanhuo@micron.com>
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20261015001855.3450573-4-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/core/ufs_bsg.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c
index 0e0b08a3821c4..36def5ef24d62 100644
--- a/drivers/ufs/core/ufs_bsg.c
+++ b/drivers/ufs/core/ufs_bsg.c
@@ -79,6 +79,9 @@ static int ufs_bsg_exec_advanced_rpmb_req(struct ufs_hba *hba, struct bsg_job *j
if (hba->ufs_version < ufshci_version(4, 0) || !hba->dev_info.b_advanced_rpmb_en)
return -EINVAL;
+ if (job->request_len < sizeof(*rpmb_request))
+ return -EINVAL;
+
if (rpmb_request->ehs_req.length != 2 || rpmb_request->ehs_req.ehs_type != 1)
return -EINVAL;
@@ -144,6 +147,11 @@ static int ufs_bsg_request(struct bsg_job *job)
memset(job->reply, 0, job->reply_len);
+ if (job->request_len < sizeof(*bsg_request)) {
+ ret = -EINVAL;
+ goto out_complete;
+ }
+
ufshcd_rpm_get_sync(hba);
msgcode = bsg_request->msgcode;
@@ -193,6 +201,7 @@ static int ufs_bsg_request(struct bsg_job *job)
out:
ufshcd_rpm_put_sync(hba);
kfree(buff);
+out_complete:
bsg_reply->result = ret;
if (ret == 0)
job->reply_len = rpmb ? sizeof(struct ufs_rpmb_reply) :
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 171/686] scsi: ufs: bsg: Reject UIC commands with a non-zero result byte
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (169 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 170/686] scsi: ufs: bsg: Validate request_len before accessing request Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 172/686] scsi: handle out-of-range SG_SET_TIMEOUT values Greg Kroah-Hartman
` (514 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stanley Jhu, Bean Huo, Peter Wang,
Bart Van Assche, Martin K. Petersen (Oracle), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanley Jhu <stanleyjhu@google.com>
[ Upstream commit 1ae42513205a38b811afedb6797f9f9c4de37b90 ]
ufs_bsg_request() passes the user-supplied UIC argument2 unchanged,
including the result byte (bits 7:0) that only the host controller
writes. A non-zero value triggers the WARN_ON_ONCE() in
ufshcd_dispatch_uic_cmd() and corrupts the reported result. Found by
syzkaller.
Reject UIC commands that have the result byte set with -EINVAL.
Fixes: e77044c5a842 ("scsi: ufs-bsg: Add support for uic commands in ufs_bsg_request()")
Fixes: 9fb4c793223b ("scsi: ufs: core: Complain if UIC argument 2 is invalid")
Cc: stable@vger.kernel.org
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20261015001855.3450573-5-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/core/ufs_bsg.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c
index 36def5ef24d62..59a473261ae16 100644
--- a/drivers/ufs/core/ufs_bsg.c
+++ b/drivers/ufs/core/ufs_bsg.c
@@ -178,6 +178,10 @@ static int ufs_bsg_request(struct bsg_job *job)
break;
case UPIU_TRANSACTION_UIC_CMD:
memcpy(&uc, &bsg_request->upiu_req.uc, UIC_CMD_SIZE);
+ if (uc.argument2 & MASK_UIC_COMMAND_RESULT) {
+ ret = -EINVAL;
+ break;
+ }
ret = ufshcd_send_bsg_uic_cmd(hba, &uc);
if (ret)
dev_err(hba->dev, "send uic cmd: error code %d\n", ret);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 172/686] scsi: handle out-of-range SG_SET_TIMEOUT values
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (170 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 171/686] scsi: ufs: bsg: Reject UIC commands with a non-zero result byte Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 173/686] posix-timers: Accept NULL clock_getres() output in stubs Greg Kroah-Hartman
` (513 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bart Van Assche, Yingjie Wang,
Martin K. Petersen (Oracle), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingjie Wang <x-professor@outlook.com>
[ Upstream commit 9a6cb1da4f3bc4633bf6669faed25a361834b1b9 ]
SG_SET_TIMEOUT accepts a signed int in USER_HZ units. The sg character
device rejects negative values and limits positive values so the converted
timeout fits its destination field. The block SCSI and BSG paths instead
pass the value to clock_t_to_jiffies(), which accepts an unsigned long, and
store the result in an unsigned int.
Negative values are converted into large unsigned timeouts. On 64-bit
systems, large positive values can also exceed UINT_MAX after conversion
and are truncated on assignment. With HZ=1000 and USER_HZ=100, for example,
429496730 clock ticks become 4294967300 jiffies and are stored as 4
jiffies. On 32-bit systems, an overflowing conversion becomes ULONG_MAX,
which is an unsafe relative interval for the block timer comparisons.
Reject negative values with -EIO, matching drivers/scsi/sg.c. Saturate the
converted value at the smaller of the destination field limit and
MAX_JIFFY_OFFSET. This preserves successful ioctl behavior while avoiding
both narrowing wraparound and an unsafe 32-bit timer interval.
The block SCSI behavior predates Git history. BSG has exposed the same
behavior since it was introduced.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Fixes: 3d6392cfbd7d ("bsg: support for full generic block layer SG v3")
Cc: stable@vger.kernel.org
Reported-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/9321a59c-c560-4742-8b71-5b0ec1f30c2f@acm.org
Signed-off-by: Yingjie Wang <x-professor@outlook.com>
Link: https://patch.msgid.link/20261022025508.294713-1-x-professor@outlook.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/bsg.c | 5 ++++-
drivers/scsi/scsi_ioctl.c | 11 ++++++++---
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/block/bsg.c b/block/bsg.c
index 72157a59b7881..7231b1de663fe 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -130,7 +130,10 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case SG_SET_TIMEOUT:
if (get_user(val, intp))
return -EFAULT;
- bd->timeout = clock_t_to_jiffies(val);
+ if (val < 0)
+ return -EIO;
+ bd->timeout = min(clock_t_to_jiffies(val),
+ min(UINT_MAX, MAX_JIFFY_OFFSET));
return 0;
case SG_GET_TIMEOUT:
return jiffies_to_clock_t(bd->timeout);
diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
index 0ddc95bafc71f..0b4bc15148de2 100644
--- a/drivers/scsi/scsi_ioctl.c
+++ b/drivers/scsi/scsi_ioctl.c
@@ -9,6 +9,7 @@
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
+#include <linux/jiffies.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -192,10 +193,14 @@ static int sg_set_timeout(struct scsi_device *sdev, int __user *p)
{
int timeout, err = get_user(timeout, p);
- if (!err)
- sdev->sg_timeout = clock_t_to_jiffies(timeout);
+ if (err)
+ return err;
+ if (timeout < 0)
+ return -EIO;
- return err;
+ sdev->sg_timeout = min(clock_t_to_jiffies(timeout),
+ min(UINT_MAX, MAX_JIFFY_OFFSET));
+ return 0;
}
static int sg_get_reserved_size(struct scsi_device *sdev, int __user *p)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 173/686] posix-timers: Accept NULL clock_getres() output in stubs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (171 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 172/686] scsi: handle out-of-range SG_SET_TIMEOUT values Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 174/686] tick/nohz: Reevaluate the tick for kicks flushed outside hardirq Greg Kroah-Hartman
` (512 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Thomas Gleixner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit 5b819071e4346256c4edbae5cc2095dff25694fc ]
With CONFIG_POSIX_TIMERS disabled, clock_getres() returns -EFAULT for a
supported clock when the result pointer is NULL. POSIX permits a NULL
result pointer to suppress returning the clock resolution.
Only copy the result when a destination is provided, in both the native
and time32 stubs. This matches the full POSIX timer implementation and
preserves clock ID validation.
Fixes: baa73d9e478f ("posix-timers: Make them configurable")
Fixes: d822cdcce43f ("posix-timers: Move compat versions of clock_gettime/settime/getres")
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261020161121.85042-1-dennylin0707@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/time/posix-stubs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/time/posix-stubs.c b/kernel/time/posix-stubs.c
index 9b6fcb8d85e78..5a27335a917ec 100644
--- a/kernel/time/posix-stubs.c
+++ b/kernel/time/posix-stubs.c
@@ -83,7 +83,7 @@ SYSCALL_DEFINE2(clock_getres, const clockid_t, which_clock, struct __kernel_time
case CLOCK_REALTIME:
case CLOCK_MONOTONIC:
case CLOCK_BOOTTIME:
- if (put_timespec64(&rtn_tp, tp))
+ if (tp && put_timespec64(&rtn_tp, tp))
return -EFAULT;
return 0;
default:
@@ -166,7 +166,7 @@ SYSCALL_DEFINE2(clock_getres_time32, clockid_t, which_clock,
case CLOCK_REALTIME:
case CLOCK_MONOTONIC:
case CLOCK_BOOTTIME:
- if (put_old_timespec32(&rtn_tp, tp))
+ if (tp && put_old_timespec32(&rtn_tp, tp))
return -EFAULT;
return 0;
default:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 174/686] tick/nohz: Reevaluate the tick for kicks flushed outside hardirq
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (172 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 173/686] posix-timers: Accept NULL clock_getres() output in stubs Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 175/686] ipmr, ip6mr: validate packets injected into the register vif on xmit Greg Kroah-Hartman
` (511 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Frederic Weisbecker, He Rongguang,
Peng Wang, Thomas Gleixner, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Wang <peng_wang@linux.alibaba.com>
[ Upstream commit e389ae428847a2e6a3b698b5967df68ccf90361c ]
The nohz full kick relies on interrupt exit to reevaluate the
tick. However, a remote kick can also be flushed from task context without
an interrupt exit guaranteed to follow. If a tick dependency is set or an
earlier timer is queued after the idle-exit reevaluation, the required tick
update can be delayed until another interrupt.
Reevaluate the tick directly from the callback outside hardirq context.
Keep the existing interrupt exit handling for hardirq callbacks. The
offline flush remains harmless because tick_sched_timer_dying() has already
cleared TS_FLAG_NOHZ.
Fixes: 4b44a21dd640 ("irq_work, smp: Allow irq_work on call_single_queue")
Fixes: a5183862e76f ("tick/nohz: Conditionally restart tick on idle exit")
Suggested-by: Frederic Weisbecker <frederic@kernel.org>
Co-developed-by: He Rongguang <herongguang@linux.alibaba.com>
Signed-off-by: He Rongguang <herongguang@linux.alibaba.com>
Signed-off-by: Peng Wang <peng_wang@linux.alibaba.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261023145101.8217-1-peng_wang@linux.alibaba.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/time/tick-sched.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 4f04c621c9224..ea0e7354930a4 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -377,9 +377,21 @@ static bool can_stop_full_tick(int cpu, struct tick_sched *ts)
return true;
}
+static void tick_nohz_full_update_tick(struct tick_sched *ts);
+
static void nohz_full_kick_func(struct irq_work *work)
{
- /* Empty, the tick restart happens on tick_nohz_irq_exit() */
+ struct tick_sched *ts = this_cpu_ptr(&tick_cpu_sched);
+
+ if (WARN_ON_ONCE(!tick_nohz_full_cpu(smp_processor_id())))
+ return;
+
+ /* Task-context flushes may not be followed by an IRQ exit. */
+ if (!in_hardirq()) {
+ if (WARN_ON_ONCE(tick_sched_flag_test(ts, TS_FLAG_INIDLE)))
+ return;
+ tick_nohz_full_update_tick(ts);
+ }
}
static DEFINE_PER_CPU(struct irq_work, nohz_full_kick_work) =
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 175/686] ipmr, ip6mr: validate packets injected into the register vif on xmit
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (173 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 174/686] tick/nohz: Reevaluate the tick for kicks flushed outside hardirq Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 176/686] ipmr: drop packets with unknown ingress VIF Greg Kroah-Hartman
` (510 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Ido Schimmel, Hangbin Liu,
Eric Dumazet, Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit aa1799e93f5ebb973252aec649d84d12d9c7fd1c ]
reg_vif_xmit() passes the packet to ipmr_cache_report() which copies its
IP header into the IGMPMSG_WHOLEPKT report that is queued to the mroute
socket. Nothing guarantees that the packet contains a full IP header, so
when a short packet is injected on the register device (e.g., using
AF_PACKET), the copy reads past the end of the packet and a recvmsg() on
the mroute socket leaks the uninitialized bytes to user space [1].
IPv6 has the same problem [2]. Its reg_vif_xmit() does call
pskb_inet_may_pull(), but the helper keys off skb->protocol and does not
pull anything when the protocol is neither IPv4 nor IPv6.
Fix by dropping packets whose protocol does not match the address family
of the register device or that do not contain a full network header.
[1]
BUG: KMSAN: kernel-infoleak in _copy_to_iter
raw_recvmsg
Uninit was stored to memory at:
ipmr_cache_report
reg_vif_xmit
packet_sendmsg
Uninit was created at:
__alloc_skb
sock_alloc_send_pskb
packet_sendmsg
Bytes 1-3 of 21 are uninitialized
[2]
BUG: KMSAN: kernel-infoleak in _copy_to_iter
rawv6_recvmsg
Uninit was stored to memory at:
ip6mr_cache_report
reg_vif_xmit
packet_sendmsg
Uninit was created at:
__alloc_skb
sock_alloc_send_pskb
packet_sendmsg
Bytes 8-23 of 41 are uninitialized
Fixes: 14fb64e1f449 ("[IPV6] MROUTE: Support PIM-SM (SSM).")
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <netdev-bot+sashiko@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz%40nebusec.ai
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/20261025071729.34967-3-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ipmr.c | 6 ++++++
net/ipv6/ip6mr.c | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 66a7f25f236b8..f3464e7a337b6 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -530,6 +530,12 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
};
int err;
+ if (skb->protocol != htons(ETH_P_IP) || !pskb_inet_may_pull(skb)) {
+ DEV_STATS_INC(dev, tx_errors);
+ kfree_skb(skb);
+ return NETDEV_TX_OK;
+ }
+
rcu_read_lock();
err = ipmr_fib_lookup(net, &fl4, &mrt);
if (err < 0) {
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 7b60e4b2a8179..9a2c23de98ad7 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -620,7 +620,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
.flowi6_mark = skb->mark,
};
- if (!pskb_inet_may_pull(skb))
+ if (skb->protocol != htons(ETH_P_IPV6) || !pskb_inet_may_pull(skb))
goto tx_err;
if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 176/686] ipmr: drop packets with unknown ingress VIF
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (174 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 175/686] ipmr, ip6mr: validate packets injected into the register vif on xmit Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 177/686] tg3: Invert restart quirk logic to restrict SNP power-down bypass Greg Kroah-Hartman
` (509 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Ido Schimmel, Naman Gulati,
Zhiling Zou, Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 09280680f2ea060514be2a39ea84209fb6d721d4 ]
A packet can race with VIF publication and make ipmr_find_vif() return
-1 even though the VIF device pointer is already visible. The parent VIF
device check can then pass with an invalid ingress VIF. For (*,G)
entries, this can also let the packet be forwarded back out its ingress
VIF.
Drop packets whose ingress VIF lookup fails in both IPv4 and IPv6
forwarding, before checking the MFC parent device. This prevents
forwarding with an unknown ingress VIF and avoids the (*,G) hairpin.
Without the early check, the negative index can reach the IPv4 offload
lookup only for an skb marked for L3 forwarding offload, currently done
by mlxsw. The race is rare; the supplied PoC reports only the UBSAN
negative-index diagnostic.
Fixes: 4eadb88244d1 ("ipmr: do not acquire mrt_lock while calling ip_mr_forward()")
Fixes: 9b1c21d898fd ("ip6mr: do not acquire mrt_lock while calling ip6_mr_forward()")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Link: https://lore.kernel.org/netdev/b966eb102e98f299e45be59ada033a8766e4c6df.1791899747.git.zhilinz@nebusec.ai/
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Suggested-by: Naman Gulati <namangulati@google.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Naman Gulati <namangulati@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/5271fcb94a4d9e697ed64a348e92ea9e74faab1c.1792608753.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ipmr.c | 3 ++-
net/ipv6/ip6mr.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index f3464e7a337b6..dd9ed871a1b4f 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2052,7 +2052,8 @@ static void ip_mr_forward(struct net *net, struct mr_table *mrt,
}
/* Wrong interface: drop packet and (maybe) send PIM assert. */
- if (rcu_access_pointer(mrt->vif_table[vif].dev) != dev) {
+ if (true_vifi < 0 ||
+ rcu_access_pointer(mrt->vif_table[vif].dev) != dev) {
if (rt_is_output_route(skb_rtable(skb))) {
/* It is our own packet, looped back.
* Very complicated situation...
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 9a2c23de98ad7..f61035619cac7 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2173,7 +2173,8 @@ static void ip6_mr_forward(struct net *net, struct mr_table *mrt,
/*
* Wrong interface: drop packet and (maybe) send PIM assert.
*/
- if (rcu_access_pointer(mrt->vif_table[vif].dev) != dev) {
+ if (true_vifi < 0 ||
+ rcu_access_pointer(mrt->vif_table[vif].dev) != dev) {
atomic_long_inc(&c->_c.mfc_un.res.wrong_if);
if (true_vifi >= 0 && mrt->mroute_do_assert &&
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 177/686] tg3: Invert restart quirk logic to restrict SNP power-down bypass
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (175 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 176/686] ipmr: drop packets with unknown ingress VIF Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 178/686] ns: dont add init_ipc_ns and init_net without namespace support Greg Kroah-Hartman
` (508 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Noam D. Eliyahu, Pavan Chebbi,
Paolo Abeni, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Noam D. Eliyahu <noam.d.eliyahu@gmail.com>
[ Upstream commit d7314b51341c037973ce022f12c6009fd07b021e ]
Commit 9fc3bc764334 ("tg3: power down device only on SYSTEM_POWER_OFF")
bypassed `tg3_power_down()` on system restarts to prevent reboot hangs and
NMIs on servers where NICs were initialized via SNP (such as Dell PowerEdge
R650 and R750).
However, skipping the power-down flow globally causes the ACPI _PTS method
to trigger fatal PCIe AER events and hangs on other models. Commit
e0efe83ed325 ("tg3: Disable tg3 PCIe AER on system reboot") attempted to
mitigate this by adding an AER-disable DMI quirk table. Maintaining a
growing list of models for a secondary symptom misses the root cause,
leaving systems like the PowerEdge T440 (sharing the BCM5720 NIC) exposed.
Fix this by inverting the quirk logic:
1. Restrict SNP power-down avoidance strictly to
`tg3_restart_snp_quirk_table` for the specific systems requiring it
(Dell PowerEdge R650 and R750).
2. Restore standard power-down behavior for all other systems, eliminating
the separate AER-disable quirk table.
For systems affected by the original SNP restart issue, their shutdown flow
remains completely untouched.
Link: https://lore.kernel.org/netdev/20251221175050.14089-1-noam.d.eliyahu@gmail.com/T/#u
Fixes: 9fc3bc764334 ("tg3: power down device only on SYSTEM_POWER_OFF")
Fixes: e0efe83ed325 ("tg3: Disable tg3 PCIe AER on system reboot")
Cc: stable@vger.kernel.org
Signed-off-by: Noam D. Eliyahu <noam.d.eliyahu@gmail.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Link: https://patch.msgid.link/20261026220955.473247-1-noam.d.eliyahu@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/tg3.c | 42 ++++++++---------------------
1 file changed, 11 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 50eb40de7b220..897bb86bedb13 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -18201,41 +18201,17 @@ static int tg3_resume(struct device *device)
static SIMPLE_DEV_PM_OPS(tg3_pm_ops, tg3_suspend, tg3_resume);
-/* Systems where ACPI _PTS (Prepare To Sleep) S5 will result in a fatal
- * PCIe AER event on the tg3 device if the tg3 device is not, or cannot
- * be, powered down.
+/* Systems where powering down a tg3 device on restarts triggers
+ * NMIs and fatal hangs during reboot if the network adapters were
+ * initialized under SNP.
*/
-static const struct dmi_system_id tg3_restart_aer_quirk_table[] = {
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R440"),
- },
- },
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R540"),
- },
- },
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R640"),
- },
- },
+static const struct dmi_system_id tg3_restart_snp_quirk_table[] = {
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R650"),
},
},
- {
- .matches = {
- DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
- DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge R740"),
- },
- },
{
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
@@ -18259,14 +18235,18 @@ static void tg3_shutdown(struct pci_dev *pdev)
if (netif_running(dev))
dev_close(dev);
- if (system_state == SYSTEM_POWER_OFF)
+ if (!dmi_first_match(tg3_restart_snp_quirk_table) ||
+ system_state == SYSTEM_POWER_OFF) {
tg3_power_down(tp);
- else if (system_state == SYSTEM_RESTART &&
- dmi_first_match(tg3_restart_aer_quirk_table) &&
+ } else if (system_state == SYSTEM_RESTART &&
pdev->current_state != PCI_D3cold &&
pdev->current_state != PCI_UNKNOWN) {
/* Disable PCIe AER on the tg3 to avoid a fatal
* error during this system restart.
+ * Needed since on restarts for systems in
+ * tg3_restart_snp_quirk_table skipping on powering down the
+ * tg3 device causes a fatal AER error during ACPI _PTS
+ * (Prepare To Sleep).
*/
pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_CERE |
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 178/686] ns: dont add init_ipc_ns and init_net without namespace support
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (176 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 177/686] tg3: Invert restart quirk logic to restrict SNP power-down bypass Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 179/686] net/9p/usbg: fix prefix matching in device lookup Greg Kroah-Hartman
` (507 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot,
Christian Brauner (Amutable), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit 82f1c815aaef1905c5c6c386c8a0d74f6ff70a54 ]
When CONFIG_IPC_NS or CONFIG_NET_NS are turned off we still add the
initial ipc and network namespace to the namespace trees. ipc_ns_init()
calls ns_tree_add(&init_ipc_ns) whenever CONFIG_SYSVIPC is set and
setup_net() calls ns_tree_add_raw() on init_net whenever CONFIG_NET is
set.
But without CONFIG_IPC_NS and CONFIG_NET_NS these aren't namespaces
userspace can do anything with. They don't have proc_ns_operations so
there's no /proc/<pid>/ns/{ipc,net} for them, nsfs_fh_to_dentry()
refuses them with -EOPNOTSUPP, and since ns->ops is NULL
__ns_tree_add_raw() doesn't add them to the owner list of init_user_ns
either. So they end up half registered. That's also not how we treat
any of the other namespace types. Without CONFIG_UTS_NS, CONFIG_PID_NS,
CONFIG_TIME_NS or CONFIG_USER_NS the initial namespace is never added
to the tree.
listns() walks the unified tree and calls is_current_namespace() for
every namespace it finds via may_list_ns(). But is_current_namespace()
only knows about CLONE_NEWIPC and CLONE_NEWNET if CONFIG_IPC_NS and
CONFIG_NET_NS are set. Otherwise we end up in the default case and its
VFS_WARN_ON_ONCE(). Any unprivileged caller can trigger that with a
plain listns() call:
WARNING: CPU: 0 PID: 526 at fs/nsfs.c:508 is_current_namespace+0x12f/0x440
Call Trace:
legitimize_ns+0x25f/0x4c0
do_listns+0x185/0x5c0
__do_sys_listns+0x13b/0x300
Instead of teaching is_current_namespace() about namespaces that can't
be opened, only add the initial namespaces to the tree if their
namespace type is enabled. Move the registration of init_ipc_ns into
ipc/namespace.c which is only built with CONFIG_IPC_NS. That also fixes
CONFIG_SYSVIPC=n, CONFIG_POSIX_MQUEUE=y, CONFIG_IPC_NS=y where
ipc/shm.c isn't built and init_ipc_ns was never added at all. For the
network namespace only call ns_tree_add_raw() if CONFIG_NET_NS is set.
Without CONFIG_NET_NS cleanup_net() isn't built and init_net is never
removed so there's nothing to balance.
Fixes: 74b24a582e1f ("ipc: support ns lookup")
Fixes: 195f7422298d ("net: support ns lookup")
Reported-by: kernel test robot <yi1.lai@intel.com>
Closes: https://lore.kernel.org/oe-lkp/202610260917.6248e316-lkp@intel.com
Cc: stable@vger.kernel.org # v6.18+
Link: https://patch.msgid.link/20261030-work-nsfs-init_ns_tree-v1-1-7ec0adb47c54@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
ipc/namespace.c | 7 +++++++
ipc/shm.c | 2 --
net/core/net_namespace.c | 4 +++-
3 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 7aab1e6e0f86d..b69da8c68f53b 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -254,3 +254,10 @@ const struct proc_ns_operations ipcns_operations = {
.install = ipcns_install,
.owner = ipcns_owner,
};
+
+static int __init ipc_ns_tree_init(void)
+{
+ ns_tree_add(&init_ipc_ns);
+ return 0;
+}
+pure_initcall(ipc_ns_tree_init);
diff --git a/ipc/shm.c b/ipc/shm.c
index 2f5cee0c78c7d..59fade2253d87 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -45,7 +45,6 @@
#include <linux/mount.h>
#include <linux/ipc_namespace.h>
#include <linux/rhashtable.h>
-#include <linux/nstree.h>
#include <linux/uaccess.h>
@@ -149,7 +148,6 @@ void shm_exit_ns(struct ipc_namespace *ns)
static int __init ipc_ns_init(void)
{
shm_init_ns(&init_ipc_ns);
- ns_tree_add(&init_ipc_ns);
return 0;
}
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 4bece5eda9d1a..ae1f9cc021b87 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -442,7 +442,9 @@ static __net_init int setup_net(struct net *net)
down_write(&net_rwsem);
list_add_tail_rcu(&net->list, &net_namespace_list);
up_write(&net_rwsem);
- ns_tree_add_raw(net);
+ /* Without CONFIG_NET_NS init_net isn't exposed as a namespace. */
+ if (IS_ENABLED(CONFIG_NET_NS))
+ ns_tree_add_raw(net);
out:
return error;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 179/686] net/9p/usbg: fix prefix matching in device lookup
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (177 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 178/686] ns: dont add init_ipc_ns and init_net without namespace support Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 180/686] xfrm: retry inexact policy lookup after node reinsertion Greg Kroah-Hartman
` (506 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 468f7e8f0277b..59505d2388f52 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -389,7 +389,7 @@ static int p9_usbg_create(struct p9_client *client, const char *devname, char *a
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] 687+ messages in thread
* [PATCH 6.18 180/686] xfrm: retry inexact policy lookup after node reinsertion
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (178 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 179/686] 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 6.18 181/686] net/9p/usbg: clear stale request context after abort Greg Kroah-Hartman
` (505 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 25f9cbd3ce6a4..c13382bcc6582 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] 687+ messages in thread
* [PATCH 6.18 181/686] net/9p/usbg: clear stale request context after abort
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (179 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 180/686] 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 6.18 182/686] 9p/trans_virtio: reject mount tags longer than NAME_MAX at probe Greg Kroah-Hartman
` (504 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 59505d2388f52..c682947dfb885 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -437,6 +437,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] 687+ messages in thread
* [PATCH 6.18 182/686] 9p/trans_virtio: reject mount tags longer than NAME_MAX at probe
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (180 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 181/686] 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 6.18 183/686] 9p/xen: fix refcount leak in p9_xen_response() on wrong tag Greg Kroah-Hartman
` (503 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 0b8086f58ad55..d1a680f699115 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -629,6 +629,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] 687+ messages in thread
* [PATCH 6.18 183/686] 9p/xen: fix refcount leak in p9_xen_response() on wrong tag
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (181 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 182/686] 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 6.18 184/686] 9p: fix caches_show() out-of-bounds write Greg Kroah-Hartman
` (502 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 068d57515dd58..92701a16511d4 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -201,6 +201,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] 687+ messages in thread
* [PATCH 6.18 184/686] 9p: fix caches_show() out-of-bounds write
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (182 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 183/686] 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 6.18 185/686] net/9p/usbg: Fix use-after-free in disable_usb9pfs() Greg Kroah-Hartman
` (501 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 bde3ffb0e319a..20dc6a03826a3 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -16,6 +16,7 @@
#include <linux/parser.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>
@@ -554,21 +555,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] 687+ messages in thread
* [PATCH 6.18 185/686] net/9p/usbg: Fix use-after-free in disable_usb9pfs()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (183 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 184/686] 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 6.18 186/686] net/9p/usbg: also disable endpoints on p9_usbg_close Greg Kroah-Hartman
` (500 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 c682947dfb885..cd45d4a8597ad 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -277,6 +277,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;
@@ -286,9 +289,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] 687+ messages in thread
* [PATCH 6.18 186/686] net/9p/usbg: also disable endpoints on p9_usbg_close
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (184 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 185/686] 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 6.18 187/686] net/9p/usbg: set client to Disconnected on usb9pfs_disable Greg Kroah-Hartman
` (499 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 cd45d4a8597ad..ff787f5fb1631 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -465,6 +465,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] 687+ messages in thread
* [PATCH 6.18 187/686] net/9p/usbg: set client to Disconnected on usb9pfs_disable
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (185 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 186/686] 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 6.18 188/686] net/9p/usbg: always reset completion when disconnecting Greg Kroah-Hartman
` (498 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 ff787f5fb1631..f1773749d9124 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -748,7 +748,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] 687+ messages in thread
* [PATCH 6.18 188/686] net/9p/usbg: always reset completion when disconnecting
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (186 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 187/686] 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 6.18 189/686] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable() Greg Kroah-Hartman
` (497 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 f1773749d9124..0b04363c39793 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -467,6 +467,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)
@@ -755,6 +756,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] 687+ messages in thread
* [PATCH 6.18 189/686] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (187 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 188/686] 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 6.18 190/686] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs Greg Kroah-Hartman
` (496 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 0b04363c39793..c58d57232369e 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -756,6 +756,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] 687+ messages in thread
* [PATCH 6.18 190/686] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (188 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 189/686] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 191/686] net/9p/usbg: remove bogus context initialization in alloc_requests Greg Kroah-Hartman
` (495 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 c58d57232369e..301123725a671 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -286,7 +286,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] 687+ messages in thread
* [PATCH 6.18 191/686] net/9p/usbg: remove bogus context initialization in alloc_requests
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (189 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 190/686] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 192/686] net/9p/usbg: clear stale client pointer on close Greg Kroah-Hartman
` (494 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 301123725a671..ed8f01ead839a 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -313,10 +313,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] 687+ messages in thread
* [PATCH 6.18 192/686] net/9p/usbg: clear stale client pointer on close
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (190 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 191/686] net/9p/usbg: remove bogus context initialization in alloc_requests Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 193/686] xfrm: interface: validate the IP header on xmit Greg Kroah-Hartman
` (493 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyungjung Joo, Michael Grzeschik,
Dominique Martinet, Sasha Levin
6.18-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 ed8f01ead839a..938e3130ab81a 100644
--- a/net/9p/trans_usbg.c
+++ b/net/9p/trans_usbg.c
@@ -148,7 +148,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 */
@@ -164,18 +165,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;
@@ -201,7 +209,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;
@@ -211,7 +219,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;
}
@@ -219,7 +227,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;
}
@@ -230,8 +238,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) {
@@ -240,9 +250,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,
@@ -256,8 +273,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);
}
@@ -410,7 +430,9 @@ static int p9_usbg_create(struct p9_client *client, const char *devname, char *a
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;
@@ -421,18 +443,25 @@ static int p9_usbg_create(struct p9_client *client, const char *devname, char *a
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] 687+ messages in thread
* [PATCH 6.18 193/686] xfrm: interface: validate the IP header on xmit
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (191 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 192/686] net/9p/usbg: clear stale client pointer on close Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 194/686] xfrm: espintcp: reorder operations within espintcp_init_sk Greg Kroah-Hartman
` (492 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qihang, Steffen Klassert,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 194/686] xfrm: espintcp: reorder operations within espintcp_init_sk
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (192 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 193/686] xfrm: interface: validate the IP header on xmit Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 195/686] drm/panic: Fix kmsg screen hang on a long log line Greg Kroah-Hartman
` (491 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 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
6.18-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 26c0a46491a47..e36a637b4ce76 100644
--- a/net/xfrm/espintcp.c
+++ b/net/xfrm/espintcp.c
@@ -437,7 +437,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);
@@ -469,34 +471,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] 687+ messages in thread
* [PATCH 6.18 195/686] drm/panic: Fix kmsg screen hang on a long log line
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (193 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 194/686] xfrm: espintcp: reorder operations within espintcp_init_sk Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 196/686] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind Greg Kroah-Hartman
` (490 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Devin Wittmayer, Jocelyn Falempe,
Sasha Levin
6.18-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 9c4ac2febc931..17b795a18d2cd 100644
--- a/drivers/gpu/drm/drm_panic.c
+++ b/drivers/gpu/drm/drm_panic.c
@@ -562,7 +562,8 @@ static void draw_panic_static_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;
@@ -580,6 +581,10 @@ static void draw_panic_static_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] 687+ messages in thread
* [PATCH 6.18 196/686] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (194 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 195/686] drm/panic: Fix kmsg screen hang on a long log line Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 197/686] wifi: mac80211: reload TDLS header pointer after skb_linearize() Greg Kroah-Hartman
` (489 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, André Draszik, Philipp Stanner,
Christian König, Sasha Levin
6.18-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 46655339003db..4ba190287c2ac 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -476,14 +476,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] 687+ messages in thread
* [PATCH 6.18 197/686] wifi: mac80211: reload TDLS header pointer after skb_linearize()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (195 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 196/686] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 198/686] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional Greg Kroah-Hartman
` (488 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Weigang He, Johannes Berg,
Sasha Levin
6.18-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 1dde37ad8bb20..83ebd9ab2e9b3 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -2017,7 +2017,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);
@@ -2033,6 +2033,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] 687+ messages in thread
* [PATCH 6.18 198/686] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (196 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 197/686] wifi: mac80211: reload TDLS header pointer after skb_linearize() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 199/686] wifi: rsi: Skip TX aggregation setup for non-QoS frames Greg Kroah-Hartman
` (487 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Perlow, Aditya Garg,
Arend van Spriel, Johannes Berg, Sasha Levin
6.18-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 f850e64108c41..24f083f42bb75 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] 687+ messages in thread
* [PATCH 6.18 199/686] wifi: rsi: Skip TX aggregation setup for non-QoS frames
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (197 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 198/686] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 200/686] wifi: cfg80211: fix out-of-bounds read in valid_rule() Greg Kroah-Hartman
` (486 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Kazinsky, Johannes Berg,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 200/686] wifi: cfg80211: fix out-of-bounds read in valid_rule()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (198 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 199/686] wifi: rsi: Skip TX aggregation setup for non-QoS frames Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 201/686] drm/vc4: Publish the output fence outside of job_lock Greg Kroah-Hartman
` (485 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Zijing Yin, Johannes Berg,
Sasha Levin
6.18-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 15e56dfad00f7..3f685b1396ff0 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -691,6 +691,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] 687+ messages in thread
* [PATCH 6.18 201/686] drm/vc4: Publish the output fence outside of job_lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (199 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 200/686] wifi: cfg80211: fix out-of-bounds read in valid_rule() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 202/686] drm/vc4: Drop the BO reservations " Greg Kroah-Hartman
` (484 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iago Toral Quiroga, Maíra Canal,
Sasha Levin
6.18-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 5eadf11f289a8..812636318cd9f 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] 687+ messages in thread
* [PATCH 6.18 202/686] drm/vc4: Drop the BO reservations outside of job_lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (200 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 201/686] drm/vc4: Publish the output fence outside of job_lock Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 203/686] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg() Greg Kroah-Hartman
` (483 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iago Toral Quiroga, Maíra Canal,
Sasha Levin
6.18-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 812636318cd9f..4fa6e71140a84 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] 687+ messages in thread
* [PATCH 6.18 203/686] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (201 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 202/686] drm/vc4: Drop the BO reservations " Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 204/686] xfrm4: use a full socket for local errors Greg Kroah-Hartman
` (482 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Evan Severson,
Toke Høiland-Jørgensen, Johannes Berg, Sasha Levin
6.18-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 b012451f45253..85c90f7c24d8e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1124,6 +1124,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)) {
/*
@@ -1155,6 +1156,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] 687+ messages in thread
* [PATCH 6.18 204/686] xfrm4: use a full socket for local errors
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (202 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 203/686] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 205/686] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers Greg Kroah-Hartman
` (481 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Eric Dumazet,
Fourie Zhang, Steffen Klassert, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 205/686] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (203 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 204/686] xfrm4: use a full socket for local errors Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 206/686] scsi: aic79xx: Fix NULL pointer dereference in device reset Greg Kroah-Hartman
` (480 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz,
Martin K. Petersen (Oracle), Sasha Levin
6.18-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 a396f048a031e..d747d0b72a13a 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] 687+ messages in thread
* [PATCH 6.18 206/686] scsi: aic79xx: Fix NULL pointer dereference in device reset
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (204 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 205/686] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 207/686] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown Greg Kroah-Hartman
` (479 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Andrew Luebke,
Martin K. Petersen (Oracle), Sasha Levin
6.18-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 6b87ea004e537..ff7efba29adac 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] 687+ messages in thread
* [PATCH 6.18 207/686] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (205 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 206/686] scsi: aic79xx: Fix NULL pointer dereference in device reset Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 208/686] 9p/xen: validate the response size from the backend Greg Kroah-Hartman
` (478 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yu Zhang,
Martin K. Petersen (Oracle), Sasha Levin
6.18-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 7bb711b24c0d7..91ba88f9934d5 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 c0e429e5ef310..d8f4538e48dc7 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] 687+ messages in thread
* [PATCH 6.18 208/686] 9p/xen: validate the response size from the backend
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (206 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 207/686] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 209/686] 9p: dont decrement a server-owned zero nlink Greg Kroah-Hartman
` (477 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yehyeong Lee, Juergen Gross,
Dominique Martinet, Sasha Levin
6.18-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 92701a16511d4..67f464acf6171 100644
--- a/net/9p/trans_xen.c
+++ b/net/9p/trans_xen.c
@@ -198,6 +198,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] 687+ messages in thread
* [PATCH 6.18 209/686] 9p: dont decrement a server-owned zero nlink
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (207 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 208/686] 9p/xen: validate the response size from the backend Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 210/686] batman-adv: Close OGM aggregation before transmission Greg Kroah-Hartman
` (476 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuanfu Xie, Dominique Martinet,
Sasha Levin
6.18-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 b2368334f6eea..34fda75c77607 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -493,6 +493,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)
@@ -501,6 +507,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] 687+ messages in thread
* [PATCH 6.18 210/686] batman-adv: Close OGM aggregation before transmission
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (208 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 209/686] 9p: dont decrement a server-owned zero nlink Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 211/686] batman-adv: mcast: validate tracker padding before forwarding Greg Kroah-Hartman
` (475 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Sven Eckelmann,
Sasha Levin
6.18-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 6e79f69c2fede..38320f6a1dd1f 100644
--- a/net/batman-adv/bat_iv_ogm.c
+++ b/net/batman-adv/bat_iv_ogm.c
@@ -1787,6 +1787,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 51d04f351fdd4..1944398e0ed65 100644
--- a/net/batman-adv/types.h
+++ b/net/batman-adv/types.h
@@ -1970,7 +1970,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] 687+ messages in thread
* [PATCH 6.18 211/686] batman-adv: mcast: validate tracker padding before forwarding
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (209 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 210/686] batman-adv: Close OGM aggregation before transmission Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 212/686] batman-adv: dat: initialize orig_node of unfilled candidate slots Greg Kroah-Hartman
` (474 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Sven Eckelmann,
Sasha Levin
6.18-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 c99579dc1ca98..1638278178d98 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] 687+ messages in thread
* [PATCH 6.18 212/686] batman-adv: dat: initialize orig_node of unfilled candidate slots
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (210 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 211/686] batman-adv: mcast: validate tracker padding before forwarding Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 213/686] batman-adv: fix skb leak when hard_iface is being released Greg Kroah-Hartman
` (473 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Linus Lüssing,
Sven Eckelmann, Sasha Levin
6.18-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 72717e2952ab9..126a546fa033d 100644
--- a/net/batman-adv/distributed-arp-table.c
+++ b/net/batman-adv/distributed-arp-table.c
@@ -582,6 +582,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] 687+ messages in thread
* [PATCH 6.18 213/686] batman-adv: fix skb leak when hard_iface is being released
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (211 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 212/686] batman-adv: dat: initialize orig_node of unfilled candidate slots Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 214/686] batman-adv: stop originator purge worker before freeing TT Greg Kroah-Hartman
` (472 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
6.18-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 f1b41078835b6..870754d1d86f9 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -427,8 +427,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);
@@ -487,7 +489,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] 687+ messages in thread
* [PATCH 6.18 214/686] batman-adv: stop originator purge worker before freeing TT
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (212 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 213/686] batman-adv: fix skb leak when hard_iface is being released Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 215/686] net: jme: keep RX MAC clock enabled for WoL Greg Kroah-Hartman
` (471 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sven Eckelmann, Sasha Levin
6.18-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 870754d1d86f9..6ffa65ef3d162 100644
--- a/net/batman-adv/main.c
+++ b/net/batman-adv/main.c
@@ -249,6 +249,11 @@ void batadv_mesh_free(struct net_device *mesh_iface)
atomic_set(&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] 687+ messages in thread
* [PATCH 6.18 215/686] net: jme: keep RX MAC clock enabled for WoL
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (213 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 214/686] batman-adv: stop originator purge worker before freeing TT Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 216/686] ipv6: raw: fix use-after-free in rawv6_send_hdrinc() Greg Kroah-Hartman
` (470 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Franck Baur, Dave Miller,
Sasha Levin
6.18-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 d8be0e4dcb072..6cfcfda055545 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] 687+ messages in thread
* [PATCH 6.18 216/686] ipv6: raw: fix use-after-free in rawv6_send_hdrinc()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (214 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 215/686] net: jme: keep RX MAC clock enabled for WoL Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 217/686] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled Greg Kroah-Hartman
` (469 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhou Qiuyue, Hangbin Liu,
Dave Miller, Sasha Levin
6.18-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 b796d84db5ce2..5ecbb9c775be0 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -653,6 +653,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] 687+ messages in thread
* [PATCH 6.18 217/686] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (215 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 216/686] ipv6: raw: fix use-after-free in rawv6_send_hdrinc() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 218/686] drm/vc4: hdmi: always cancel the scrambling work synchronously Greg Kroah-Hartman
` (468 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dom Cobley, Lucas Tanure,
Dave Stevenson, Maíra Canal, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 218/686] drm/vc4: hdmi: always cancel the scrambling work synchronously
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (216 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 217/686] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 219/686] drm/vc4: hdmi: enable scrambling before the TMDS clock starts Greg Kroah-Hartman
` (467 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas Tanure, Maíra Canal,
Sasha Levin
6.18-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 2f854386c3389..7a84d8414436f 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -764,8 +764,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] 687+ messages in thread
* [PATCH 6.18 219/686] drm/vc4: hdmi: enable scrambling before the TMDS clock starts
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (217 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 218/686] drm/vc4: hdmi: always cancel the scrambling work synchronously Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 220/686] sctp: account for chunk padding in sctp_init_cause() Greg Kroah-Hartman
` (466 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas Tanure, Maíra Canal,
Sasha Levin
6.18-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 7a84d8414436f..8f5d43946583a 100644
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -839,8 +839,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:
@@ -869,6 +867,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);
@@ -1478,6 +1478,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);
@@ -1612,7 +1614,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] 687+ messages in thread
* [PATCH 6.18 220/686] sctp: account for chunk padding in sctp_init_cause()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (218 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 219/686] drm/vc4: hdmi: enable scrambling before the TMDS clock starts Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 221/686] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type() Greg Kroah-Hartman
` (465 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masafumi Suzuki, Xin Long,
Jakub Kicinski, Sasha Levin
6.18-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 04716666b29ba..8e4e88b1d0c06 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] 687+ messages in thread
* [PATCH 6.18 221/686] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (219 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 220/686] sctp: account for chunk padding in sctp_init_cause() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 222/686] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked Greg Kroah-Hartman
` (464 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, guolingxing, Qu Wenruo, David Sterba,
Sasha Levin
6.18-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 d66681ce2b3da..204edb659304b 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -1899,6 +1899,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] 687+ messages in thread
* [PATCH 6.18 222/686] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (220 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 221/686] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type() Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 223/686] scsi: bsg: Report synchronous data copyback failures Greg Kroah-Hartman
` (463 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yu Zhang, Jakub Kicinski,
Sasha Levin
6.18-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 200eaf5006968..0d4b081daf639 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] 687+ messages in thread
* [PATCH 6.18 223/686] scsi: bsg: Report synchronous data copyback failures
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (221 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 222/686] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 224/686] scsi: target: Verify the iSCSI ISID is null-terminated Greg Kroah-Hartman
` (462 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yingjie Wang, Yang Xiuwei,
Bart Van Assche, Martin K. Petersen (Oracle), Sasha Levin
6.18-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 a9a9ec086a7e3..e2e4b8bb559f9 100644
--- a/drivers/scsi/scsi_bsg.c
+++ b/drivers/scsi/scsi_bsg.c
@@ -15,7 +15,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)
@@ -89,7 +89,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] 687+ messages in thread
* [PATCH 6.18 224/686] scsi: target: Verify the iSCSI ISID is null-terminated
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (222 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 223/686] scsi: bsg: Report synchronous data copyback failures Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 225/686] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store Greg Kroah-Hartman
` (461 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 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
6.18-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 3af9a26cdefc4..a1ee106971cb0 100644
--- a/drivers/target/target_core_fabric_lib.c
+++ b/drivers/target/target_core_fabric_lib.c
@@ -370,6 +370,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] 687+ messages in thread
* [PATCH 6.18 225/686] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (223 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 224/686] scsi: target: Verify the iSCSI ISID is null-terminated Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 226/686] drm/loongson: Fix framebuffer selection in async cursor updates Greg Kroah-Hartman
` (460 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shao Mingyin, Bodo Stroesser,
Martin K. Petersen (Oracle), Sasha Levin
6.18-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 3fd9636127758..72878700b1a6c 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -2514,6 +2514,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] 687+ messages in thread
* [PATCH 6.18 226/686] drm/loongson: Fix framebuffer selection in async cursor updates
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (224 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 225/686] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store Greg Kroah-Hartman
@ 2026-11-13 15:45 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 227/686] drm/loongson: Fix double free on BO initialization failure Greg Kroah-Hartman
` (459 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:45 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Evanshenf,
Icenowy Zheng, Qianhai Wu, Huacai Chen, Sasha Levin
6.18-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 aa9a97f9c4dc2..df941f13a9699 100644
--- a/drivers/gpu/drm/loongson/lsdc_plane.c
+++ b/drivers/gpu/drm/loongson/lsdc_plane.c
@@ -228,7 +228,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] 687+ messages in thread
* [PATCH 6.18 227/686] drm/loongson: Fix double free on BO initialization failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (225 preceding siblings ...)
2026-11-13 15:45 ` [PATCH 6.18 226/686] 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 6.18 228/686] drm/loongson: Handle buffer mapping failures when clearing a BO Greg Kroah-Hartman
` (458 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 2e42c6970c9fd..e8805a2a0db43 100644
--- a/drivers/gpu/drm/loongson/lsdc_ttm.c
+++ b/drivers/gpu/drm/loongson/lsdc_ttm.c
@@ -474,10 +474,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] 687+ messages in thread
* [PATCH 6.18 228/686] drm/loongson: Handle buffer mapping failures when clearing a BO
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (226 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 227/686] 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 6.18 229/686] ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap() Greg Kroah-Hartman
` (457 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 a720d8f532093..5eb6b4f92302b 100644
--- a/drivers/gpu/drm/loongson/lsdc_gem.c
+++ b/drivers/gpu/drm/loongson/lsdc_gem.c
@@ -155,14 +155,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 e8805a2a0db43..17b1998254e23 100644
--- a/drivers/gpu/drm/loongson/lsdc_ttm.c
+++ b/drivers/gpu/drm/loongson/lsdc_ttm.c
@@ -387,9 +387,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);
@@ -397,6 +401,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] 687+ messages in thread
* [PATCH 6.18 229/686] ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (227 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 228/686] 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 6.18 230/686] ALSA: us122l: Fix NULL dereference at hwdep open and release Greg Kroah-Hartman
` (456 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 aaeae099b5f2e..50975b7ef1b8b 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] 687+ messages in thread
* [PATCH 6.18 230/686] ALSA: us122l: Fix NULL dereference at hwdep open and release
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (228 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 229/686] 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 6.18 231/686] ALSA: usx2y: Initialize idle URBs before submitting streams Greg Kroah-Hartman
` (455 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 50975b7ef1b8b..46dbf9ea1fb70 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] 687+ messages in thread
* [PATCH 6.18 231/686] ALSA: usx2y: Initialize idle URBs before submitting streams
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (229 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 230/686] 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 6.18 232/686] ALSA: hwdep: Serialize DSP load requests Greg Kroah-Hartman
` (454 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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] 687+ messages in thread
* [PATCH 6.18 232/686] ALSA: hwdep: Serialize DSP load requests
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (230 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 231/686] 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 6.18 233/686] bpf: Fix skb_pull() BUG in __bpf_redirect_neigh() Greg Kroah-Hartman
` (453 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 09200df2932c7..10a32004398ff 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;
@@ -381,6 +382,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] 687+ messages in thread
* [PATCH 6.18 233/686] bpf: Fix skb_pull() BUG in __bpf_redirect_neigh()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (231 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 232/686] ALSA: hwdep: Serialize DSP load requests Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 234/686] ksmbd: require DELETE access for delete-on-close opens Greg Kroah-Hartman
` (452 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 6926903163592..6670b43cb640d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2270,9 +2270,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;
@@ -2375,9 +2379,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 = {
@@ -2427,15 +2435,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] 687+ messages in thread
* [PATCH 6.18 234/686] ksmbd: require DELETE access for delete-on-close opens
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (232 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 233/686] 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 6.18 235/686] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()` Greg Kroah-Hartman
` (451 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 40d86993dbe3d..ec4c54c9c6dc9 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -3176,6 +3176,14 @@ int smb2_open(struct ksmbd_work *work)
req->CreateOptions = ~(FILE_NO_COMPRESSION_LE);
}
}
+
+ /* 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) >
@@ -3355,6 +3363,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] 687+ messages in thread
* [PATCH 6.18 235/686] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()`
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (233 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 234/686] 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 6.18 236/686] x86/bugs: Select the BHI mitigation based on the attack vector properly Greg Kroah-Hartman
` (450 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 be312f523ebec..dbd1ea1e9be79 100644
--- a/rust/kernel/cpufreq.rs
+++ b/rust/kernel/cpufreq.rs
@@ -695,8 +695,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] 687+ messages in thread
* [PATCH 6.18 236/686] x86/bugs: Select the BHI mitigation based on the attack vector properly
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (234 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 235/686] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()` Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 237/686] drm/i915/psr: Clear selective fetch area when duplicating plane state Greg Kroah-Hartman
` (449 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Borislav Petkov (AMD),
David Kaplan, stable, Sasha Levin
6.18-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 90d0488d54c5c..cbf5c0ddd3b38 100644
--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -2233,14 +2233,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] 687+ messages in thread
* [PATCH 6.18 237/686] drm/i915/psr: Clear selective fetch area when duplicating plane state
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (235 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 236/686] x86/bugs: Select the BHI mitigation based on the attack vector properly Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 238/686] drm/i915/display: Add enabled pipe planes into state for selective fetch Greg Kroah-Hartman
` (448 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
6.18-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 91deeaec61100..6f9c22476b14d 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -139,6 +139,7 @@ intel_plane_duplicate_state(struct drm_plane *plane)
intel_state->dpt_vma = NULL;
intel_state->flags = 0;
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 5f6ccd953c1e3..d41ad77c086f4 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2797,16 +2797,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.
@@ -2890,7 +2890,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);
@@ -2926,6 +2926,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.
@@ -2942,8 +2947,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
@@ -2983,11 +2986,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] 687+ messages in thread
* [PATCH 6.18 238/686] drm/i915/display: Add enabled pipe planes into state for selective fetch
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (236 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 237/686] drm/i915/psr: Clear selective fetch area when duplicating plane state Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 239/686] drm/i915/psr: Disable linked plane sel fetch as well Greg Kroah-Hartman
` (447 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
6.18-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 6f9c22476b14d..bbf85f47a73ff 100644
--- a/drivers/gpu/drm/i915/display/intel_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_plane.c
@@ -1699,6 +1699,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 d41ad77c086f4..253045374a061 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2779,7 +2779,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
@@ -2894,19 +2894,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);
@@ -2957,11 +2953,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;
@@ -2975,9 +2966,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] 687+ messages in thread
* [PATCH 6.18 239/686] drm/i915/psr: Disable linked plane sel fetch as well
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (237 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 238/686] drm/i915/display: Add enabled pipe planes into state for selective fetch Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 240/686] drm/i915/psr: Fix SFF and CFF CTL register bit definitions Greg Kroah-Hartman
` (446 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
6.18-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 253045374a061..d1a9f9de75b9a 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2942,21 +2942,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
@@ -2964,16 +2957,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] 687+ messages in thread
* [PATCH 6.18 240/686] drm/i915/psr: Fix SFF and CFF CTL register bit definitions
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (238 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 239/686] drm/i915/psr: Disable linked plane sel fetch as well Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 241/686] drm/i915/psr: Dont clip plane state destination rectangle Greg Kroah-Hartman
` (445 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
6.18-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 8afbf5a383353..1e85860eefb83 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] 687+ messages in thread
* [PATCH 6.18 241/686] drm/i915/psr: Dont clip plane state destination rectangle
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (239 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 240/686] drm/i915/psr: Fix SFF and CFF CTL register bit definitions Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 242/686] drm/i915/gem: Reset err for each fence entry Greg Kroah-Hartman
` (444 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jouni Högander, Mika Kahola,
Joonas Lahtinen, Sasha Levin
6.18-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 d1a9f9de75b9a..ebade0f4e70ba 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -2592,23 +2592,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] 687+ messages in thread
* [PATCH 6.18 242/686] drm/i915/gem: Reset err for each fence entry
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (240 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 241/686] drm/i915/psr: Dont clip plane state destination rectangle Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 243/686] drm/i915/display: Single scaler per pipe on WCL Greg Kroah-Hartman
` (443 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lu Yao, Andi Shyti, Joonas Lahtinen,
Sasha Levin
6.18-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 61f1b8f172a76..e05b1e98c9b2b 100644
--- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c
@@ -2789,7 +2789,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)
@@ -2827,6 +2826,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] 687+ messages in thread
* [PATCH 6.18 243/686] drm/i915/display: Single scaler per pipe on WCL
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (241 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 242/686] drm/i915/gem: Reset err for each fence entry Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 244/686] net: atl1c: drop oversized RX frames instead of panicking Greg Kroah-Hartman
` (442 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Charlton Lin, Uma Shankar,
Vidya Srinivas, Joonas Lahtinen, Sasha Levin
6.18-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 f3f1f25b0f383..d94f07bda5ee6 100644
--- a/drivers/gpu/drm/i915/display/intel_display_device.c
+++ b/drivers/gpu/drm/i915/display/intel_display_device.c
@@ -1767,7 +1767,10 @@ static void __intel_display_device_info_runtime_init(struct intel_display *displ
if (display->platform.alderlake_s && IS_DISPLAY_STEP(display, STEP_A0, STEP_A2))
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] 687+ messages in thread
* [PATCH 6.18 244/686] net: atl1c: drop oversized RX frames instead of panicking
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (242 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 243/686] drm/i915/display: Single scaler per pipe on WCL Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 245/686] ksmbd: grant a POSIX ACL group entry only to the groups members Greg Kroah-Hartman
` (441 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Federico Musto, Dave Miller,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 245/686] ksmbd: grant a POSIX ACL group entry only to the groups members
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (243 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 244/686] net: atl1c: drop oversized RX frames instead of panicking Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 246/686] mm/mempolicy: charge shared policy nodes Greg Kroah-Hartman
` (440 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Ian Bridges,
Sasha Levin
6.18-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 33a607e709f18..63f7bccb4d9af 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -1606,7 +1606,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] 687+ messages in thread
* [PATCH 6.18 246/686] mm/mempolicy: charge shared policy nodes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (244 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 245/686] ksmbd: grant a POSIX ACL group entry only to the groups members Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 247/686] tmpfs: keep the quota soft limits of an unused id Greg Kroah-Hartman
` (439 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 919a505cabaee..3dfd20b55a9d7 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -3269,11 +3269,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] 687+ messages in thread
* [PATCH 6.18 247/686] tmpfs: keep the quota soft limits of an unused id
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (245 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 246/686] mm/mempolicy: charge shared policy nodes Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 248/686] tmpfs: preserve explicitly disabled quota limits Greg Kroah-Hartman
` (438 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jan Kara,
Gregory Price (Meta), David Hildenbrand (Arm), Sasha Levin
6.18-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 d1e32ac01407a..a359e8cceedb4 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] 687+ messages in thread
* [PATCH 6.18 248/686] tmpfs: preserve explicitly disabled quota limits
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (246 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 247/686] tmpfs: keep the quota soft limits of an unused id Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 249/686] mm/shmem: stop retrying folios that cannot be split Greg Kroah-Hartman
` (437 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Jan Kara,
Gregory Price (Meta), David Hildenbrand (Arm), Sasha Levin
6.18-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 a359e8cceedb4..868b3e05f1aa8 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] 687+ messages in thread
* [PATCH 6.18 249/686] mm/shmem: stop retrying folios that cannot be split
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (247 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 248/686] tmpfs: preserve explicitly disabled quota limits Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 250/686] mm/shmem: preserve data in clean folios when splitting fails Greg Kroah-Hartman
` (436 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Gregory Price (Meta),
Zi Yan, Balbir Singh, David Hildenbrand (Arm), Sasha Levin
6.18-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 68a3a0734e3df..2ee25d8ade752 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1243,6 +1243,15 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_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] 687+ messages in thread
* [PATCH 6.18 250/686] mm/shmem: preserve data in clean folios when splitting fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (248 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 249/686] mm/shmem: stop retrying folios that cannot be split Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 251/686] mm/shmem: discard whole new large folios on fallocate rollback Greg Kroah-Hartman
` (435 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 2ee25d8ade752..a764a26b0adf2 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1227,6 +1227,15 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_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] 687+ messages in thread
* [PATCH 6.18 251/686] mm/shmem: discard whole new large folios on fallocate rollback
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (249 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 250/686] mm/shmem: preserve data in clean folios when splitting fails Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 252/686] mm/shmem: rescan after nonuniform folio splitting Greg Kroah-Hartman
` (434 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 a764a26b0adf2..675d45aa85f64 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1236,7 +1236,7 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_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] 687+ messages in thread
* [PATCH 6.18 252/686] mm/shmem: rescan after nonuniform folio splitting
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (250 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 251/686] mm/shmem: discard whole new large folios on fallocate rollback Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 253/686] mm/shmem: fix truncate hang in large swap entry Greg Kroah-Hartman
` (433 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 675d45aa85f64..c598daacb5efa 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1240,18 +1240,12 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_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] 687+ messages in thread
* [PATCH 6.18 253/686] mm/shmem: fix truncate hang in large swap entry
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (251 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 252/686] mm/shmem: rescan after nonuniform folio splitting Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 254/686] mm/shmem: fix truncate loop after boundary swapin failure Greg Kroah-Hartman
` (432 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 c598daacb5efa..4c5e07c8f3173 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1057,12 +1057,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;
@@ -1073,13 +1071,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] 687+ messages in thread
* [PATCH 6.18 254/686] mm/shmem: fix truncate loop after boundary swapin failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (252 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 253/686] mm/shmem: fix truncate hang in large swap entry Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 255/686] mm/shmem: fix truncation of files containing only swapin-error markers Greg Kroah-Hartman
` (431 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 4c5e07c8f3173..169ba30664782 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1197,14 +1197,16 @@ static void shmem_undo_range(struct inode *inode, loff_t lstart, loff_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] 687+ messages in thread
* [PATCH 6.18 255/686] mm/shmem: fix truncation of files containing only swapin-error markers
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (253 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 254/686] mm/shmem: fix truncate loop after boundary swapin failure Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 256/686] mm/mglru: dont use stack pointers when walking PUD and PMD tables Greg Kroah-Hartman
` (430 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gregory Price (Meta), Baolin Wang,
David Hildenbrand (Arm), Sasha Levin
6.18-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 169ba30664782..da043ca0c2e22 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1351,7 +1351,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] 687+ messages in thread
* [PATCH 6.18 256/686] mm/mglru: dont use stack pointers when walking PUD and PMD tables
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (254 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 255/686] mm/shmem: fix truncation of files containing only swapin-error markers Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 257/686] mm/memfd: make f_pos accesses atomic Greg Kroah-Hartman
` (429 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 e640d1ec59749..ed75f1bce9f0a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -3750,7 +3750,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]++;
@@ -3786,7 +3786,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] 687+ messages in thread
* [PATCH 6.18 257/686] mm/memfd: make f_pos accesses atomic
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (255 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 256/686] mm/mglru: dont use stack pointers when walking PUD and PMD tables Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 258/686] mm/filemap: dont lose a folio lock wakeup to a signal Greg Kroah-Hartman
` (428 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 f7ba1e9dea49a..aa3c948e55738 100644
--- a/mm/memfd.c
+++ b/mm/memfd.c
@@ -472,6 +472,8 @@ static struct file *alloc_file(const char *name, unsigned int flags)
if (IS_ERR(file))
return file;
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] 687+ messages in thread
* [PATCH 6.18 258/686] mm/filemap: dont lose a folio lock wakeup to a signal
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (256 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 257/686] mm/memfd: make f_pos accesses atomic Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 259/686] mm/filemap: finish fault cleanup before dropping the fault lock Greg Kroah-Hartman
` (427 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 1a03588106090..7a8528d1daf79 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1383,10 +1383,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] 687+ messages in thread
* [PATCH 6.18 259/686] mm/filemap: finish fault cleanup before dropping the fault lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (257 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 258/686] mm/filemap: dont lose a folio lock wakeup to a signal Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 260/686] ext2: preserve completed DIO bytes when buffered fallback fails Greg Kroah-Hartman
` (426 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 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
6.18-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 7a8528d1daf79..cd7af384cff26 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3222,11 +3222,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)
@@ -3243,21 +3243,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;
}
@@ -3459,7 +3447,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.
@@ -3615,9 +3603,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);
@@ -3625,6 +3612,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] 687+ messages in thread
* [PATCH 6.18 260/686] ext2: preserve completed DIO bytes when buffered fallback fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (258 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 259/686] mm/filemap: finish fault cleanup before dropping the fault lock Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 261/686] xfs: dont skip free extents in later batches of a whole-AG FITRIM Greg Kroah-Hartman
` (425 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Jan Kara, Sasha Levin
6.18-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 c59c19e5ff72b..81f9cf3b884ce 100644
--- a/fs/ext2/file.c
+++ b/fs/ext2/file.c
@@ -256,7 +256,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] 687+ messages in thread
* [PATCH 6.18 261/686] xfs: dont skip free extents in later batches of a whole-AG FITRIM
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (259 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 260/686] ext2: preserve completed DIO bytes when buffered fallback fails Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 262/686] xfs: dont skip free extents of the longest length in " Greg Kroah-Hartman
` (424 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daejun Park, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-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 6917de8321915..b866329c7a28d 100644
--- a/fs/xfs/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -166,6 +166,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
@@ -209,14 +211,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;
@@ -246,9 +249,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;
}
@@ -351,6 +360,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] 687+ messages in thread
* [PATCH 6.18 262/686] xfs: dont skip free extents of the longest length in a whole-AG FITRIM
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (260 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 261/686] xfs: dont skip free extents in later batches of a whole-AG FITRIM Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 263/686] drm/v3d: Initialize timedout_batches when running a CSD job Greg Kroah-Hartman
` (423 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Chinner, Daejun Park,
Christoph Hellwig, Carlos Maiolino, Sasha Levin
6.18-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 b866329c7a28d..98933c1725214 100644
--- a/fs/xfs/xfs_discard.c
+++ b/fs/xfs/xfs_discard.c
@@ -211,12 +211,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] 687+ messages in thread
* [PATCH 6.18 263/686] drm/v3d: Initialize timedout_batches when running a CSD job
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (261 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 262/686] xfs: dont skip free extents of the longest length in " Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 264/686] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence Greg Kroah-Hartman
` (422 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jose Maria Casanova Crespo,
Iago Toral Quiroga, Maíra Canal, Sasha Levin
6.18-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 9b98386965796..5cdfc107a012d 100644
--- a/drivers/gpu/drm/v3d/v3d_sched.c
+++ b/drivers/gpu/drm/v3d/v3d_sched.c
@@ -403,6 +403,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, V3D_CSD);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 264/686] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (262 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 263/686] drm/v3d: Initialize timedout_batches when running a CSD job Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 265/686] cipso: fix optlen corruption in cipso_v4_delopt() Greg Kroah-Hartman
` (421 subsequent siblings)
685 siblings, 0 replies; 687+ 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,
Jose Maria Casanova Crespo, Maíra Canal, Sasha Levin
6.18-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 b499f6635cd24..92df68f5523b1 100644
--- a/drivers/gpu/drm/v3d/v3d_gem.c
+++ b/drivers/gpu/drm/v3d/v3d_gem.c
@@ -222,6 +222,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 */
@@ -238,7 +240,6 @@ v3d_clean_caches(struct v3d_dev *v3d)
DRM_ERROR("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));
@@ -248,8 +249,6 @@ v3d_clean_caches(struct v3d_dev *v3d)
DRM_ERROR("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] 687+ messages in thread
* [PATCH 6.18 265/686] cipso: fix optlen corruption in cipso_v4_delopt()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (263 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 264/686] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 266/686] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path Greg Kroah-Hartman
` (420 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qihang, Paul Moore, Dave Miller,
Sasha Levin
6.18-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 e741f0a47afbd..793c556c206d7 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -2014,6 +2014,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)
@@ -2027,11 +2031,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] 687+ messages in thread
* [PATCH 6.18 266/686] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (264 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 265/686] cipso: fix optlen corruption in cipso_v4_delopt() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 267/686] vringh: bound top-level re-entry into indirect tables Greg Kroah-Hartman
` (419 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tal Zussman, Linfeng Sun,
Michael S. Tsirkin, Sasha Levin
6.18-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 219af4f0d06a8..e4ddaf0e5abc6 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -1149,7 +1149,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;
@@ -1185,7 +1185,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);
@@ -1200,7 +1199,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]);
@@ -1231,7 +1229,6 @@ static int vhost_vdpa_pa_map(struct vhost_vdpa *v,
map_pfn = this_pfn;
iova += csize;
- nchunks = 0;
}
last_pfn = this_pfn;
@@ -1246,7 +1243,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;
/*
@@ -1258,7 +1255,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] 687+ messages in thread
* [PATCH 6.18 267/686] vringh: bound top-level re-entry into indirect tables
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (265 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 266/686] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 268/686] vringh: reject empty / undersized indirect descriptor tables Greg Kroah-Hartman
` (418 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xie Yongji, Fang Xieyan,
Michael S. Tsirkin, Sasha Levin
6.18-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 925858cc60964..c753a0cee240d 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] 687+ messages in thread
* [PATCH 6.18 268/686] vringh: reject empty / undersized indirect descriptor tables
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (266 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 267/686] vringh: bound top-level re-entry into indirect tables Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 269/686] veth: keep carrier off when resizing channels with a down peer Greg Kroah-Hartman
` (417 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fang Xieyan, Michael S. Tsirkin,
Sasha Levin
6.18-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 c753a0cee240d..3391413379579 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] 687+ messages in thread
* [PATCH 6.18 269/686] veth: keep carrier off when resizing channels with a down peer
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (267 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 268/686] vringh: reject empty / undersized indirect descriptor tables Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 270/686] hwmon: (corsair-cpro) Cache fan target only after a successful command Greg Kroah-Hartman
` (416 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hangbin Liu, Xia Yan, Jiayuan Chen,
Paolo Abeni, Sasha Levin
6.18-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 25cdbba5dfa9b..c2b8b9d02e357 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -1371,9 +1371,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] 687+ messages in thread
* [PATCH 6.18 270/686] hwmon: (corsair-cpro) Cache fan target only after a successful command
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (268 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 269/686] veth: keep carrier off when resizing channels with a down peer Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 271/686] hwmon: (aquacomputer_d5next) reject short status reports Greg Kroah-Hartman
` (415 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baek Kyu, Kim, Guenter Roeck,
Sasha Levin
6.18-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 17bb080eb9bb6..1c152a6db3806 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] 687+ messages in thread
* [PATCH 6.18 271/686] hwmon: (aquacomputer_d5next) reject short status reports
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (269 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 270/686] hwmon: (corsair-cpro) Cache fan target only after a successful command Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 272/686] hwmon: chipcap2: fix command error diagnostics Greg Kroah-Hartman
` (414 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Jiale Yao,
Sasha Levin
6.18-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 0dcb8a3a691d6..1f0e71d3b52e4 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -133,6 +133,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 */
@@ -156,6 +157,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 */
@@ -180,11 +183,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
@@ -194,6 +200,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
@@ -210,6 +218,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 */
@@ -230,6 +239,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 */
@@ -249,6 +259,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
@@ -264,6 +275,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
@@ -556,6 +568,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;
@@ -1356,6 +1369,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);
@@ -1541,6 +1556,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);
@@ -1608,6 +1624,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;
@@ -1633,6 +1650,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;
@@ -1643,6 +1661,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;
@@ -1659,6 +1678,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;
@@ -1688,6 +1708,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;
@@ -1717,6 +1738,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;
@@ -1734,6 +1756,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:
/*
@@ -1753,6 +1776,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;
@@ -1783,6 +1807,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;
@@ -1856,6 +1881,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] 687+ messages in thread
* [PATCH 6.18 272/686] hwmon: chipcap2: fix command error diagnostics
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (270 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 271/686] hwmon: (aquacomputer_d5next) reject short status reports Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 273/686] hwmon: chipcap2: fix off-by-one in command mode retry loop Greg Kroah-Hartman
` (413 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
6.18-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 0e182454779e0..b3d944852e73a 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -165,13 +165,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] 687+ messages in thread
* [PATCH 6.18 273/686] hwmon: chipcap2: fix off-by-one in command mode retry loop
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (271 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 272/686] hwmon: chipcap2: fix command error diagnostics Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 274/686] hwmon: chipcap2: fix be16 handling Greg Kroah-Hartman
` (412 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
6.18-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 b3d944852e73a..c5b6e147467cf 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -224,7 +224,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] 687+ messages in thread
* [PATCH 6.18 274/686] hwmon: chipcap2: fix be16 handling
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (272 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 273/686] hwmon: chipcap2: fix off-by-one in command mode retry loop Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 275/686] hwmon: chipcap2: defer probe when IRQs are unavailable Greg Kroah-Hartman
` (411 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
6.18-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 c5b6e147467cf..b7b59ca4a4f9d 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>
#define CC2_START_CM 0xA0
@@ -258,8 +259,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;
@@ -309,7 +309,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);
}
@@ -349,10 +349,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] 687+ messages in thread
* [PATCH 6.18 275/686] hwmon: chipcap2: defer probe when IRQs are unavailable
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (273 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 274/686] hwmon: chipcap2: fix be16 handling Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 276/686] hwmon: chipcap2: enable IRQ processing when regulator is already enabled Greg Kroah-Hartman
` (410 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
6.18-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 b7b59ca4a4f9d..34c3e26211458 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -624,6 +624,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,
@@ -641,6 +643,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,
@@ -654,6 +658,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] 687+ messages in thread
* [PATCH 6.18 276/686] hwmon: chipcap2: enable IRQ processing when regulator is already enabled
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (274 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 275/686] hwmon: chipcap2: defer probe when IRQs are unavailable Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 277/686] hwmon: chipcap2: balance regulator state Greg Kroah-Hartman
` (409 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
6.18-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 34c3e26211458..632efe64f190a 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -118,8 +118,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] 687+ messages in thread
* [PATCH 6.18 277/686] hwmon: chipcap2: balance regulator state
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (275 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 276/686] hwmon: chipcap2: enable IRQ processing when regulator is already enabled Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 278/686] hwmon: chipcap2: do not discard pending alarms on disable Greg Kroah-Hartman
` (408 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
6.18-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 632efe64f190a..3e8218a7ff2ad 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -89,6 +89,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 */
@@ -118,7 +119,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;
}
@@ -130,6 +131,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;
@@ -145,11 +148,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 int cc2_cmd_response_diagnostic(struct device *dev, u8 status)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 278/686] hwmon: chipcap2: do not discard pending alarms on disable
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (276 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 277/686] hwmon: chipcap2: balance regulator state Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 279/686] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices Greg Kroah-Hartman
` (407 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck,
Sasha Levin
6.18-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 3e8218a7ff2ad..5f4b0fd535af8 100644
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -144,6 +144,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] 687+ messages in thread
* [PATCH 6.18 279/686] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (277 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 278/686] hwmon: chipcap2: do not discard pending alarms on disable Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 280/686] hwmon: (asus_wmi_sensors) Avoid global struct mutation Greg Kroah-Hartman
` (406 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksa Savic, Jack Doan,
Guenter Roeck, Sasha Levin
6.18-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 1f0e71d3b52e4..e0052ba4702c6 100644
--- a/drivers/hwmon/aquacomputer_d5next.c
+++ b/drivers/hwmon/aquacomputer_d5next.c
@@ -1593,7 +1593,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] 687+ messages in thread
* [PATCH 6.18 280/686] hwmon: (asus_wmi_sensors) Avoid global struct mutation
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (278 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 279/686] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 281/686] hwmon: (hp-wmi-sensors) " Greg Kroah-Hartman
` (405 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ed Brindley, Denis Pauk,
Guenter Roeck, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 281/686] hwmon: (hp-wmi-sensors) Avoid global struct mutation
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (279 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 280/686] hwmon: (asus_wmi_sensors) Avoid global struct mutation Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 282/686] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor() Greg Kroah-Hartman
` (404 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, James Seo, Guenter Roeck,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 282/686] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (280 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 281/686] hwmon: (hp-wmi-sensors) " Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 283/686] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store() Greg Kroah-Hartman
` (403 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, James Seo, Guenter Roeck,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 283/686] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (281 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 282/686] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 284/686] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm() Greg Kroah-Hartman
` (402 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
6.18-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 d2d970e73c616..bdd633feb2ba8 100644
--- a/drivers/hwmon/lm87.c
+++ b/drivers/hwmon/lm87.c
@@ -600,13 +600,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] 687+ messages in thread
* [PATCH 6.18 284/686] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (282 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 283/686] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 285/686] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind Greg Kroah-Hartman
` (401 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
6.18-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 4a83804140386..05fc440f417c8 100644
--- a/drivers/hwmon/nct6683.c
+++ b/drivers/hwmon/nct6683.c
@@ -918,7 +918,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]);
@@ -928,7 +928,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] 687+ messages in thread
* [PATCH 6.18 285/686] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (283 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 284/686] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm() Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 286/686] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check Greg Kroah-Hartman
` (400 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Iwona Winiarska, Guenter Roeck,
Sasha Levin
6.18-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 fbe82d9852e01..d327e38d59e18 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>
@@ -331,11 +330,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;
@@ -405,10 +406,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) {
@@ -419,6 +418,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)
{
@@ -655,6 +661,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] 687+ messages in thread
* [PATCH 6.18 286/686] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (284 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 285/686] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind Greg Kroah-Hartman
@ 2026-11-13 15:46 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 287/686] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor() Greg Kroah-Hartman
` (399 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:46 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
6.18-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 7b0d292a425ae..1f2811354aac3 100644
--- a/drivers/hwmon/pmbus/q54sj108a2.c
+++ b/drivers/hwmon/pmbus/q54sj108a2.c
@@ -343,6 +343,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] 687+ messages in thread
* [PATCH 6.18 287/686] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (285 preceding siblings ...)
2026-11-13 15:46 ` [PATCH 6.18 286/686] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 288/686] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error Greg Kroah-Hartman
` (398 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
6.18-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 aa578d2723f22..08702ee8105f4 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1420,10 +1420,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)
@@ -1448,14 +1449,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;
}
@@ -1556,8 +1560,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,
@@ -1596,8 +1600,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,
@@ -2270,8 +2274,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)))
@@ -2281,15 +2285,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;
}
@@ -2306,6 +2310,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]))
@@ -2326,10 +2331,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] 687+ messages in thread
* [PATCH 6.18 288/686] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (286 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 287/686] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 289/686] hwmon: (pmbus) Fix return value check from thermal zone registration Greg Kroah-Hartman
` (397 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
6.18-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 08702ee8105f4..3f310c8e97012 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1404,8 +1404,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] 687+ messages in thread
* [PATCH 6.18 289/686] hwmon: (pmbus) Fix return value check from thermal zone registration
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (287 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 288/686] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 290/686] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference Greg Kroah-Hartman
` (396 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
6.18-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 3f310c8e97012..acab5fdf108e7 100644
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1401,10 +1401,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] 687+ messages in thread
* [PATCH 6.18 290/686] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (288 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 289/686] hwmon: (pmbus) Fix return value check from thermal zone registration Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 291/686] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks Greg Kroah-Hartman
` (395 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 1dfc02df9bbb0..34986266180e2 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] 687+ messages in thread
* [PATCH 6.18 291/686] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (289 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 290/686] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 292/686] hwmon: (sht4x) Convert update_interval to jiffies in pending data check Greg Kroah-Hartman
` (394 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Asaf Nuri Bertizlioğlu,
Guenter Roeck, Sasha Levin
6.18-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 c9b7e435eda81..ac56319ff90cf 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -686,6 +686,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;
@@ -737,6 +740,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] 687+ messages in thread
* [PATCH 6.18 292/686] hwmon: (sht4x) Convert update_interval to jiffies in pending data check
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (290 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 291/686] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 293/686] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings Greg Kroah-Hartman
` (393 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Guenter Roeck, Sasha Levin
6.18-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 83dc3ca67046b..53c8feb7e2910 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] 687+ messages in thread
* [PATCH 6.18 293/686] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (291 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 292/686] hwmon: (sht4x) Convert update_interval to jiffies in pending data check Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 294/686] nvme: unregister when pr_register() is given a zero new key Greg Kroah-Hartman
` (392 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vas Zayarskiy, Guenter Roeck,
Sasha Levin
6.18-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 e0052ba4702c6..95ec74c6e67eb 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/mutex.h>
#include <linux/seq_file.h>
@@ -614,9 +615,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;
@@ -1009,7 +1010,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);
@@ -1042,6 +1043,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);
@@ -1106,7 +1108,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) {
@@ -1406,9 +1411,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;
@@ -1448,7 +1453,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;
@@ -1461,10 +1467,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] 687+ messages in thread
* [PATCH 6.18 294/686] nvme: unregister when pr_register() is given a zero new key
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (292 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 293/686] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 295/686] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure Greg Kroah-Hartman
` (391 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Daejun Park,
Keith Busch, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 295/686] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (293 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 294/686] nvme: unregister when pr_register() is given a zero new key Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 296/686] KVM: x86: Conditionally resched when restarting REP string emulation Greg Kroah-Hartman
` (390 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
6.18-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 4e84b5a1eeaaa..ec265eb196da4 100644
--- a/arch/x86/kvm/mmu/paging_tmpl.h
+++ b/arch/x86/kvm/mmu/paging_tmpl.h
@@ -321,6 +321,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 = mmu->cpu_role.base.level;
@@ -471,8 +478,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] 687+ messages in thread
* [PATCH 6.18 296/686] KVM: x86: Conditionally resched when restarting REP string emulation
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (294 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 295/686] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 297/686] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry Greg Kroah-Hartman
` (389 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Woodhouse, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
6.18-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 6576c692a94eb..0a6fb6e08d1bd 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -9218,10 +9218,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] 687+ messages in thread
* [PATCH 6.18 297/686] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (295 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 296/686] KVM: x86: Conditionally resched when restarting REP string emulation Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 298/686] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit) Greg Kroah-Hartman
` (388 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Woodhouse, Stefan Teodorescu,
Sean Christopherson, Paolo Bonzini, Sasha Levin
6.18-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 ab1558f1f9f8d..ffca5fef5b5ea 100644
--- a/arch/x86/kvm/vmx/nested.c
+++ b/arch/x86/kvm/vmx/nested.c
@@ -5136,6 +5136,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] 687+ messages in thread
* [PATCH 6.18 298/686] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit)
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (296 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 297/686] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 299/686] KVM: x86: Unconditionally reset MMU context when emulating INIT Greg Kroah-Hartman
` (387 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 24f22c10e6774..3b1fb5696ed65 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -2279,6 +2279,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] 687+ messages in thread
* [PATCH 6.18 299/686] KVM: x86: Unconditionally reset MMU context when emulating INIT
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (297 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 298/686] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit) Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 300/686] ipv6: reject wrapped temporary address preferred lifetimes Greg Kroah-Hartman
` (386 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Stefan Teodorescu, Oren Yomtov,
Chris Mason, Yosry Ahmed, Sean Christopherson, Paolo Bonzini,
Sasha Levin
6.18-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 0a6fb6e08d1bd..3ca396316d3cf 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -12278,18 +12278,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] 687+ messages in thread
* [PATCH 6.18 300/686] ipv6: reject wrapped temporary address preferred lifetimes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (298 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 299/686] KVM: x86: Unconditionally reset MMU context when emulating INIT Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 301/686] x86/vmware: Fix i386 high-bandwidth hypercall arguments Greg Kroah-Hartman
` (385 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Yingjie Wang,
Alex Henrie, Paolo Abeni, Sasha Levin
6.18-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 527ae9fc1c41c..8f651cafcb2a5 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] 687+ messages in thread
* [PATCH 6.18 301/686] x86/vmware: Fix i386 high-bandwidth hypercall arguments
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (299 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 300/686] ipv6: reject wrapped temporary address preferred lifetimes Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 302/686] Bluetooth: hci_sync: re-enable legacy advertising on resume Greg Kroah-Hartman
` (384 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zack Rusin, Borislav Petkov (AMD),
Maaz Mombasawala, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 302/686] Bluetooth: hci_sync: re-enable legacy advertising on resume
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (300 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 301/686] x86/vmware: Fix i386 high-bandwidth hypercall arguments Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 303/686] Bluetooth: hci_sync: pause advertising for the scan address update Greg Kroah-Hartman
` (383 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Valentin Kindschi,
Luiz Augusto von Dentz, Sasha Levin
6.18-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 8da58c61e9723..1bdaf7b2e01e1 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -2708,7 +2708,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)
@@ -2741,13 +2741,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] 687+ messages in thread
* [PATCH 6.18 303/686] Bluetooth: hci_sync: pause advertising for the scan address update
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (301 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 302/686] Bluetooth: hci_sync: re-enable legacy advertising on resume Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 304/686] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset Greg Kroah-Hartman
` (382 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Valentin Kindschi,
Luiz Augusto von Dentz, Sasha Levin
6.18-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 1bdaf7b2e01e1..9cb1cdbff3fd2 100644
--- a/net/bluetooth/hci_sync.c
+++ b/net/bluetooth/hci_sync.c
@@ -6146,6 +6146,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, "");
@@ -6169,6 +6170,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.
@@ -6178,6 +6185,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)) {
@@ -6201,9 +6211,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] 687+ messages in thread
* [PATCH 6.18 304/686] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (302 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 303/686] Bluetooth: hci_sync: pause advertising for the scan address update Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 305/686] ASoC: qcom: q6apm: Guard callbacks until probe data is ready Greg Kroah-Hartman
` (381 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael McAllister,
Bartosz Golaszewski, Luiz Augusto von Dentz, Sasha Levin
6.18-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 bdbb5801b2400..4215522e62a2c 100644
--- a/drivers/bluetooth/btqca.c
+++ b/drivers/bluetooth/btqca.c
@@ -443,7 +443,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] 687+ messages in thread
* [PATCH 6.18 305/686] ASoC: qcom: q6apm: Guard callbacks until probe data is ready
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (303 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 304/686] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 306/686] x86/resctrl: Correct ABMC counter ID field width Greg Kroah-Hartman
` (380 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ajay Kumar Nandam, Mohit Sharma,
Mark Brown, Sasha Levin
6.18-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 50d5d2143daaf..7894d4430ff17 100644
--- a/sound/soc/qcom/qdsp6/q6apm.c
+++ b/sound/soc/qcom/qdsp6/q6apm.c
@@ -765,8 +765,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;
@@ -780,6 +778,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);
@@ -820,6 +819,9 @@ static int apm_callback(struct gpr_resp_pkt *data, void *priv, int op)
struct gpr_ibasic_rsp_result_t *result;
struct gpr_hdr *hdr = &data->hdr;
+ 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 81554d2026589..22e2a174a3871 100644
--- a/sound/soc/qcom/qdsp6/q6prm.c
+++ b/sound/soc/qcom/qdsp6/q6prm.c
@@ -197,6 +197,9 @@ static int prm_callback(struct gpr_resp_pkt *data, void *priv, int op)
struct gpr_ibasic_rsp_result_t *result;
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] 687+ messages in thread
* [PATCH 6.18 306/686] x86/resctrl: Correct ABMC counter ID field width
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (304 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 305/686] ASoC: qcom: q6apm: Guard callbacks until probe data is ready Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 307/686] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot Greg Kroah-Hartman
` (379 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Babu Moger, Borislav Petkov (AMD),
Reinette Chatre, Sasha Levin
6.18-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 6c9e75440c10e..6dd132414a95c 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -201,8 +201,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 9fc3adb4b232c..db0577d47b677 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -476,7 +476,8 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL))) {
r->mon.mbm_cntr_assignable = 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] 687+ messages in thread
* [PATCH 6.18 307/686] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (305 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 306/686] x86/resctrl: Correct ABMC counter ID field width Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 308/686] mm/khugepaged: flush deferred unmaps before dropping a failed folio Greg Kroah-Hartman
` (378 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Babu Moger, Borislav Petkov (AMD),
Sasha Levin
6.18-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 b7f35b07876a9..e48298f3babb8 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -260,12 +260,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":
@@ -283,20 +283,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:
::
@@ -308,6 +305,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.
@@ -1639,17 +1654,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.
::
@@ -1660,36 +1677,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
@@ -1746,13 +1766,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 db0577d47b677..d16253607ac47 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -478,7 +478,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] 687+ messages in thread
* [PATCH 6.18 308/686] mm/khugepaged: flush deferred unmaps before dropping a failed folio
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (306 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 307/686] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 309/686] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares Greg Kroah-Hartman
` (377 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 cc3a09a0c2596..8ed9b2a3e8f07 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2068,6 +2068,11 @@ static int 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;
@@ -2078,9 +2083,8 @@ static int 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] 687+ messages in thread
* [PATCH 6.18 309/686] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (307 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 308/686] mm/khugepaged: flush deferred unmaps before dropping a failed folio Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 310/686] mm/hugetlb: fix mremap move length truncation Greg Kroah-Hartman
` (376 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 757bc4d3b5b55..17b12b4c4b667 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -902,6 +902,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;
@@ -913,13 +914,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
@@ -935,7 +937,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] 687+ messages in thread
* [PATCH 6.18 310/686] mm/hugetlb: fix mremap move length truncation
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (308 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 309/686] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 311/686] mm/hugetlb: fix mremap deadlock when PMD sharing is possible Greg Kroah-Hartman
` (375 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 ca6d6eb817118..d43965f4b6c82 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -122,10 +122,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 *,
@@ -340,11 +339,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 42aace6e3ca17..1d71352bfec57 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5828,10 +5828,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] 687+ messages in thread
* [PATCH 6.18 311/686] mm/hugetlb: fix mremap deadlock when PMD sharing is possible
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (309 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 310/686] mm/hugetlb: fix mremap move length truncation Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 312/686] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged Greg Kroah-Hartman
` (374 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 1d71352bfec57..bf1188e9b1c9b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -126,6 +126,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 void hugetlb_free_folio(struct folio *folio)
@@ -5860,6 +5864,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) {
@@ -5876,6 +5882,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;
@@ -5895,9 +5919,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;
@@ -5915,13 +5940,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) {
@@ -6050,6 +6068,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] 687+ messages in thread
* [PATCH 6.18 312/686] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (310 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 311/686] mm/hugetlb: fix mremap deadlock when PMD sharing is possible Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 313/686] mm/ksm: keep soft-dirty when merging a page Greg Kroah-Hartman
` (373 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 a27ba1c1a7192..4e00624e3c7b5 100644
--- a/mm/mm_init.c
+++ b/mm/mm_init.c
@@ -2524,8 +2524,6 @@ void __init memblock_free_pages(struct page *page, unsigned long pfn,
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 8d608699bf508..2685e570bf7de 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1662,6 +1662,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] 687+ messages in thread
* [PATCH 6.18 313/686] mm/ksm: keep soft-dirty when merging a page
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (311 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 312/686] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 314/686] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls Greg Kroah-Hartman
` (372 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 80274ace8155e..1eee363fd727e 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -1414,6 +1414,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] 687+ messages in thread
* [PATCH 6.18 314/686] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (312 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 313/686] mm/ksm: keep soft-dirty when merging a page Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 315/686] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store() Greg Kroah-Hartman
` (371 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 0f08913cfa529..823e8ee1b0953 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -3179,7 +3179,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] 687+ messages in thread
* [PATCH 6.18 315/686] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (313 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 314/686] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 316/686] mm: make swapoff interruptible when unusing mms/shmem Greg Kroah-Hartman
` (370 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton, Sasha Levin
6.18-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 952e12fd6dbf7..f90d079dc9628 100644
--- a/mm/damon/sysfs-schemes.c
+++ b/mm/damon/sysfs-schemes.c
@@ -1072,7 +1072,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] 687+ messages in thread
* [PATCH 6.18 316/686] mm: make swapoff interruptible when unusing mms/shmem
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (314 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 315/686] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 317/686] mm/migrate: untag addresses when querying page nodes Greg Kroah-Hartman
` (369 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 da043ca0c2e22..5efde9fcc3057 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1519,6 +1519,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 3ffa258de79ec..3a786446dacbe 100644
--- a/mm/swapfile.c
+++ b/mm/swapfile.c
@@ -2349,6 +2349,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)
@@ -2562,7 +2564,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] 687+ messages in thread
* [PATCH 6.18 317/686] mm/migrate: untag addresses when querying page nodes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (315 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 316/686] mm: make swapoff interruptible when unusing mms/shmem Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 318/686] mm/migrate: snapshot the source nid before the misplaced migration Greg Kroah-Hartman
` (368 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 08f1382318024..0d2b327368073 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2448,7 +2448,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] 687+ messages in thread
* [PATCH 6.18 318/686] mm/migrate: snapshot the source nid before the misplaced migration
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (316 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 317/686] mm/migrate: untag addresses when querying page nodes Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 319/686] mm/vma: update VMA iterator state on error in new VMA merge Greg Kroah-Hartman
` (367 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 0d2b327368073..2a5846a86baf8 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -2737,6 +2737,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);
@@ -2751,7 +2752,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] 687+ messages in thread
* [PATCH 6.18 319/686] mm/vma: update VMA iterator state on error in new VMA merge
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (317 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 318/686] mm/migrate: snapshot the source nid before the misplaced migration Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 320/686] mm/cma: accept memory of multi-range CMA areas Greg Kroah-Hartman
` (366 subsequent siblings)
685 siblings, 0 replies; 687+ 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), Andrew Morton,
Li Jinyue, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Sasha Levin
6.18-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 d1627a8ef32b1..dadf7d69182c2 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -1046,6 +1046,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);
@@ -1083,23 +1084,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;
}
/*
@@ -1190,7 +1198,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_start_write(next);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 320/686] mm/cma: accept memory of multi-range CMA areas
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (318 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 319/686] mm/vma: update VMA iterator state on error in new VMA merge Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 321/686] mm/cma: accept memory of CMA areas reserved at a fixed address Greg Kroah-Hartman
` (365 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 90d3ab262dae0..d829726319d81 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -674,6 +674,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] 687+ messages in thread
* [PATCH 6.18 321/686] mm/cma: accept memory of CMA areas reserved at a fixed address
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (319 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 320/686] mm/cma: accept memory of multi-range CMA areas Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 322/686] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg Greg Kroah-Hartman
` (364 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 d829726319d81..f5c9da62aeb57 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -377,6 +377,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] 687+ messages in thread
* [PATCH 6.18 322/686] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (320 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 321/686] mm/cma: accept memory of CMA areas reserved at a fixed address Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 323/686] openrisc: export __mulsi3 for modules Greg Kroah-Hartman
` (363 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 eec89dcb7801b..97ed5ad4053f0 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -2062,7 +2062,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);
}
/*
@@ -3906,6 +3909,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] 687+ messages in thread
* [PATCH 6.18 323/686] openrisc: export __mulsi3 for modules
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (321 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 322/686] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 324/686] ocfs2: find the xattr entry again after defragmenting a bucket Greg Kroah-Hartman
` (362 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 212e5f85004cc..c63d7f25bc575 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] 687+ messages in thread
* [PATCH 6.18 324/686] ocfs2: find the xattr entry again after defragmenting a bucket
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (322 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 323/686] openrisc: export __mulsi3 for modules Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 325/686] ocfs2: find the xattr entry again after converting a block to " Greg Kroah-Hartman
` (361 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
6.18-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 734801de8e89e..e83db0ca737a6 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -5635,13 +5635,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;
@@ -5660,6 +5665,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] 687+ messages in thread
* [PATCH 6.18 325/686] ocfs2: find the xattr entry again after converting a block to a bucket
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (323 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 324/686] ocfs2: find the xattr entry again after defragmenting a bucket Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 326/686] ocfs2: do not read the entry array of an empty xattr bucket Greg Kroah-Hartman
` (360 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
6.18-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 e83db0ca737a6..406b40375f6c7 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -256,6 +256,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);
@@ -3013,7 +3014,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;
}
@@ -4341,13 +4342,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);
@@ -4356,11 +4354,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)
{
@@ -4427,7 +4461,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] 687+ messages in thread
* [PATCH 6.18 326/686] ocfs2: do not read the entry array of an empty xattr bucket
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (324 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 325/686] ocfs2: find the xattr entry again after converting a block to " Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 327/686] ocfs2: do not index before the entry array when dividing an empty bucket Greg Kroah-Hartman
` (359 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
6.18-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 406b40375f6c7..a82fb4a5084c3 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -5644,11 +5644,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] 687+ messages in thread
* [PATCH 6.18 327/686] ocfs2: do not index before the entry array when dividing an empty bucket
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (325 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 326/686] ocfs2: do not read the entry array of an empty xattr bucket Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 328/686] ocfs2: do not read the entry array of an empty xattr block Greg Kroah-Hartman
` (358 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
6.18-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 a82fb4a5084c3..5f263d24bbc3b 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -4814,7 +4814,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] 687+ messages in thread
* [PATCH 6.18 328/686] ocfs2: do not read the entry array of an empty xattr block
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (326 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 327/686] ocfs2: do not index before the entry array when dividing an empty bucket Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 329/686] fat: hold truncate_lock in fat_write_failed() Greg Kroah-Hartman
` (357 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joseph Qi, Andrew Morton,
Heming Zhao, Mark Fasheh, Joel Becker, Sasha Levin
6.18-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 5f263d24bbc3b..921d050c37581 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -4296,6 +4296,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] 687+ messages in thread
* [PATCH 6.18 329/686] fat: hold truncate_lock in fat_write_failed()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (327 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 328/686] ocfs2: do not read the entry array of an empty xattr block Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 330/686] ocfs2: keep locking_state within the cluster connection lifetime Greg Kroah-Hartman
` (356 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matheus Alves de Almeida,
Andrew Morton, OGAWA Hirofumi, Pedro Falcato, Sasha Levin
6.18-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 9cfe20a3daaf6..1a951dfb33dc0 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -215,7 +215,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] 687+ messages in thread
* [PATCH 6.18 330/686] ocfs2: keep locking_state within the cluster connection lifetime
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (328 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 329/686] fat: hold truncate_lock in fat_write_failed() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 331/686] ocfs2/dlm: serialize migration MLE cleanup on failure Greg Kroah-Hartman
` (355 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 90d23dd7d4c8f..6f44f9f230596 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] 687+ messages in thread
* [PATCH 6.18 331/686] ocfs2/dlm: serialize migration MLE cleanup on failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (329 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 330/686] ocfs2: keep locking_state within the cluster connection lifetime Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 332/686] ocfs2: stop recovery before shutting down local allocators Greg Kroah-Hartman
` (354 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 4ab8c48582b15..ee28a01e7be34 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -2526,6 +2526,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)
{
@@ -2610,9 +2656,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;
@@ -2641,9 +2688,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;
@@ -2687,9 +2736,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] 687+ messages in thread
* [PATCH 6.18 332/686] ocfs2: stop recovery before shutting down local allocators
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (330 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 331/686] ocfs2/dlm: serialize migration MLE cleanup on failure Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 333/686] ocfs2/cluster: unlink socket containers before releasing resources Greg Kroah-Hartman
` (353 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 2b8b57e914f08..602b6c8dc39fc 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -230,13 +230,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 fe4ab1659e0d9..ed5b303f56bf6 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -1829,6 +1829,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] 687+ messages in thread
* [PATCH 6.18 333/686] ocfs2/cluster: unlink socket containers before releasing resources
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (331 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 332/686] ocfs2: stop recovery before shutting down local allocators Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 334/686] ocfs2: wait for filecheck kobject release after a failed add Greg Kroah-Hartman
` (352 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 32048c65b66ba..07b2252779410 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] 687+ messages in thread
* [PATCH 6.18 334/686] ocfs2: wait for filecheck kobject release after a failed add
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (332 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 333/686] ocfs2/cluster: unlink socket containers before releasing resources Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 335/686] ocfs2: cache the mount context for dentry lock callbacks Greg Kroah-Hartman
` (351 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 47659ef73ca22..e676839078f44 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] 687+ messages in thread
* [PATCH 6.18 335/686] ocfs2: cache the mount context for dentry lock callbacks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (333 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 334/686] ocfs2: wait for filecheck kobject release after a failed add Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 336/686] x86/init: Initialize wall clock in get_rtc_noop() Greg Kroah-Hartman
` (350 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 6f44f9f230596..fdd0ed900e7e7 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] 687+ messages in thread
* [PATCH 6.18 336/686] x86/init: Initialize wall clock in get_rtc_noop()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (334 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 335/686] ocfs2: cache the mount context for dentry lock callbacks Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 337/686] xfs: fix temporary cursor leak in btree shift corruption paths Greg Kroah-Hartman
` (349 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 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
6.18-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 0a2bbd674a6d9..c1e20abc7fe52 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -36,7 +36,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] 687+ messages in thread
* [PATCH 6.18 337/686] xfs: fix temporary cursor leak in btree shift corruption paths
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (335 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 336/686] x86/init: Initialize wall clock in get_rtc_noop() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 338/686] net/sched: sch_qfq: prevent aggregate self-replacement Greg Kroah-Hartman
` (348 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jianyun Gao, Carlos Maiolino,
Carlos Maiolino, Sasha Levin
6.18-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 dbe9df8c33004..b0824d381e7c6 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] 687+ messages in thread
* [PATCH 6.18 338/686] net/sched: sch_qfq: prevent aggregate self-replacement
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (336 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 337/686] xfs: fix temporary cursor leak in btree shift corruption paths Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 339/686] vhost-scsi: zero misaligned I/O bounce pages Greg Kroah-Hartman
` (347 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, David Lee, Paolo Abeni,
Sasha Levin
6.18-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 7d93690cb4360..d82b04827c2c4 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] 687+ messages in thread
* [PATCH 6.18 339/686] vhost-scsi: zero misaligned I/O bounce pages
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (337 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 338/686] net/sched: sch_qfq: prevent aggregate self-replacement Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 340/686] vhost: fix used ring index wrap in vhost_add_used_n_in_order Greg Kroah-Hartman
` (346 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shubham Antil, Mike Christie,
Michael S. Tsirkin, Sasha Levin
6.18-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 deb4c8bfd3d57..fac400b25dad7 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -906,7 +906,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] 687+ messages in thread
* [PATCH 6.18 340/686] vhost: fix used ring index wrap in vhost_add_used_n_in_order
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (338 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 339/686] vhost-scsi: zero misaligned I/O bounce pages Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 341/686] iommu/virtio: Reset device before deleting virtqueues on probe failure Greg Kroah-Hartman
` (345 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Weibin Liu, Fang Xieyan,
Eugenio Pérez, Michael S. Tsirkin, Sasha Levin
6.18-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 ebdbf1cf9143a..78cee55cedf85 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -3145,8 +3145,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] 687+ messages in thread
* [PATCH 6.18 341/686] iommu/virtio: Reset device before deleting virtqueues on probe failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (339 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 340/686] vhost: fix used ring index wrap in vhost_add_used_n_in_order Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 342/686] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg() Greg Kroah-Hartman
` (344 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuho Choi, Michael S. Tsirkin,
Sasha Levin
6.18-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 d314fa5cd8476..3aa54bd716728 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] 687+ messages in thread
* [PATCH 6.18 342/686] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (340 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 341/686] iommu/virtio: Reset device before deleting virtqueues on probe failure Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 343/686] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Greg Kroah-Hartman
` (343 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuho Choi, Michael S. Tsirkin,
Sasha Levin
6.18-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 3cef2571d15d3..1c3b5f2e44990 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] 687+ messages in thread
* [PATCH 6.18 343/686] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (341 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 342/686] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg() Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 344/686] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Greg Kroah-Hartman
` (342 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luca Ceresoli, Esben Haabendal,
Sasha Levin
6.18-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 2f7429b24fc20..29f175c0d118c 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] 687+ messages in thread
* [PATCH 6.18 344/686] drm/bridge: nwl-dsi: Limit LCDIF specific sync override
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (342 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 343/686] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 345/686] hwrng: virtio - prevent use-after-free after a failed restore Greg Kroah-Hartman
` (341 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Luca Ceresoli, Esben Haabendal,
Sasha Levin
6.18-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 29f175c0d118c..38bc83e7af475 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] 687+ messages in thread
* [PATCH 6.18 345/686] hwrng: virtio - prevent use-after-free after a failed restore
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (343 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 344/686] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 346/686] vduse: fix VA/PA confusion in the coherent page fault path Greg Kroah-Hartman
` (340 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Michael S. Tsirkin,
Sasha Levin, PrasannaKumar Muralidharan
6.18-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 2933f8cb769e4..fcb60d4deaacd 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -187,6 +187,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;
}
@@ -195,6 +196,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;
@@ -204,6 +210,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] 687+ messages in thread
* [PATCH 6.18 346/686] vduse: fix VA/PA confusion in the coherent page fault path
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (344 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 345/686] hwrng: virtio - prevent use-after-free after a failed restore Greg Kroah-Hartman
@ 2026-11-13 15:47 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 347/686] inotify: do not coalesce rename events Greg Kroah-Hartman
` (339 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:47 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xie Yongji, chenglong.ma,
Michael S. Tsirkin, Sasha Levin, Claude Code
6.18-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 e8b837df328f0..b8b2eb44410da 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] 687+ messages in thread
* [PATCH 6.18 347/686] inotify: do not coalesce rename events
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (345 preceding siblings ...)
2026-11-13 15:47 ` [PATCH 6.18 346/686] vduse: fix VA/PA confusion in the coherent page fault path Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 348/686] blk-mq: end the request if getting a keyslot fails Greg Kroah-Hartman
` (338 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amir Goldstein, Hungyu Lin, Jan Kara,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 348/686] blk-mq: end the request if getting a keyslot fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (346 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 347/686] inotify: do not coalesce rename events Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 349/686] virtio_blk: use synchronous quiesce in virtblk_freeze_priv() Greg Kroah-Hartman
` (337 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Eric Biggers,
Christoph Hellwig, Jens Axboe, Sasha Levin
6.18-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 cced68a0e3c53..b7347c4462cb3 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3223,16 +3223,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] 687+ messages in thread
* [PATCH 6.18 349/686] virtio_blk: use synchronous quiesce in virtblk_freeze_priv()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (347 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 348/686] blk-mq: end the request if getting a keyslot fails Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 350/686] block: Return the soft block size for compat BLKBSZGET Greg Kroah-Hartman
` (336 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Wang, Stefan Hajnoczi,
Cong Zhang, Jens Axboe, Sasha Levin
6.18-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 e577b02cf4003..84dc751266e9b 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -1588,7 +1588,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] 687+ messages in thread
* [PATCH 6.18 350/686] block: Return the soft block size for compat BLKBSZGET
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (348 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 349/686] virtio_blk: use synchronous quiesce in virtblk_freeze_priv() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 351/686] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin() Greg Kroah-Hartman
` (335 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Christoph Hellwig,
Arnd Bergmann, Jens Axboe, Sasha Levin
6.18-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 801f904b5af47..c038a4b27b573 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -742,8 +742,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] 687+ messages in thread
* [PATCH 6.18 351/686] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (349 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 350/686] block: Return the soft block size for compat BLKBSZGET Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 352/686] blk-mq: fix out-of-bounds read in blk_mq_free_rqs Greg Kroah-Hartman
` (334 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Reid Downing, Carlos Maiolino,
Carlos Maiolino, Sasha Levin
6.18-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 b64785dc4354e..c2e01fcb6015d 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] 687+ messages in thread
* [PATCH 6.18 352/686] blk-mq: fix out-of-bounds read in blk_mq_free_rqs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (350 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 351/686] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 353/686] blk-iocost: account flush sequence latency only once Greg Kroah-Hartman
` (333 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+e90526cab23b9efcd03c,
Nilay Shorff, Krystian Kaniewski, syzbot, Jens Axboe, Sasha Levin
6.18-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 b7347c4462cb3..82df2f6073d8d 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -3495,8 +3495,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] 687+ messages in thread
* [PATCH 6.18 353/686] blk-iocost: account flush sequence latency only once
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (351 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 352/686] blk-mq: fix out-of-bounds read in blk_mq_free_rqs Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 354/686] xfs: mark the inode preallocated for pNFS write layouts past EOF Greg Kroah-Hartman
` (332 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhe Liu, Tejun Heo, Jens Axboe,
Sasha Levin
6.18-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 5c7cdb493768c..8c0214d48e3e6 100644
--- a/block/blk-iocost.c
+++ b/block/blk-iocost.c
@@ -2818,6 +2818,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] 687+ messages in thread
* [PATCH 6.18 354/686] xfs: mark the inode preallocated for pNFS write layouts past EOF
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (352 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 353/686] blk-iocost: account flush sequence latency only once Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 355/686] xfs: add a flag to convert unwritten extents without allocating blocks Greg Kroah-Hartman
` (331 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chuck Lever, Daejun Park,
Christoph Hellwig, Pankaj Raghav, Carlos Maiolino, Sasha Levin
6.18-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 1b0b739571612..ef08f0f619f70 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);
}
/*
@@ -135,6 +143,7 @@ xfs_fs_map_blocks(
uint lock_flags;
int error = 0;
u64 seq;
+ bool update_inode = false;
if (xfs_is_shutdown(mp))
return -EIO;
@@ -203,20 +212,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] 687+ messages in thread
* [PATCH 6.18 355/686] xfs: add a flag to convert unwritten extents without allocating blocks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (353 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 354/686] xfs: mark the inode preallocated for pNFS write layouts past EOF Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 356/686] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Greg Kroah-Hartman
` (330 subsequent siblings)
685 siblings, 0 replies; 687+ 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,
Pankaj Raghav, Carlos Maiolino, Sasha Levin
6.18-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 bdffade9848f8..8fc6ee96e1f56 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -4130,6 +4130,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(
@@ -4189,6 +4191,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)) {
@@ -4237,6 +4241,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;
@@ -4332,10 +4339,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] 687+ messages in thread
* [PATCH 6.18 356/686] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (354 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 355/686] xfs: add a flag to convert unwritten extents without allocating blocks Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 357/686] xfs: cap the block count of xfs_iomap_write_direct() at one extent Greg Kroah-Hartman
` (329 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daejun Park, Christoph Hellwig,
Pankaj Raghav, Carlos Maiolino, Sasha Levin
6.18-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 ef08f0f619f70..b880d061ee90c 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -311,9 +311,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] 687+ messages in thread
* [PATCH 6.18 357/686] xfs: cap the block count of xfs_iomap_write_direct() at one extent
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (355 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 356/686] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 358/686] xfs: clamp the pNFS layout range to the maximum file size Greg Kroah-Hartman
` (328 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Pankaj Raghav, Daejun Park, Carlos Maiolino, Sasha Levin
6.18-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 a1c88df45dd0d..c7dea4242e8bf 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -282,6 +282,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] 687+ messages in thread
* [PATCH 6.18 358/686] xfs: clamp the pNFS layout range to the maximum file size
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (356 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 357/686] xfs: cap the block count of xfs_iomap_write_direct() at one extent Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 359/686] net: restore refcount ordering for lockless socket access Greg Kroah-Hartman
` (327 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daejun Park, Darrick J. Wong,
Pankaj Raghav, Christoph Hellwig, Carlos Maiolino, Sasha Levin
6.18-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 b880d061ee90c..298fdc9e9f1c3 100644
--- a/fs/xfs/xfs_pnfs.c
+++ b/fs/xfs/xfs_pnfs.c
@@ -177,10 +177,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] 687+ messages in thread
* [PATCH 6.18 359/686] net: restore refcount ordering for lockless socket access
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (357 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 358/686] xfs: clamp the pNFS layout range to the maximum file size Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 360/686] xfs: fix recovery of partial attr removals Greg Kroah-Hartman
` (326 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Kuniyuki Iwashima,
Paolo Abeni, Sasha Levin
6.18-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 6670b43cb640d..5c3c0939e2d20 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -7691,7 +7691,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 dd14944ad3edd..543a6f2d12dfc 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -1083,8 +1083,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;
@@ -1461,7 +1461,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);
@@ -1514,7 +1514,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 49c70d752a892..c0accacdc3eb1 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -547,7 +547,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 c96d61d08854f..8997cc9db7520 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -161,7 +161,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);
inet_twsk_schedule(tw, timeo);
@@ -339,7 +339,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 8b3d4e8ee4556..d2db09bc7e29e 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 444306af444ae..dbd97df1b442f 100644
--- a/net/ipv4/tcp_fastopen.c
+++ b/net/ipv4/tcp_fastopen.c
@@ -278,7 +278,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 f4f39a20e9514..bc3a496a47dbf 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -70,7 +70,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] 687+ messages in thread
* [PATCH 6.18 360/686] xfs: fix recovery of partial attr removals
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (358 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 359/686] net: restore refcount ordering for lockless socket access Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 361/686] nvmet: reject keep-alive timeouts that would overflow Greg Kroah-Hartman
` (325 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Carlos Maiolino,
Carlos Maiolino, Sasha Levin
6.18-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 914f5dfb6463a..a6fe8a845079c 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -2948,7 +2948,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] 687+ messages in thread
* [PATCH 6.18 361/686] nvmet: reject keep-alive timeouts that would overflow
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (359 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 360/686] xfs: fix recovery of partial attr removals Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 362/686] can: isotp: check the frame type, not just the length Greg Kroah-Hartman
` (324 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Yingjie Wang,
Keith Busch, Sasha Levin
6.18-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 623b5303de2aa..f86336c79056d 100644
--- a/drivers/nvme/target/admin-cmd.c
+++ b/drivers/nvme/target/admin-cmd.c
@@ -1228,8 +1228,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 9b64c313c7039..36b3dab59e212 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -1588,6 +1588,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) {
@@ -1655,7 +1661,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 45fc188412d28..6a0d9b37443e8 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>
@@ -694,6 +695,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] 687+ messages in thread
* [PATCH 6.18 362/686] can: isotp: check the frame type, not just the length
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (360 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 361/686] nvmet: reject keep-alive timeouts that would overflow Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 363/686] can: dev: can_put_echo_skb(): free skb on invalid echo index Greg Kroah-Hartman
` (323 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kaixuan Li, Oliver Hartkopp,
Quchaosheng, Marc Kleine-Budde, Sasha Levin
6.18-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 6c88f7777965a..39cd943df19ec 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -750,6 +750,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] 687+ messages in thread
* [PATCH 6.18 363/686] can: dev: can_put_echo_skb(): free skb on invalid echo index
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (361 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 362/686] can: isotp: check the frame type, not just the length Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 364/686] can: isotp: check the return values of can_rx_register() in isotp_bind() Greg Kroah-Hartman
` (322 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Mailhol, Cunhao Lu,
Marc Kleine-Budde, Sasha Levin
6.18-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 3ebd4f779b9bd..6fb1f9b2a9e20 100644
--- a/drivers/net/can/dev/skb.c
+++ b/drivers/net/can/dev/skb.c
@@ -52,6 +52,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] 687+ messages in thread
* [PATCH 6.18 364/686] can: isotp: check the return values of can_rx_register() in isotp_bind()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (362 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 363/686] can: dev: can_put_echo_skb(): free skb on invalid echo index Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 365/686] can: proc: reset pkg_stats atomics individually Greg Kroah-Hartman
` (321 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Hartkopp, Marc Kleine-Budde,
Sasha Levin
6.18-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 39cd943df19ec..e3261fb4663af 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1527,7 +1527,6 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
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;
@@ -1604,26 +1603,36 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
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()
@@ -1634,6 +1643,9 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
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] 687+ messages in thread
* [PATCH 6.18 365/686] can: proc: reset pkg_stats atomics individually
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (363 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 364/686] can: isotp: check the return values of can_rx_register() in isotp_bind() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 366/686] can: proc: skip stats calculation after reset in can_stat_update() Greg Kroah-Hartman
` (320 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Oliver Hartkopp,
Marc Kleine-Budde, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 366/686] can: proc: skip stats calculation after reset in can_stat_update()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (364 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 365/686] can: proc: reset pkg_stats atomics individually Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 367/686] can: dev: can_fill_info(): dont wake up controller if interface is down Greg Kroah-Hartman
` (319 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Hartkopp, Marc Kleine-Budde,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 367/686] can: dev: can_fill_info(): dont wake up controller if interface is down
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (365 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 366/686] can: proc: skip stats calculation after reset in can_stat_update() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 368/686] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records Greg Kroah-Hartman
` (318 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, ChunYuZhiQiang, Vincent Mailhol,
Marc Kleine-Budde, Sasha Levin
6.18-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 fcfff221d1cc2..f4ab494b91518 100644
--- a/drivers/net/can/dev/netlink.c
+++ b/drivers/net/can/dev/netlink.c
@@ -586,7 +586,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 */
@@ -737,7 +737,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] 687+ messages in thread
* [PATCH 6.18 368/686] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (366 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 367/686] can: dev: can_fill_info(): dont wake up controller if interface is down Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 369/686] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp() Greg Kroah-Hartman
` (317 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Liu Changjie, Stéphane Grosjean,
Marc Kleine-Budde, Sasha Levin
6.18-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 f92a3b404ec18..7823b4b52c16a 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] 687+ messages in thread
* [PATCH 6.18 369/686] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (367 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 368/686] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 370/686] mm/khugepaged: fix PMD table lock leak " Greg Kroah-Hartman
` (316 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 8ed9b2a3e8f07..573e4063eaf60 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1664,12 +1664,11 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
/* 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] 687+ messages in thread
* [PATCH 6.18 370/686] mm/khugepaged: fix PMD table lock leak in try_collapse_pte_mapped_thp()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (368 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 369/686] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 371/686] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs Greg Kroah-Hartman
` (315 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 573e4063eaf60..3a866347a1cf1 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1555,7 +1555,7 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
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 */
@@ -1586,6 +1586,7 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
}
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);
@@ -1603,7 +1604,7 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
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] 687+ messages in thread
* [PATCH 6.18 371/686] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (369 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 370/686] mm/khugepaged: fix PMD table lock leak " Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 372/686] mm/gup: recheck the PUD under PTL in follow_pud_mask() Greg Kroah-Hartman
` (314 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 3a866347a1cf1..6bff1096de7d8 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1646,9 +1646,10 @@ int collapse_pte_mapped_thp(struct mm_struct *mm, unsigned long addr,
/*
* 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] 687+ messages in thread
* [PATCH 6.18 372/686] mm/gup: recheck the PUD under PTL in follow_pud_mask()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (370 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 371/686] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 373/686] mm/gup: fix clearing folios in memfd_pin_folios() Greg Kroah-Hartman
` (313 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Muhammad Usama Anjum,
David Hildenbrand (Arm), Sasha Levin
6.18-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 2264a36bc773f..50ff90775cbb8 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] 687+ messages in thread
* [PATCH 6.18 373/686] mm/gup: fix clearing folios in memfd_pin_folios()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (371 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 372/686] mm/gup: recheck the PUD under PTL in follow_pud_mask() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 374/686] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast Greg Kroah-Hartman
` (312 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 50ff90775cbb8..6ea400b5b8c5e 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3519,6 +3519,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] 687+ messages in thread
* [PATCH 6.18 374/686] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (372 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 373/686] mm/gup: fix clearing folios in memfd_pin_folios() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 375/686] mm/gup: check for overflow when converting nr_pages to bytes " Greg Kroah-Hartman
` (311 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 6ea400b5b8c5e..ac5abfc3dff7e 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3207,6 +3207,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] 687+ messages in thread
* [PATCH 6.18 375/686] mm/gup: check for overflow when converting nr_pages to bytes in GUP-fast
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (373 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 374/686] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 376/686] mm/mmu_gather: fix flushing ranges with 4 GiB or larger Greg Kroah-Hartman
` (310 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 ac5abfc3dff7e..9ce5c8ef72fad 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3217,8 +3217,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] 687+ messages in thread
* [PATCH 6.18 376/686] mm/mmu_gather: fix flushing ranges with 4 GiB or larger
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (374 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 375/686] mm/gup: check for overflow when converting nr_pages to bytes " Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 377/686] mm/mmu_notifier: finish non-blocking interval invalidation on error Greg Kroah-Hartman
` (309 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 4d679d2a206b4..16dd46d376559 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -395,8 +395,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] 687+ messages in thread
* [PATCH 6.18 377/686] mm/mmu_notifier: finish non-blocking interval invalidation on error
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (375 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 376/686] mm/mmu_gather: fix flushing ranges with 4 GiB or larger Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 378/686] mm/mmu_notifier: set ->mm only after mmgrab() Greg Kroah-Hartman
` (308 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Lorenzo Stoakes (ARM),
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
6.18-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 d1094c2d5fb61..c46f44340da79 100644
--- a/include/linux/mmu_notifier.h
+++ b/include/linux/mmu_notifier.h
@@ -444,7 +444,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 8e0125dc05227..8a3fefe18618e 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -522,16 +522,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] 687+ messages in thread
* [PATCH 6.18 378/686] mm/mmu_notifier: set ->mm only after mmgrab()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (376 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 377/686] mm/mmu_notifier: finish non-blocking interval invalidation on error Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 379/686] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs Greg Kroah-Hartman
` (307 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 8a3fefe18618e..c1b566243da9a 100644
--- a/mm/mmu_notifier.c
+++ b/mm/mmu_notifier.c
@@ -901,7 +901,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;
@@ -918,8 +917,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] 687+ messages in thread
* [PATCH 6.18 379/686] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (377 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 378/686] mm/mmu_notifier: set ->mm only after mmgrab() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 380/686] mm/mremap: recheck PUDs under the page table lock Greg Kroah-Hartman
` (306 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 8ed7c50e499b8..1830ecb91e3c1 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -496,8 +496,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] 687+ messages in thread
* [PATCH 6.18 380/686] mm/mremap: recheck PUDs under the page table lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (378 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 379/686] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 381/686] mm/mremap: fix moving PUD leaves Greg Kroah-Hartman
` (305 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 1830ecb91e3c1..369e1406854d3 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -448,14 +448,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);
@@ -490,7 +494,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] 687+ messages in thread
* [PATCH 6.18 381/686] mm/mremap: fix moving PUD leaves
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (379 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 380/686] mm/mremap: recheck PUDs under the page table lock Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 382/686] mm/madvise: fix data loss from MADV_FREE on a KSM page Greg Kroah-Hartman
` (304 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 369e1406854d3..9f7f45281b487 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;
@@ -834,11 +834,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] 687+ messages in thread
* [PATCH 6.18 382/686] mm/madvise: fix data loss from MADV_FREE on a KSM page
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (380 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 381/686] mm/mremap: fix moving PUD leaves Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 383/686] mm/memory: reject remote COW faults on PFN mappings Greg Kroah-Hartman
` (303 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 729d8f2f07fd8..bd0a5093a2df2 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] 687+ messages in thread
* [PATCH 6.18 383/686] mm/memory: reject remote COW faults on PFN mappings
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (381 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 382/686] mm/madvise: fix data loss from MADV_FREE on a KSM page Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 384/686] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit Greg Kroah-Hartman
` (302 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 01d14ca0e74d2..08dcd668c2d6b 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -3387,6 +3387,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
@@ -3712,6 +3719,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] 687+ messages in thread
* [PATCH 6.18 384/686] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (382 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 383/686] mm/memory: reject remote COW faults on PFN mappings Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 385/686] mm: fix unkillable fault loop on MAP_DROPPABLE memory Greg Kroah-Hartman
` (301 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 08dcd668c2d6b..0ef286c4a9ae2 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -4277,8 +4277,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] 687+ messages in thread
* [PATCH 6.18 385/686] mm: fix unkillable fault loop on MAP_DROPPABLE memory
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (383 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 384/686] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 386/686] mm/ksm: reset the unstable trees of all nodes Greg Kroah-Hartman
` (300 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Lorenzo Stoakes (ARM),
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
6.18-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 0ef286c4a9ae2..3049e4dc2651f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -6541,8 +6541,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] 687+ messages in thread
* [PATCH 6.18 386/686] mm/ksm: reset the unstable trees of all nodes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (384 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 385/686] mm: fix unkillable fault loop on MAP_DROPPABLE memory Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 387/686] mm/vma: call ->may_split() before a partial merge Greg Kroah-Hartman
` (299 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 1eee363fd727e..bcaca6e99b1ce 100644
--- a/mm/ksm.c
+++ b/mm/ksm.c
@@ -469,6 +469,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
@@ -3572,14 +3573,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] 687+ messages in thread
* [PATCH 6.18 387/686] mm/vma: call ->may_split() before a partial merge
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (385 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 386/686] mm/ksm: reset the unstable trees of all nodes Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 388/686] mm/memory-tiers: unregister empty tiers outside memory_tier_lock Greg Kroah-Hartman
` (298 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 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
6.18-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 dadf7d69182c2..8669da66edc5c 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -485,6 +485,15 @@ void unmap_region(struct ma_state *mas, struct vm_area_struct *vma,
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.
@@ -501,11 +510,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;
new = vm_area_dup(vma);
if (!new)
@@ -875,6 +882,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] 687+ messages in thread
* [PATCH 6.18 388/686] mm/memory-tiers: unregister empty tiers outside memory_tier_lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (386 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 387/686] mm/vma: call ->may_split() before a partial merge Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 389/686] mm/huge_memory: set the mmu_gather page size in zap_huge_pud() Greg Kroah-Hartman
` (297 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Gregory Price (Meta),
Muhammad Usama Anjum, David Hildenbrand (Arm), Sasha Levin
6.18-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 864811fff4093..fb3d63be1b897 100644
--- a/mm/memory-tiers.c
+++ b/mm/memory-tiers.c
@@ -561,21 +561,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
@@ -593,14 +586,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)
@@ -873,13 +862,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] 687+ messages in thread
* [PATCH 6.18 389/686] mm/huge_memory: set the mmu_gather page size in zap_huge_pud()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (387 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 388/686] mm/memory-tiers: unregister empty tiers outside memory_tier_lock Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 390/686] mm/gup: check folio->mapping under folio lock in memfd_pin_folios() Greg Kroah-Hartman
` (296 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pavithra, Ritesh Harjani (IBM),
Zi Yan, Muchun Song, David Hildenbrand (Arm), Sasha Levin
6.18-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 df4a3e6215d4d..78fecc3ad5700 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -2822,6 +2822,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] 687+ messages in thread
* [PATCH 6.18 390/686] mm/gup: check folio->mapping under folio lock in memfd_pin_folios()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (388 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 389/686] mm/huge_memory: set the mmu_gather page size in zap_huge_pud() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 391/686] ipv6: fix device binding after failed datagram connect Greg Kroah-Hartman
` (295 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andy Lutomirski, Samiullah Khawaja,
David Hildenbrand (Arm), Sasha Levin
6.18-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 9ce5c8ef72fad..c345bca01e3af 100644
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -3463,7 +3463,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;
@@ -3504,6 +3504,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,
@@ -3516,7 +3517,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;
@@ -3527,14 +3542,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] 687+ messages in thread
* [PATCH 6.18 391/686] ipv6: fix device binding after failed datagram connect
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (389 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 390/686] mm/gup: check folio->mapping under folio lock in memfd_pin_folios() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 392/686] ovl: do not let chattr change the casefold flag Greg Kroah-Hartman
` (294 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xia Yan, Paolo Abeni, Sasha Levin
6.18-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 97c655c260568..7edf30d8098de 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -148,6 +148,7 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr,
__be32 fl6_flowlabel = 0;
__be32 old_fl6_flowlabel;
__be16 old_dport;
+ int old_bound_dev_if;
int addr_type;
int err;
@@ -218,6 +219,8 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *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) {
@@ -260,6 +263,7 @@ int __ip6_datagram_connect(struct sock *sk, struct sockaddr *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] 687+ messages in thread
* [PATCH 6.18 392/686] ovl: do not let chattr change the casefold flag
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (390 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 391/686] ipv6: fix device binding after failed datagram connect Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 393/686] net/sched: clamp skb->queue_mapping before indexing the tx queue Greg Kroah-Hartman
` (293 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Hungyu Lin,
Amir Goldstein, Sasha Levin
6.18-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 78803e40c9619..79ad351298feb 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -657,6 +657,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] 687+ messages in thread
* [PATCH 6.18 393/686] net/sched: clamp skb->queue_mapping before indexing the tx queue
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (391 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 392/686] ovl: do not let chattr change the casefold flag Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 394/686] vhost/vsock: size receive SKBs from declared payload Greg Kroah-Hartman
` (292 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko (nipa), Jamal Hadi Salim,
Simon Horman, Paolo Abeni, Sasha Levin
6.18-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 26085d31be47c..e2dc86758888a 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -71,9 +71,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;
@@ -85,7 +110,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)) {
@@ -199,6 +225,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;
@@ -216,7 +244,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;
@@ -224,7 +251,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;
}
@@ -269,7 +298,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)) {
@@ -305,6 +334,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 99a711d0479c2..f9eeb6296f1dc 100644
--- a/net/sched/sch_taprio.c
+++ b/net/sched/sch_taprio.c
@@ -631,6 +631,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] 687+ messages in thread
* [PATCH 6.18 394/686] vhost/vsock: size receive SKBs from declared payload
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (392 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 393/686] net/sched: clamp skb->queue_mapping before indexing the tx queue Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 395/686] mptcp: do not use Fast Open on MP_JOIN subflows Greg Kroah-Hartman
` (291 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Stefano Garzarella,
Michael S. Tsirkin, Paolo Abeni, Sasha Levin
6.18-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 65297f245b272..f00182e9efec0 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -331,7 +331,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;
@@ -349,34 +349,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] 687+ messages in thread
* [PATCH 6.18 395/686] mptcp: do not use Fast Open on MP_JOIN subflows
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (393 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 394/686] vhost/vsock: size receive SKBs from declared payload Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 396/686] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check Greg Kroah-Hartman
` (290 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kimi Security Team, Jiayuan Chen,
Paolo Abeni, Yilin Zhang, Matthieu Baerts (NGI0), Sasha Levin
6.18-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 e020960f093e0..c2d6a7adca6b2 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -380,6 +380,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;
@@ -889,6 +893,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] 687+ messages in thread
* [PATCH 6.18 396/686] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (394 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 395/686] mptcp: do not use Fast Open on MP_JOIN subflows Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 397/686] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup() Greg Kroah-Hartman
` (289 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yitang Yang, Ming Lei, Jens Axboe,
Sasha Levin
6.18-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 8c33a5f86c3d6..6b2035c46daa3 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -3872,6 +3872,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] 687+ messages in thread
* [PATCH 6.18 397/686] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (395 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 396/686] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 398/686] drm/amdgpu: Check cs flags Greg Kroah-Hartman
` (288 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Jarkko Sakkinen,
Keith Busch, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 398/686] drm/amdgpu: Check cs flags.
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (396 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 397/686] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup() Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 399/686] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at Greg Kroah-Hartman
` (287 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bas Nieuwenhuizen, Faith Ekstrand,
Alex Deucher, Sasha Levin
6.18-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 efcd2322afa61..6e15b759ef135 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -205,6 +205,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] 687+ messages in thread
* [PATCH 6.18 399/686] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (397 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 398/686] drm/amdgpu: Check cs flags Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 400/686] drm/amdgpu: keep the CS user fence BO in GTT Greg Kroah-Hartman
` (286 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alex Deucher, Jesse Zhang,
Sasha Levin
6.18-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 6e15b759ef135..87305df456239 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1091,7 +1091,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] 687+ messages in thread
* [PATCH 6.18 400/686] drm/amdgpu: keep the CS user fence BO in GTT
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (398 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 399/686] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 401/686] drm/amdkfd: use the queues process info for the WPTR BO eviction fence Greg Kroah-Hartman
` (285 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher, Sasha Levin
6.18-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 87305df456239..946c6bfe1f7f4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -161,7 +161,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] 687+ messages in thread
* [PATCH 6.18 401/686] drm/amdkfd: use the queues process info for the WPTR BO eviction fence
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (399 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 400/686] drm/amdgpu: keep the CS user fence BO in GTT Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 402/686] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify Greg Kroah-Hartman
` (284 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Kuehling, Jesse Zhang,
Alex Deucher, Sasha Levin
6.18-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 21dbc8675f4e7..7aa5b22ed87af 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd.h
@@ -330,7 +330,8 @@ int amdgpu_amdkfd_gpuvm_map_gtt_bo_to_kernel(struct kgd_mem *mem,
void **kptr, uint64_t *size);
void amdgpu_amdkfd_gpuvm_unmap_gtt_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 6de7dfa30ce50..359ce3f696375 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -2244,11 +2244,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_gtt_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;
@@ -2270,8 +2272,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 99a47f2a45e7a..6f3cfb9245c4a 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c
@@ -286,7 +286,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] 687+ messages in thread
* [PATCH 6.18 402/686] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (400 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 401/686] drm/amdkfd: use the queues process info for the WPTR BO eviction fence Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 403/686] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers Greg Kroah-Hartman
` (283 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Deucher, Dariusz Marcinkiewicz,
Sasha Levin
6.18-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 efa6214eee315..640f627342916 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dma_buf.c
@@ -533,6 +533,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] 687+ messages in thread
* [PATCH 6.18 403/686] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (401 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 402/686] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 404/686] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih Greg Kroah-Hartman
` (282 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Prike Liang, Lijo Lazar,
Alex Deucher, Sasha Levin
6.18-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 2e0998de67ed1..b152beddbc3f9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -6667,8 +6667,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.
@@ -6678,18 +6680,17 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
if (job && dma_fence_is_signaled(&job->hw_fence.base)) {
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);
end_reset:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 404/686] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (402 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 403/686] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 405/686] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL Greg Kroah-Hartman
` (281 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Danijel Slivka, Alex Deucher,
Milan Milicevic, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 405/686] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (403 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 404/686] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 406/686] drm/amd/display: Avoid closing unowned DDC pins Greg Kroah-Hartman
` (280 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Danijel Slivka, Milan Milicevic,
Alex Deucher, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 406/686] drm/amd/display: Avoid closing unowned DDC pins
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (404 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 405/686] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL Greg Kroah-Hartman
@ 2026-11-13 15:48 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 407/686] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID Greg Kroah-Hartman
` (279 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:48 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jerry Zuo, Mario Limonciello,
Alex Deucher, Alex Hung, Dan Wheeler, Leo Li, Sasha Levin
6.18-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 eb262ce42e2dc..9154fea65f583 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
@@ -2483,12 +2483,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] 687+ messages in thread
* [PATCH 6.18 407/686] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (405 preceding siblings ...)
2026-11-13 15:48 ` [PATCH 6.18 406/686] drm/amd/display: Avoid closing unowned DDC pins Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 408/686] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto Greg Kroah-Hartman
` (278 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alex Deucher, Jesse Zhang,
Sasha Levin
6.18-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 06fde713b9229..69c9af88704cd 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c
@@ -3976,6 +3976,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);
@@ -3989,6 +3990,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] 687+ messages in thread
* [PATCH 6.18 408/686] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (406 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 407/686] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 409/686] drm/amd/display: Drop clock requirements on DCN32 when no displays are active Greg Kroah-Hartman
` (277 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Roman Demidov, Alex Hung,
Alex Deucher, Sasha Levin
6.18-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 306016c1f109c..8f53a1f228f59 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
@@ -535,6 +535,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] 687+ messages in thread
* [PATCH 6.18 409/686] drm/amd/display: Drop clock requirements on DCN32 when no displays are active
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (407 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 408/686] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 410/686] drm/amd/display: Keep the nominal vtotal while VRR is inactive Greg Kroah-Hartman
` (276 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Misha Nasledov, Alex Hung,
Alex Deucher, Sasha Levin
6.18-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 e655772986851..61cb8d051917a 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
@@ -1777,8 +1777,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] 687+ messages in thread
* [PATCH 6.18 410/686] drm/amd/display: Keep the nominal vtotal while VRR is inactive
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (408 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 409/686] drm/amd/display: Drop clock requirements on DCN32 when no displays are active Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 411/686] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot Greg Kroah-Hartman
` (275 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Schwartz, Ivan Lipski,
Alex Deucher, Sasha Levin
6.18-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 1aae46d703ba0..4a957f87c07c5 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -1265,10 +1265,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] 687+ messages in thread
* [PATCH 6.18 411/686] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (409 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 410/686] drm/amd/display: Keep the nominal vtotal while VRR is inactive Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 412/686] drm/amdgpu: Fix duplicate dependency fence releases Greg Kroah-Hartman
` (274 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kylie C, Alex Hung, Alex Deucher,
Sasha Levin
6.18-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 e7a90a437fffb..06edf66136597 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
@@ -452,6 +452,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] 687+ messages in thread
* [PATCH 6.18 412/686] drm/amdgpu: Fix duplicate dependency fence releases
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (410 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 411/686] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 413/686] drm/amdgpu: Report MES ring wait timeouts Greg Kroah-Hartman
` (273 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Deucher, Erhan Bilgili,
Sasha Levin
6.18-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 902d0a538e419..dd72891624ebb 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] 687+ messages in thread
* [PATCH 6.18 413/686] drm/amdgpu: Report MES ring wait timeouts.
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (411 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 412/686] drm/amdgpu: Fix duplicate dependency fence releases Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 414/686] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points Greg Kroah-Hartman
` (272 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Deucher, Erhan Bilgili,
Sasha Levin
6.18-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 d5cc32fa78485..f73b41b4be7e3 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c
@@ -207,8 +207,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 7d7bcf1c69f27..5e438d5896df1 100644
--- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c
@@ -192,8 +192,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] 687+ messages in thread
* [PATCH 6.18 414/686] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (412 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 413/686] drm/amdgpu: Report MES ring wait timeouts Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 415/686] drm/amdgpu: drop the dma-buf reference when a KFD import fails Greg Kroah-Hartman
` (271 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hugo Sales, Mario Limonciello,
Alex Deucher, Sasha Levin
6.18-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 5a04c20a5fd15..4dc44acc1b772 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acpi.c
@@ -400,7 +400,11 @@ static 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] 687+ messages in thread
* [PATCH 6.18 415/686] drm/amdgpu: drop the dma-buf reference when a KFD import fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (413 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 414/686] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 416/686] drm/amdgpu: Only enable HDMI audio if display supports it Greg Kroah-Hartman
` (270 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Felix Kuehling, Jesse Zhang,
Alex Deucher, Sasha Levin
6.18-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 359ce3f696375..c57d9e4837d68 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
@@ -2450,6 +2450,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] 687+ messages in thread
* [PATCH 6.18 416/686] drm/amdgpu: Only enable HDMI audio if display supports it
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (414 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 415/686] drm/amdgpu: drop the dma-buf reference when a KFD import fails Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 417/686] drm/amdgpu: dont drop the gang dependency fence twice Greg Kroah-Hartman
` (269 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Alex Deucher, renpanpan, Sasha Levin
6.18-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 72ca6538b2e49..08535245e5fd8 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -1735,8 +1735,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 acc887a58518d..24462e6f221b0 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c
@@ -1777,8 +1777,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 2ccd6aad8dd65..03d6b6f54c0f1 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -1682,8 +1682,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] 687+ messages in thread
* [PATCH 6.18 417/686] drm/amdgpu: dont drop the gang dependency fence twice
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (415 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 416/686] drm/amdgpu: Only enable HDMI audio if display supports it Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 418/686] nvmet: dont return memory contents beyond valid data when reading ANA log page Greg Kroah-Hartman
` (268 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Jesse Zhang,
Alex Deucher, Sasha Levin
6.18-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 946c6bfe1f7f4..0f6505d4c958b 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1333,10 +1333,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] 687+ messages in thread
* [PATCH 6.18 418/686] nvmet: dont return memory contents beyond valid data when reading ANA log page
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (416 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 417/686] drm/amdgpu: dont drop the gang dependency fence twice Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 419/686] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend Greg Kroah-Hartman
` (267 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ewan D. Milne, Keith Busch,
Sasha Levin
6.18-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 f86336c79056d..007029eaca39b 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(struct_size(desc, nsids, NVMET_MAX_NAMESPACES),
GFP_KERNEL);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 419/686] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (417 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 418/686] nvmet: dont return memory contents beyond valid data when reading ANA log page Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 420/686] arm64: mm: validate /dev/mem mmap ranges without overflow Greg Kroah-Hartman
` (266 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Will Deacon, Mark Brown, Wei Wang,
Catalin Marinas, Sasha Levin
6.18-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 eb60c97355530..2cc5fb405769c 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 17df19647556f..5e7bc1a8d9ca7 100644
--- a/arch/arm64/mm/proc.S
+++ b/arch/arm64/mm/proc.S
@@ -103,6 +103,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)
@@ -142,6 +146,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] 687+ messages in thread
* [PATCH 6.18 420/686] arm64: mm: validate /dev/mem mmap ranges without overflow
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (418 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 419/686] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 421/686] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d Greg Kroah-Hartman
` (265 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhao Gongyi, Catalin Marinas,
Sasha Levin
6.18-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 92b2f5097a96c..dabc61000ecc4 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] 687+ messages in thread
* [PATCH 6.18 421/686] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (419 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 420/686] arm64: mm: validate /dev/mem mmap ranges without overflow Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 422/686] ovl: look up the index by the decoded origin Greg Kroah-Hartman
` (264 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin, Keith Busch
6.18-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 6e4261b0a0821..9245fae713210 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -3939,6 +3939,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] 687+ messages in thread
* [PATCH 6.18 422/686] ovl: look up the index by the decoded origin
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (420 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 421/686] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 423/686] l2tp: only return sessions of the given tunnel in l2tp_session_get() Greg Kroah-Hartman
` (263 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Amir Goldstein,
Sasha Levin
6.18-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 c493fcbe0df4a..2d6202807fd1d 100644
--- a/Documentation/filesystems/overlayfs.rst
+++ b/Documentation/filesystems/overlayfs.rst
@@ -716,7 +716,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 83f80fdb15674..d961533c9c9b7 100644
--- a/fs/overlayfs/export.c
+++ b/fs/overlayfs/export.c
@@ -718,9 +718,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 c20be56c9b9d6..3d03e0312561a 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -775,14 +775,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 22555205c84ce..6268db46483e7 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -736,7 +736,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] 687+ messages in thread
* [PATCH 6.18 423/686] l2tp: only return sessions of the given tunnel in l2tp_session_get()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (421 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 422/686] ovl: look up the index by the decoded origin Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 424/686] drm/nouveau/nvkm: clear use.enabled when subdev init fails Greg Kroah-Hartman
` (262 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hengyu Liang, Guillaume Nault,
Paolo Abeni, Sasha Levin
6.18-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 fd78928e9be26..e78e8ea93bb7b 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] 687+ messages in thread
* [PATCH 6.18 424/686] drm/nouveau/nvkm: clear use.enabled when subdev init fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (422 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 423/686] l2tp: only return sessions of the given tunnel in l2tp_session_get() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 425/686] drm/dp: keep MOT set between messages when no_zero_sized is set Greg Kroah-Hartman
` (261 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rosen Penev, Dave Airlie,
Sasha Levin
6.18-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 b7045d1c84158..8c9e3427bfc06 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] 687+ messages in thread
* [PATCH 6.18 425/686] drm/dp: keep MOT set between messages when no_zero_sized is set
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (423 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 424/686] drm/nouveau/nvkm: clear use.enabled when subdev init fails Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 426/686] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts Greg Kroah-Hartman
` (260 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Finn Zeruhn, Dave Airlie,
Sasha Levin
6.18-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 4fc371f0fa123..8ef5adecace12 100644
--- a/drivers/gpu/drm/display/drm_dp_helper.c
+++ b/drivers/gpu/drm/display/drm_dp_helper.c
@@ -2183,7 +2183,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] 687+ messages in thread
* [PATCH 6.18 426/686] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (424 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 425/686] drm/dp: keep MOT set between messages when no_zero_sized is set Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 427/686] ALSA: ump: Fix dropped data bytes at UMP System message conversion Greg Kroah-Hartman
` (259 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ilia Mirkin, Dave Airlie,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 427/686] ALSA: ump: Fix dropped data bytes at UMP System message conversion
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (425 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 426/686] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 428/686] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3 Greg Kroah-Hartman
` (258 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, HyeongJun An, Takashi Iwai,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 428/686] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (426 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 427/686] ALSA: ump: Fix dropped data bytes at UMP System message conversion Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 429/686] ALSA: cs46xx: Handle SCB creation failures before dereferencing Greg Kroah-Hartman
` (257 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Simpson, Takashi Iwai,
Sasha Levin
6.18-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 404a93f552cb4..99d3fda16f3a2 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -6710,6 +6710,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] 687+ messages in thread
* [PATCH 6.18 429/686] ALSA: cs46xx: Handle SCB creation failures before dereferencing
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (427 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 428/686] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3 Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 430/686] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close Greg Kroah-Hartman
` (256 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Kazinsky, Takashi Iwai,
Sasha Levin
6.18-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 ba290f3a50e43..144c87097ae82 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -1106,6 +1106,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 32ed415bf427c..b7c41f2bc312e 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] 687+ messages in thread
* [PATCH 6.18 430/686] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (428 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 429/686] ALSA: cs46xx: Handle SCB creation failures before dereferencing Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 431/686] ALSA: usx2y: Refuse a retried DSP load after a failure Greg Kroah-Hartman
` (255 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, YuanZhe Liu, Takashi Iwai,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 431/686] ALSA: usx2y: Refuse a retried DSP load after a failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (429 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 430/686] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 432/686] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid Greg Kroah-Hartman
` (254 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bin Yu, Cheng Wen, YuanZhe Liu,
Takashi Iwai, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 432/686] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (430 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 431/686] ALSA: usx2y: Refuse a retried DSP load after a failure Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 433/686] ALSA: line6: Reject capture buffers smaller than two packets Greg Kroah-Hartman
` (253 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cristian Castellano,
Mohamed Yassine Jebabli, Takashi Iwai, Sasha Levin
6.18-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 00628e0b5c3e4..dc4e42fd88484 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] 687+ messages in thread
* [PATCH 6.18 433/686] ALSA: line6: Reject capture buffers smaller than two packets
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (431 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 432/686] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 434/686] ALSA: caiaq: free the EP4 URB when input setup fails Greg Kroah-Hartman
` (252 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sinan Turunc, Takashi Iwai,
Sasha Levin
6.18-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 46acd2f44c440..f59ec9c4a1a52 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] 687+ messages in thread
* [PATCH 6.18 434/686] ALSA: caiaq: free the EP4 URB when input setup fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (432 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 433/686] ALSA: line6: Reject capture buffers smaller than two packets Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 435/686] ALSA: usx2y: Require a buffer of two URBs Greg Kroah-Hartman
` (251 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Liang, Takashi Iwai,
Sasha Levin
6.18-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 c12eeb9710002..6a5adb8d1e6a7 100644
--- a/sound/usb/caiaq/input.c
+++ b/sound/usb/caiaq/input.c
@@ -830,6 +830,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] 687+ messages in thread
* [PATCH 6.18 435/686] ALSA: usx2y: Require a buffer of two URBs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (433 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 434/686] ALSA: caiaq: free the EP4 URB when input setup fails Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 436/686] ALSA: usx2y: Guard the playback copy Greg Kroah-Hartman
` (250 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sinan Turunc, Takashi Iwai,
Sasha Levin
6.18-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 1ea181e9bb283..12b1c890812ba 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) {
@@ -890,6 +902,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] 687+ messages in thread
* [PATCH 6.18 436/686] ALSA: usx2y: Guard the playback copy
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (434 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 435/686] ALSA: usx2y: Require a buffer of two URBs Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 437/686] ext2: preserve IOMAP_F_DIRTY for extending direct writes Greg Kroah-Hartman
` (249 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sinan Turunc, Takashi Iwai,
Sasha Levin
6.18-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 12b1c890812ba..f035add1e1b5a 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] 687+ messages in thread
* [PATCH 6.18 437/686] ext2: preserve IOMAP_F_DIRTY for extending direct writes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (435 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 436/686] ALSA: usx2y: Guard the playback copy Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 438/686] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data Greg Kroah-Hartman
` (248 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hungyu Lin, Jan Kara, Sasha Levin
6.18-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 50d431949fd4b..12f9b1b36e056 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -824,6 +824,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
@@ -831,13 +837,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;
if (flags & IOMAP_DAX)
iomap->dax_dev = sbi->s_daxdev;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 438/686] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (436 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 437/686] ext2: preserve IOMAP_F_DIRTY for extending direct writes Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 439/686] net: count last skb of each sk_backlog pass in __release_sock() Greg Kroah-Hartman
` (247 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bryam Vargas, Dust Li, Paolo Abeni,
Sasha Levin
6.18-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 24524dfd55180..4e2b156a52459 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] 687+ messages in thread
* [PATCH 6.18 439/686] net: count last skb of each sk_backlog pass in __release_sock()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (437 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 438/686] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 440/686] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets Greg Kroah-Hartman
` (246 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ray Zhang, Kuniyuki Iwashima,
Eric Dumazet, Paolo Abeni, Sasha Levin
6.18-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 03136176c7d0f..486989dfaaeee 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -3185,7 +3185,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));
@@ -3193,12 +3193,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] 687+ messages in thread
* [PATCH 6.18 440/686] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (438 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 439/686] net: count last skb of each sk_backlog pass in __release_sock() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 441/686] drm/etnaviv: Flush the tile status cache through both the PE and BLT Greg Kroah-Hartman
` (245 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Clark,
Sebastian Andrzej Siewior, Paolo Abeni, Sasha Levin
6.18-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 5bcf1126d627e..89fdc30d80a43 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))
@@ -1859,7 +1860,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] 687+ messages in thread
* [PATCH 6.18 441/686] drm/etnaviv: Flush the tile status cache through both the PE and BLT
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (439 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 440/686] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 442/686] mptcp: pm: kernel: use RCU to free endpoint listeners Greg Kroah-Hartman
` (244 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lucas Stach, Christian Gmeiner,
Sasha Levin
6.18-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 88385dc3b30d8..4f22e373ed346 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_buffer.c
@@ -230,6 +230,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;
@@ -253,7 +264,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);
@@ -266,16 +277,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) {
@@ -462,12 +465,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);
@@ -484,14 +487,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] 687+ messages in thread
* [PATCH 6.18 442/686] mptcp: pm: kernel: use RCU to free endpoint listeners
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (440 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 441/686] drm/etnaviv: Flush the tile status cache through both the PE and BLT Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 443/686] udf: dont let the extent type hide an exhausted free-space table extent Greg Kroah-Hartman
` (243 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Matthieu Baerts (NGI0),
Paolo Abeni, Sasha Levin
6.18-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 fa34a333a3110..cf635b84fff4a 100644
--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -881,6 +881,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] 687+ messages in thread
* [PATCH 6.18 443/686] udf: dont let the extent type hide an exhausted free-space table extent
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (441 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 442/686] mptcp: pm: kernel: use RCU to free endpoint listeners Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 444/686] udf: check the unallocated space table when it is loaded Greg Kroah-Hartman
` (242 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+799a0e744ac47f928024,
syzbot+43fc5ba6dcb33e3261ca, Matthias Goergens, Jan Kara,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 444/686] udf: check the unallocated space table when it is loaded
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (442 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 443/686] udf: dont let the extent type hide an exhausted free-space table extent Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 445/686] udf: fix preallocation discarding before an empty allocation extent Greg Kroah-Hartman
` (241 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthias Goergens, Jan Kara,
Sasha Levin
6.18-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 556540f2797ae..8d3d758714da2 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1105,6 +1105,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)
{
@@ -1165,6 +1232,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) @ %lu\n",
@@ -2228,8 +2305,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] 687+ messages in thread
* [PATCH 6.18 445/686] udf: fix preallocation discarding before an empty allocation extent
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (443 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 444/686] udf: check the unallocated space table when it is loaded Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 446/686] udf: dont use eloc after the end of the unallocated space table Greg Kroah-Hartman
` (240 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jan Kara, Matthias Goergens,
Sasha Levin
6.18-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 da5a61306390c..85bbd6fa2a302 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] 687+ messages in thread
* [PATCH 6.18 446/686] udf: dont use eloc after the end of the unallocated space table
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (444 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 445/686] udf: fix preallocation discarding before an empty allocation extent Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 447/686] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels Greg Kroah-Hartman
` (239 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthias Goergens, Jan Kara,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 447/686] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (445 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 446/686] udf: dont use eloc after the end of the unallocated space table Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 448/686] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Greg Kroah-Hartman
` (238 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz, Thomas Bogendoerfer,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 448/686] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (446 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 447/686] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 449/686] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Greg Kroah-Hartman
` (237 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz, Thomas Bogendoerfer,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 449/686] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (447 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 448/686] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 450/686] srcu: Add list_splice_init_srcu() Greg Kroah-Hartman
` (236 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Imre Kaloz, Thomas Bogendoerfer,
Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 450/686] srcu: Add list_splice_init_srcu()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (448 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 449/686] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 451/686] nvme: wait for SRCU readers before splicing the namespace list Greg Kroah-Hartman
` (235 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Qiliang Yuan,
Paul E. McKenney, Keith Busch, Sasha Levin
6.18-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 ada65b58bc4c5..d4fa064600f64 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>
@@ -68,6 +69,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] 687+ messages in thread
* [PATCH 6.18 451/686] nvme: wait for SRCU readers before splicing the namespace list
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (449 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 450/686] srcu: Add list_splice_init_srcu() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 452/686] nvmet: bound the traddr and trsvcid configfs writes Greg Kroah-Hartman
` (234 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qiliang Yuan, Christoph Hellwig,
Keith Busch, Sasha Levin
6.18-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 99a8e2953b02a..1ecf26f24b7fa 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -4628,9 +4628,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] 687+ messages in thread
* [PATCH 6.18 452/686] nvmet: bound the traddr and trsvcid configfs writes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (450 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 451/686] nvme: wait for SRCU readers before splicing the namespace list Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 453/686] perf/core: Dont send SIGTRAP after exec removed the event Greg Kroah-Hartman
` (233 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shao Mingyin, Christoph Hellwig,
Keith Busch, Sasha Levin
6.18-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 e2032b58191c5..61b4e90f4e34d 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] 687+ messages in thread
* [PATCH 6.18 453/686] perf/core: Dont send SIGTRAP after exec removed the event
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (451 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 452/686] nvmet: bound the traddr and trsvcid configfs writes Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 454/686] x86/nmi: Ignore negative NMI handler durations Greg Kroah-Hartman
` (232 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Danish Khateeb,
Peter Zijlstra (Intel), Ingo Molnar, Sasha Levin
6.18-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 469f89cb92f11..ec2d21af68f63 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -7324,6 +7324,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] 687+ messages in thread
* [PATCH 6.18 454/686] x86/nmi: Ignore negative NMI handler durations
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (452 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 453/686] perf/core: Dont send SIGTRAP after exec removed the event Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 455/686] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions Greg Kroah-Hartman
` (231 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Peter Zijlstra (Intel),
Ingo Molnar, Sasha Levin
6.18-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 be93ec7255bfc..eece49c490e07 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -114,6 +114,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] 687+ messages in thread
* [PATCH 6.18 455/686] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (453 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 454/686] x86/nmi: Ignore negative NMI handler durations Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 456/686] arm64: kexec_file: Fix elf_headers memory leak in retry loop Greg Kroah-Hartman
` (230 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Akshay Jindal, Vasant Hegde,
Joerg Roedel, Sasha Levin
6.18-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 16c26d75f46f4..c20034b8693fc 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -2721,6 +2721,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)
{
@@ -2732,10 +2741,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] 687+ messages in thread
* [PATCH 6.18 456/686] arm64: kexec_file: Fix elf_headers memory leak in retry loop
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (454 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 455/686] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 457/686] x86/boot: Fix off-by-one error in sme_clear_pgd() Greg Kroah-Hartman
` (229 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 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
6.18-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 410060ebd86df..2034ca8287a22 100644
--- a/arch/arm64/kernel/machine_kexec_file.c
+++ b/arch/arm64/kernel/machine_kexec_file.c
@@ -128,6 +128,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] 687+ messages in thread
* [PATCH 6.18 457/686] x86/boot: Fix off-by-one error in sme_clear_pgd()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (455 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 456/686] arm64: kexec_file: Fix elf_headers memory leak in retry loop Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 458/686] arm64: sdei: Run the event handler on the kernel vectors Greg Kroah-Hartman
` (228 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Borislav Petkov (AMD),
Tom Lendacky, stable, Sasha Levin
6.18-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 e7ea65f3f1d6a..1528199e3a3ff 100644
--- a/arch/x86/boot/startup/sme.c
+++ b/arch/x86/boot/startup/sme.c
@@ -97,7 +97,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] 687+ messages in thread
* [PATCH 6.18 458/686] arm64: sdei: Run the event handler on the kernel vectors
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (456 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 457/686] x86/boot: Fix off-by-one error in sme_clear_pgd() Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 459/686] arm64: sdei: Preserve the interrupted contexts exception registers Greg Kroah-Hartman
` (227 subsequent siblings)
685 siblings, 0 replies; 687+ 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),
Catalin Marinas, Breno Leitao, Sasha Levin
6.18-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 484cb6972e99a..3b689185f3715 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 5b97dfcf796d9..67ecb9fdb355e 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.
@@ -993,6 +994,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;
@@ -1018,10 +1020,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 95169f7b65319..f77e30314fe13 100644
--- a/arch/arm64/kernel/sdei.c
+++ b/arch/arm64/kernel/sdei.c
@@ -204,16 +204,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 firmare.
* 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] 687+ messages in thread
* [PATCH 6.18 459/686] arm64: sdei: Preserve the interrupted contexts exception registers
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (457 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 458/686] arm64: sdei: Run the event handler on the kernel vectors Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 460/686] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705 Greg Kroah-Hartman
` (226 subsequent siblings)
685 siblings, 0 replies; 687+ 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), Breno Leitao,
Catalin Marinas, Sasha Levin
6.18-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 67ecb9fdb355e..4334bade249be 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -994,7 +994,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;
@@ -1020,6 +1020,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
@@ -1039,6 +1050,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 f77e30314fe13..839b0723f5dbc 100644
--- a/arch/arm64/kernel/sdei.c
+++ b/arch/arm64/kernel/sdei.c
@@ -199,6 +199,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.
@@ -215,6 +240,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())
@@ -227,18 +253,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] 687+ messages in thread
* [PATCH 6.18 460/686] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (458 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 459/686] arm64: sdei: Preserve the interrupted contexts exception registers Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 461/686] x86/mm: Fix global ASID handed out to two processes Greg Kroah-Hartman
` (225 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyrylo Biryuk, Marco Ziliani,
Niklas Cassel, Sasha Levin
6.18-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 299b1823e0d09..99c67dbfb7536 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] 687+ messages in thread
* [PATCH 6.18 461/686] x86/mm: Fix global ASID handed out to two processes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (459 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 460/686] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705 Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 462/686] iommu/amd: Force device table to maximum size Greg Kroah-Hartman
` (224 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 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
6.18-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 5d221709353e0..41a81d58cf962 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -319,13 +319,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] 687+ messages in thread
* [PATCH 6.18 462/686] iommu/amd: Force device table to maximum size
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (460 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 461/686] x86/mm: Fix global ASID handed out to two processes Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 463/686] Revert "hugetlb: remove VMEMMAP_SYNCHRONIZE_RCU" Greg Kroah-Hartman
` (223 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Suravee Suthikulpanit, Joerg Roedel,
Linus Torvalds
6.18-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
@@ -1736,6 +1736,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)
@@ -1758,9 +1773,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] 687+ messages in thread
* [PATCH 6.18 463/686] Revert "hugetlb: remove VMEMMAP_SYNCHRONIZE_RCU"
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (461 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 462/686] iommu/amd: Force device table to maximum size Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 464/686] can: replace ARPHRD_CAN type checks with can_get_ml_priv() Greg Kroah-Hartman
` (222 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
This reverts commit dba93b8cceb0048071389352fc29dcb0a7fe666f.
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb_vmemmap.c | 20 ++++++++++++++++----
1 file changed, 16 insertions(+), 4 deletions(-)
diff --git a/mm/hugetlb_vmemmap.c b/mm/hugetlb_vmemmap.c
index 795e7dbbca7d0..efe4bcc85da2c 100644
--- a/mm/hugetlb_vmemmap.c
+++ b/mm/hugetlb_vmemmap.c
@@ -45,6 +45,8 @@ struct vmemmap_remap_walk {
#define VMEMMAP_SPLIT_NO_TLB_FLUSH BIT(0)
/* Skip the TLB flush when we remap the PTE */
#define VMEMMAP_REMAP_NO_TLB_FLUSH BIT(1)
+/* synchronize_rcu() to avoid writes from page_ref_add_unless() */
+#define VMEMMAP_SYNCHRONIZE_RCU BIT(2)
unsigned long flags;
};
@@ -405,6 +407,9 @@ static int __hugetlb_vmemmap_restore_folio(const struct hstate *h,
if (!folio_test_hugetlb_vmemmap_optimized(folio))
return 0;
+ if (flags & VMEMMAP_SYNCHRONIZE_RCU)
+ synchronize_rcu();
+
vmemmap_start = (unsigned long)&folio->page;
vmemmap_end = vmemmap_start + hugetlb_vmemmap_size(h);
@@ -437,7 +442,7 @@ static int __hugetlb_vmemmap_restore_folio(const struct hstate *h,
*/
int hugetlb_vmemmap_restore_folio(const struct hstate *h, struct folio *folio)
{
- return __hugetlb_vmemmap_restore_folio(h, folio, 0);
+ return __hugetlb_vmemmap_restore_folio(h, folio, VMEMMAP_SYNCHRONIZE_RCU);
}
/**
@@ -460,11 +465,14 @@ long hugetlb_vmemmap_restore_folios(const struct hstate *h,
struct folio *folio, *t_folio;
long restored = 0;
long ret = 0;
- unsigned long flags = VMEMMAP_REMAP_NO_TLB_FLUSH;
+ unsigned long flags = VMEMMAP_REMAP_NO_TLB_FLUSH | VMEMMAP_SYNCHRONIZE_RCU;
list_for_each_entry_safe(folio, t_folio, folio_list, lru) {
if (folio_test_hugetlb_vmemmap_optimized(folio)) {
ret = __hugetlb_vmemmap_restore_folio(h, folio, flags);
+ /* only need to synchronize_rcu() once for each batch */
+ flags &= ~VMEMMAP_SYNCHRONIZE_RCU;
+
if (ret)
break;
restored++;
@@ -513,6 +521,8 @@ static int __hugetlb_vmemmap_optimize_folio(const struct hstate *h,
static_branch_inc(&hugetlb_optimize_vmemmap_key);
+ if (flags & VMEMMAP_SYNCHRONIZE_RCU)
+ synchronize_rcu();
/*
* Very Subtle
* If VMEMMAP_REMAP_NO_TLB_FLUSH is set, TLB flushing is not performed
@@ -572,7 +582,7 @@ void hugetlb_vmemmap_optimize_folio(const struct hstate *h, struct folio *folio)
{
LIST_HEAD(vmemmap_pages);
- __hugetlb_vmemmap_optimize_folio(h, folio, &vmemmap_pages, 0);
+ __hugetlb_vmemmap_optimize_folio(h, folio, &vmemmap_pages, VMEMMAP_SYNCHRONIZE_RCU);
free_vmemmap_page_list(&vmemmap_pages);
}
@@ -600,7 +610,7 @@ static void __hugetlb_vmemmap_optimize_folios(struct hstate *h,
struct folio *folio;
int nr_to_optimize;
LIST_HEAD(vmemmap_pages);
- unsigned long flags = VMEMMAP_REMAP_NO_TLB_FLUSH;
+ unsigned long flags = VMEMMAP_REMAP_NO_TLB_FLUSH | VMEMMAP_SYNCHRONIZE_RCU;
nr_to_optimize = 0;
list_for_each_entry(folio, folio_list, lru) {
@@ -654,6 +664,8 @@ static void __hugetlb_vmemmap_optimize_folios(struct hstate *h,
int ret;
ret = __hugetlb_vmemmap_optimize_folio(h, folio, &vmemmap_pages, flags);
+ /* only need to synchronize_rcu() once for each batch */
+ flags &= ~VMEMMAP_SYNCHRONIZE_RCU;
/*
* Pages to be freed may have been accumulated. If we
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 464/686] can: replace ARPHRD_CAN type checks with can_get_ml_priv()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (462 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 463/686] Revert "hugetlb: remove VMEMMAP_SYNCHRONIZE_RCU" Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 465/686] can: protect the receive lists with a per-device lock Greg Kroah-Hartman
` (221 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
commit 962947b69589881167054bae5accc8abfd5aa4b6 upstream.
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>
[ backport to 6.18: This tree has no can_skb_ext, so only the ARPHRD_CAN
check is removed from the conditions in can_rcv(), canfd_rcv() and
canxl_rcv(). Add the <linux/can/can-ml.h> include to raw.c, which
upstream got with commit faba5860fcf9 ("can: raw: instantly reject
disabled CAN frames"). ]
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/af_can.c | 12 ++++++------
net/can/bcm.c | 7 ++++---
net/can/gw.c | 7 ++++---
net/can/isotp.c | 5 +++--
net/can/raw.c | 5 +++--
5 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 52d72d56f2dd3..539e9ba06ccc9 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)))
@@ -685,7 +685,7 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev)
static int can_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
- if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_can_skb(skb))) {
+ if (unlikely(!can_get_ml_priv(dev) || !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);
@@ -700,7 +700,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
- if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canfd_skb(skb))) {
+ if (unlikely(!can_get_ml_priv(dev) || !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);
@@ -715,7 +715,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
static int canxl_rcv(struct sk_buff *skb, struct net_device *dev,
struct packet_type *pt, struct net_device *orig_dev)
{
- if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canxl_skb(skb))) {
+ if (unlikely(!can_get_ml_priv(dev) || !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 6d67af0a3b141..5f3321ede5208 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>
@@ -1706,7 +1707,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;
@@ -1854,7 +1855,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;
@@ -2011,7 +2012,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
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 79fa58cb232ed..de222fa93d6c3 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>
@@ -603,7 +604,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) {
@@ -1154,7 +1155,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);
@@ -1162,7 +1163,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 e3261fb4663af..dfe3fd47e220e 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>
@@ -1595,7 +1596,7 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
err = -ENODEV;
goto out;
}
- if (dev->type != ARPHRD_CAN) {
+ if (!can_get_ml_priv(dev)) {
err = -ENODEV;
goto out_put_dev;
}
@@ -1895,7 +1896,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 9f0fa8baff85a..26c8cf15d60ed 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -49,6 +49,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/dev.h> /* for can_is_canxl_dev_mtu() */
#include <linux/can/skb.h>
@@ -343,7 +344,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;
@@ -486,7 +487,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *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] 687+ messages in thread
* [PATCH 6.18 465/686] can: protect the receive lists with a per-device lock
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (463 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 464/686] 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:49 ` [PATCH 6.18 466/686] ceph: clamp the inline data length in ceph_fill_inline_data() Greg Kroah-Hartman
` (220 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Oliver Hartkopp,
Marc Kleine-Budde, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
commit 0f3ad9ab40e3dad06d5c0693806e07935ceedbc3 upstream.
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>
[ backport to 6.18: Adapt the can_pernet_init() context to kzalloc() as
this tree has no kzalloc_obj(). ]
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
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 8afa92d15a664..f10444c6115f2 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>
#define CAN_SFF_RCV_ARRAY_SZ (1 << CAN_SFF_ID_BITS)
#define CAN_EFF_RCV_HASH_BITS 10
@@ -53,6 +54,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];
@@ -74,6 +76,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 539e9ba06ccc9..c1e0569f777b2 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);
@@ -797,6 +807,7 @@ static int can_pernet_init(struct net *net)
kzalloc(sizeof(*net->can.rx_alldev_list), GFP_KERNEL);
if (!net->can.rx_alldev_list)
goto out;
+ spin_lock_init(&net->can.rx_alldev_list->lock);
net->can.pkg_stats = kzalloc(sizeof(*net->can.pkg_stats), GFP_KERNEL);
if (!net->can.pkg_stats)
goto out_free_rx_alldev_list;
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 5f3321ede5208..1c7c4ad3b7596 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -957,7 +957,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 */
@@ -983,21 +983,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);
@@ -1923,6 +1912,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)
@@ -1936,29 +1926,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 dfe3fd47e220e..c1c78f2d2893f 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1116,7 +1116,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
@@ -1161,7 +1161,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;
}
@@ -1401,7 +1401,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);
@@ -1475,11 +1475,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))
@@ -1494,11 +1494,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
@@ -1565,7 +1563,7 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
if (!addr->can_ifindex)
return -ENODEV;
- rtnl_lock();
+ /* lock_sock() serializes the binding with isotp_notify() */
lock_sock(sk);
if (so->bound) {
@@ -1591,19 +1589,24 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
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;
@@ -1630,35 +1633,39 @@ static int isotp_bind(struct socket *sock, struct sockaddr *uaddr, int len)
}
}
- /* 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;
}
@@ -1854,12 +1861,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))
@@ -1874,16 +1890,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 26c8cf15d60ed..94d9b36591660 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;
@@ -220,6 +221,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);
@@ -254,9 +256,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,
@@ -301,16 +305,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);
@@ -322,13 +341,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:
@@ -377,6 +396,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;
@@ -427,13 +447,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);
@@ -452,7 +474,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);
@@ -475,14 +496,25 @@ static int raw_bind(struct socket *sock, struct sockaddr *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;
@@ -492,9 +524,6 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
goto out_put_dev;
}
- if (!(dev->flags & IFF_UP))
- notify_enetdown = 1;
-
ifindex = dev->ifindex;
/* filters set by default/setsockopt */
@@ -513,7 +542,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *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);
@@ -524,24 +553,32 @@ static int raw_bind(struct socket *sock, struct sockaddr *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;
}
@@ -595,8 +632,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;
@@ -644,8 +686,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 */
@@ -752,13 +796,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] 687+ messages in thread
* [PATCH 6.18 466/686] ceph: clamp the inline data length in ceph_fill_inline_data()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (464 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 465/686] can: protect the receive lists with a per-device lock Greg Kroah-Hartman
@ 2026-11-13 15:49 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 467/686] Revert "mm/page_owner: fix memory leak in page_owner_stack_fops->release()" Greg Kroah-Hartman
` (219 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:49 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guanglei Zhu, Alex Markuze,
Ilya Dryomov, Sasha Levin
6.18-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 6.18.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 51aeae341f56d..6f6c8d9214362 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -2214,6 +2214,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] 687+ messages in thread
* [PATCH 6.18 467/686] Revert "mm/page_owner: fix memory leak in page_owner_stack_fops->release()"
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (465 preceding siblings ...)
2026-11-13 15:49 ` [PATCH 6.18 466/686] ceph: clamp the inline data length in ceph_fill_inline_data() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 468/686] timekeeping: Require permission to set auxiliary clocks Greg Kroah-Hartman
` (218 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hamid Nassiby, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hamid Nassiby <hamid.nassiby@nokia.com>
This reverts commit 05a8edf607be826738dfc620a17d9d98e8976762, which is
commit a76a5ae2c6c6 upstream.
The upstream change is only correct on top of commit 156c0c5d1463
("mm/page_owner: introduce struct stack_print_ctx"), which first appeared
in v6.19. That commit makes page_owner_stack_open() allocate a struct
stack_print_ctx through seq_open_private() and moves the stack_list
cursor into it, so ->release() must free it with seq_release_private().
6.18 does not have that commit: page_owner_stack_open() passes a size of 0
to seq_open_private(), so there is nothing to leak, and
stack_start()/stack_next() store the current struct stack node directly
in m->private.
The upstream commit was backported because it is tagged for stable and
carries a Fixes tag for 765973a09803 ("mm,page_owner: display all stacks
and their count"), but the leak it fixes only exists since 156c0c5d1463.
seq_release_private() kfree()s m->private. Closing show_stacks before
EOF therefore frees a struct stack node that is still linked in
stack_list, and the next reader of show_stacks walks into freed memory.
On v6.18.60 (x86_64 QEMU, KASAN, page_owner=on), a single 4 KiB read()
and close() followed by a full read gives:
BUG: KASAN: slab-use-after-free in stack_print+0x165/0x170
Read of size 8 at addr ff110000062adfc0 by task init/1
...
Allocated by task 1:
__kasan_kmalloc+0x7f/0x90
__set_page_owner+0x4a5/0x720
...
Freed by task 1:
kfree+0xf8/0x460
seq_release_private+0x58/0x110
full_proxy_release+0xa1/0x130
__fput+0x35c/0xac0
__x64_sys_close+0x79/0xd0
...
The buggy address belongs to the object at ff110000062adfc0
which belongs to the cache kmalloc-16 of size 16
Without KASAN, the same bug panics arm64 hardware running a
6.12.108-based kernel ("head -12 show_stacks; cat show_stacks").
With this revert applied, the QEMU reproducer completes 20
partial-read/full-read cycles without a KASAN report. mm/page_owner.c is
unchanged between v6.18.60 and v6.18.62.
Backporting 156c0c5d1463 instead is not proposed: it prepares for the
new show_handles and show_stacks_handles debugfs files rather than
fixing anything, so reverting the backport is the minimal change for
stable.
Link: https://lore.kernel.org/stable/20260106170556.173097317@linuxfoundation.org/
Signed-off-by: Hamid Nassiby <hamid.nassiby@nokia.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page_owner.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/page_owner.c b/mm/page_owner.c
index bc26764142ba5..589ec37c94aab 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -936,7 +936,7 @@ static const struct file_operations page_owner_stack_operations = {
.open = page_owner_stack_open,
.read = seq_read,
.llseek = seq_lseek,
- .release = seq_release_private,
+ .release = seq_release,
};
static int page_owner_threshold_get(void *data, u64 *val)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 468/686] timekeeping: Require permission to set auxiliary clocks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (466 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 467/686] Revert "mm/page_owner: fix memory leak in page_owner_stack_fops->release()" Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 469/686] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID Greg Kroah-Hartman
` (217 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daehyeon Ko, Thomas Gleixner, shaos,
John Stultz, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit 524d95c8a2000cba6cb80a173d76cb746c561244 upstream.
The generic clock_settime() entry point delegates permission checks to
each clock-specific callback. aux_clock_set() does not perform one. Once
an administrator enables an auxiliary clock, any local process can
therefore change the global clock offset.
A test process running as UID and GID 65534 with no effective, permitted,
inheritable, or ambient capabilities set CLOCK_AUX0 successfully, and a
separate process observed the new value. The same process was denied by
clock_adjtime(). An AppArmor profile denying sys_time also blocked
CLOCK_REALTIME changes but did not see the auxiliary clock operation.
Call security_settime64() before mutating the auxiliary timekeeper. This
matches CLOCK_REALTIME's permission model, enforces initial-user-namespace
CAP_SYS_TIME, and gives LSMs the settime hook while preserving authorized
clock changes.
Fixes: 60ecc26ec5af ("timekeeping: Provide time setter for auxiliary clocks")
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Tested-by: shaos <shawnq1@163.com>
Acked-by: John Stultz <jstultz@google.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261019080324.4147815-1-4ncienth@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/time/timekeeping.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 32f59de2ba4ce..bf25112b01568 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -14,6 +14,7 @@
#include <linux/sched.h>
#include <linux/sched/loadavg.h>
#include <linux/sched/clock.h>
+#include <linux/security.h>
#include <linux/syscore_ops.h>
#include <linux/clocksource.h>
#include <linux/jiffies.h>
@@ -2937,11 +2938,15 @@ static int aux_clock_set(const clockid_t id, const struct timespec64 *tnew)
struct tk_data *aux_tkd = aux_get_tk_data(id);
struct timekeeper *aux_tks;
ktime_t tnow, nsecs;
+ int ret;
if (!timespec64_valid_settod(tnew))
return -EINVAL;
if (!aux_tkd)
return -ENODEV;
+ ret = security_settime64(tnew, NULL);
+ if (ret)
+ return ret;
aux_tks = &aux_tkd->shadow_timekeeper;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 469/686] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (467 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 468/686] timekeeping: Require permission to set auxiliary clocks Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 470/686] mm/damon/core: move static variable last_nr_regions to damon_ctx Greg Kroah-Hartman
` (216 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sascha Frey, Ido Schimmel,
Nikolay Aleksandrov, Paolo Abeni, Sasha Levin
6.18-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 580fdec50bd59..090d50b163816 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -997,12 +997,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.
*/
@@ -1264,11 +1258,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;
@@ -2889,6 +2878,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 7e450fb9d65b0..db65dd4abd3f7 100755
--- a/tools/testing/selftests/net/fib_nexthops.sh
+++ b/tools/testing/selftests/net/fib_nexthops.sh
@@ -423,6 +423,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
@@ -527,14 +535,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"
@@ -641,14 +653,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] 687+ messages in thread
* [PATCH 6.18 470/686] mm/damon/core: move static variable last_nr_regions to damon_ctx
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (468 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 469/686] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 471/686] batman-adv: tpmeter: fix u32 truncation of reported bytes Greg Kroah-Hartman
` (215 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, SJ Park, Andrew Morton,
Fernand Sieber, SeongJae Park, Sasha Levin
6.18-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: SJ Park <sj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/damon.h | 6 ++++++
mm/damon/core.c | 5 ++---
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/include/linux/damon.h b/include/linux/damon.h
index 656a314ad2159..125fbe1c73a9d 100644
--- a/include/linux/damon.h
+++ b/include/linux/damon.h
@@ -804,6 +804,12 @@ struct damon_ctx {
struct list_head adaptive_targets;
struct list_head schemes;
+/* private: */
+ /*
+ * number of regions after last merge. Read kdamond_split_regions()
+ * for more details.
+ */
+ unsigned long last_nr_regions;
};
static inline struct damon_region *damon_next_region(struct damon_region *r)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 54a29d21d0dd1..ec44433200c63 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -2568,7 +2568,6 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
{
struct damon_target *t;
unsigned int nr_regions = 0;
- static unsigned int last_nr_regions;
int nr_subregions = 2;
damon_for_each_target(t, ctx)
@@ -2578,14 +2577,14 @@ static void kdamond_split_regions(struct damon_ctx *ctx)
return;
/* 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 < ctx->attrs.max_nr_regions / 3)
nr_subregions = 3;
damon_for_each_target(t, ctx)
damon_split_regions_of(t, nr_subregions, ctx->min_sz_region);
- last_nr_regions = nr_regions;
+ ctx->last_nr_regions = nr_regions;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 471/686] batman-adv: tpmeter: fix u32 truncation of reported bytes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (469 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 470/686] mm/damon/core: move static variable last_nr_regions to damon_ctx Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 472/686] batman-adv: tt: only transmit local ROAM flag together with DEL Greg Kroah-Hartman
` (214 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sven Eckelmann, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
commit 1025b76d13288a311e8259a0eefde0854fa63c41 upstream.
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")
[ Context ]
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 02af19aaaff29..aa297e551cd07 100644
--- a/net/batman-adv/tp_meter.c
+++ b/net/batman-adv/tp_meter.c
@@ -226,9 +226,9 @@ static void batadv_tp_batctl_notify(enum batadv_tp_meter_reason reason,
unsigned long start_time, u64 total_sent,
u32 cookie)
{
+ u64 total_bytes;
u32 test_time;
u8 result;
- u32 total_bytes;
if (!batadv_tp_is_error(reason)) {
result = BATADV_TP_REASON_COMPLETE;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 472/686] batman-adv: tt: only transmit local ROAM flag together with DEL
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (470 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 471/686] batman-adv: tpmeter: fix u32 truncation of reported bytes Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 473/686] batman-adv: tt: clear ROAM flag when re-adding a pending local client Greg Kroah-Hartman
` (213 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
6.18-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 877475c688252..c7ea317acc516 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -430,7 +430,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);
@@ -438,6 +437,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);
@@ -2691,8 +2699,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] 687+ messages in thread
* [PATCH 6.18 473/686] batman-adv: tt: clear ROAM flag when re-adding a pending local client
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (471 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 472/686] batman-adv: tt: only transmit local ROAM flag together with DEL Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 474/686] batman-adv: tt: send ROAM_ADV on each roamed back client Greg Kroah-Hartman
` (212 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
6.18-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 c7ea317acc516..d1cc702e1f14d 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -612,6 +612,7 @@ bool batadv_tt_local_add(struct net_device *mesh_iface, const u8 *addr,
int hash_added, table_size, packet_size_max;
bool ret = false;
bool roamed_back = false;
+ bool added = false;
u8 remote_flags;
u32 match_mark;
@@ -638,7 +639,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) {
@@ -719,10 +720,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] 687+ messages in thread
* [PATCH 6.18 474/686] batman-adv: tt: send ROAM_ADV on each roamed back client
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (472 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 473/686] batman-adv: tt: clear ROAM flag when re-adding a pending local client Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 475/686] batman-adv: tt: ignore ROAM flag of received ADD changes Greg Kroah-Hartman
` (211 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
6.18-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 d1cc702e1f14d..3f0b26ad699c0 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -729,7 +729,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] 687+ messages in thread
* [PATCH 6.18 475/686] batman-adv: tt: ignore ROAM flag of received ADD changes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (473 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 474/686] batman-adv: tt: send ROAM_ADV on each roamed back client Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 476/686] batman-adv: tt: only update flags for TT events Greg Kroah-Hartman
` (210 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
commit c5d68abe6e7f1dbd132a602cb696fe1fff0389eb upstream.
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")
[ Context ]
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 3f0b26ad699c0..c73596ef6160c 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -3268,20 +3268,29 @@ static void _batadv_tt_update_changes(struct batadv_priv *bat_priv,
{
int i;
int roams;
+ u8 flags;
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] 687+ messages in thread
* [PATCH 6.18 476/686] batman-adv: tt: only update flags for TT events
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (474 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 475/686] batman-adv: tt: ignore ROAM flag of received ADD changes Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 477/686] batman-adv: tt: dont drop local events queued during TVLV update Greg Kroah-Hartman
` (209 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sven Eckelmann, Sasha Levin
6.18-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 | 30 ++++++++++--------------------
1 file changed, 10 insertions(+), 20 deletions(-)
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
index c73596ef6160c..e7242706e3345 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -415,6 +415,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,
@@ -423,7 +426,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv,
struct batadv_tt_change_node *tt_change_node, *entry, *safe;
struct batadv_tt_common_entry *common = &tt_local_entry->common;
u8 flags = common->flags | event_flags;
- bool del_op_requested, del_op_entry;
+ bool del_op_requested;
size_t changes;
tt_change_node = kmem_cache_alloc(batadv_tt_change_cache, GFP_ATOMIC);
@@ -457,25 +460,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] 687+ messages in thread
* [PATCH 6.18 477/686] batman-adv: tt: dont drop local events queued during TVLV update
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (475 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 476/686] batman-adv: tt: only update flags for TT events Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 478/686] can: raw, isotp: copy socket options outside of lock_sock() Greg Kroah-Hartman
` (208 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Sven Eckelmann, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <sven@narfation.org>
commit ed7a0dfdd370acb48be7a281df732c1bebcc7f1d upstream.
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")
[ Context ]
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 e7242706e3345..dfec5cce5fe50 100644
--- a/net/batman-adv/translation-table.c
+++ b/net/batman-adv/translation-table.c
@@ -978,20 +978,22 @@ 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_tt_change_node *entry, *safe;
struct batadv_tvlv_tt_data *tt_data;
struct batadv_tvlv_tt_change *tt_change;
int tt_diff_len, tt_change_len = 0;
- int tt_diff_entries_num = 0;
int tt_diff_entries_count = 0;
bool drop_changes = false;
size_t tt_extra_len = 0;
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
@@ -1009,19 +1011,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,
@@ -1031,7 +1053,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);
@@ -3695,11 +3716,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;
}
@@ -3716,7 +3751,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] 687+ messages in thread
* [PATCH 6.18 478/686] can: raw, isotp: copy socket options outside of lock_sock()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (476 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 477/686] batman-adv: tt: dont drop local events queued during TVLV update Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 479/686] sched_ext: Reset runnable_at when a task leaves its scheduler Greg Kroah-Hartman
` (207 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Hartkopp <socketcan@hartkopp.net>
commit 43c973a0887d3d7b2ee0a446603c97bf0f38c58e upstream.
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>
[ backport to 6.18: raw_getsockopt() uses copy_to_user() and put_user()
instead of the getsockopt_iter interface in this tree. Duplicate the
filters under lock_sock() and copy them with copy_to_user() after
release_sock(). Also move the put_user() of the needed filter space
for -ERANGE behind release_sock(), which upstream writes to the kernel
side opt->optlen. ]
Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/can/isotp.c | 100 ++++++++++++++-----------
net/can/raw.c | 193 ++++++++++++++++++++++++++----------------------
2 files changed, 160 insertions(+), 133 deletions(-)
diff --git a/net/can/isotp.c b/net/can/isotp.c
index c1c78f2d2893f..3597e72a88cac 100644
--- a/net/can/isotp.c
+++ b/net/can/isotp.c
@@ -1687,8 +1687,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);
@@ -1699,11 +1699,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))
@@ -1728,55 +1724,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;
@@ -1790,13 +1768,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 94d9b36591660..1e357783292b5 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -600,63 +600,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,
@@ -670,7 +643,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;
@@ -678,13 +651,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;
@@ -711,31 +678,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)
@@ -745,13 +696,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)
@@ -759,11 +704,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;
@@ -772,13 +713,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:
@@ -791,17 +726,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;
}
@@ -823,29 +825,40 @@ static int raw_getsockopt(struct socket *sock, int level, int optname,
switch (optname) {
case CAN_RAW_FILTER: {
+ struct can_filter *filter = NULL;
+ int fsize = 0;
int err = 0;
lock_sock(sk);
if (ro->count > 0) {
- int fsize = ro->count * sizeof(struct can_filter);
+ fsize = ro->count * sizeof(struct can_filter);
/* user space buffer to small for filter list? */
if (len < fsize) {
/* return -ERANGE and needed space in optlen */
err = -ERANGE;
- if (put_user(fsize, optlen))
- err = -EFAULT;
} else {
if (len > fsize)
len = fsize;
- if (copy_to_user(optval, ro->filter, 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 (err == -ERANGE) {
+ if (put_user(fsize, optlen))
+ err = -EFAULT;
+ } else if (filter) {
+ if (copy_to_user(optval, filter, len))
+ err = -EFAULT;
+ kfree(filter);
+ }
+
if (!err)
err = put_user(len, optlen);
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 479/686] sched_ext: Reset runnable_at when a task leaves its scheduler
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (477 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 478/686] 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 6.18 480/686] ata: libata-scsi: reject data-in commands with a data-out buffer Greg Kroah-Hartman
` (206 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michal Blaszczyk, Andrea Righi,
Tejun Heo, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Blaszczyk <michalblk@google.com>
[ Upstream commit 993e8fbfecbbf284b9644c6f10741b28fb914094 ]
The watchdog measures how long a task has been waiting from
p->scx.runnable_at, which set_task_runnable() resets when the task becomes
runnable after it last ran. ops_dequeue() never asks for a reset, as the
dequeue of a waiting task is temporary, e.g. for a migration or an
attribute change.
Leaving the scheduler isn't temporary. A task which is switched out of
SCHED_EXT while it's waiting keeps its runnable_at. When it's switched back
and becomes runnable, its wait appears to have started before it left, and
the time it spent in another class counts towards the timeout. If the
watchdog checks before the task runs, it aborts the scheduler:
sched_ext: class_switch_stall: runner[418] failed to run for 3.010s
Here, the task waited for a few milliseconds before it was switched to
SCHED_OTHER, slept outside of SCHED_EXT for three seconds, and was charged
for all of it as soon as it woke up on SCHED_EXT again.
The same happens when scx_sub_enable_workfn() hands a waiting task over to
a new sub-scheduler, which can then be blamed for time the task waited
under the parent. scx_rehome_task() isn't affected, as it moves the task
through SCX_TASK_INIT, which resets runnable_at. The stale runnable_at also
skews the default core-sched ordering in scx_prio_less().
Reset runnable_at in scx_disable_task(), when the task leaves the control
of its scheduler.
Fixes: 8a010b81b3a5 ("sched_ext: Implement runnable task stall watchdog")
Cc: stable@vger.kernel.org # v6.12+
Assisted-by: LLM
Signed-off-by: Michal Blaszczyk <michalblk@google.com>
Reviewed-by: Andrea Righi <arighi@nvidia.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
[ michalblk: applied to kernel/sched/ext.c; adjusted context ]
Signed-off-by: Michal Blaszczyk <michalblk@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/ext.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c
index 78f15ddc0aa5a..3117d1ef869c5 100644
--- a/kernel/sched/ext.c
+++ b/kernel/sched/ext.c
@@ -1438,7 +1438,11 @@ static void ops_dequeue(struct rq *rq, struct task_struct *p, u64 deq_flags)
struct scx_sched *sch = scx_root;
unsigned long opss;
- /* dequeue is always temporary, don't reset runnable_at */
+ /*
+ * Don't reset runnable_at. If @p is waiting, the wait continues across
+ * temporary dequeues, e.g. for a migration or an attribute change.
+ * scx_disable_task() ends it if @p leaves its scheduler.
+ */
clr_task_runnable(p, false);
/* acquire ensures that we see the preceding updates on QUEUED */
@@ -2959,6 +2963,14 @@ static void scx_disable_task(struct task_struct *p)
if (SCX_HAS_OP(sch, disable))
SCX_CALL_OP_TASK(sch, SCX_KF_REST, disable, rq, p);
scx_set_task_state(p, SCX_TASK_READY);
+
+ /*
+ * If @p is runnable but not running, its wait started at runnable_at,
+ * which ops_dequeue() didn't reset. Leaving @sch ends the wait. Reset
+ * runnable_at the next time @p is enqueued on SCX, so that the watchdog
+ * doesn't count the time @p spends elsewhere.
+ */
+ p->scx.flags |= SCX_TASK_RESET_RUNNABLE_AT;
}
static void scx_exit_task(struct task_struct *p)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 480/686] ata: libata-scsi: reject data-in commands with a data-out buffer
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (478 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 479/686] sched_ext: Reset runnable_at when a task leaves its scheduler Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 481/686] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Greg Kroah-Hartman
` (205 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhao Gongyi, Damien Le Moal,
Niklas Cassel, Sasha Levin
6.18-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 8b9530c505315..0988bf574b81e 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -1977,6 +1977,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:
@@ -2008,6 +2020,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);
@@ -3065,6 +3083,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] 687+ messages in thread
* [PATCH 6.18 481/686] powerpc/bpf: fix buffer overflow in JIT for large BPF programs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (479 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 480/686] ata: libata-scsi: reject data-in commands with a data-out buffer Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 482/686] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels Greg Kroah-Hartman
` (204 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Hari Bathini,
Abhishek Dubey, Saket Kumar Bhaskar, Yeswanth Krishna Tellakula,
R Nageswara Sastry, Madhavan Srinivasan, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abhishek Dubey <adubey@linux.ibm.com>
[ Upstream commit 78ce55b7913a78e1687306668e078b86bc6508ee ]
During size calculation in pass-0, exit_addr is 0 since addrs[fp->len]
is not yet populated. bpf_jit_emit_exit_insn() treats a zero exit_addr
as in-range and skips bpf_jit_build_epilogue(), so the alternate inline
epilogue instructions are not counted in alloclen.
In later passes, if the real exit_addr falls outside the 32MB branch
range, the full inline epilogue is emitted into the already-allocated
buffer, writing past its end and corrupting adjacent memory.
Fix by ensuring exit_addr is non-zero before treating it as in-range,
so pass-0 always falls through to bpf_jit_build_epilogue() and
conservatively accounts for all epilogue instructions in alloclen.
Also range check alt_exit_addr directly in the else-if condition.
Since exit_addr handling now falls through to the epilogue, two
related issues in bpf_int_jit_compile() must also be addressed:
1. Reset cgctx.alt_exit_addr before the second size-calculation pass.
Without this, a stale alt_exit_addr from the first pass causes the
second pass to emit a single jump instead of the full epilogue,
undercounting alloclen and reintroducing the overflow.
2. Recompute addrs[fp->len] at the end of each code-generation pass.
The larger pass-0 body can shrink in later passes as out-of-range
exits settle into in-range jumps; a stale addrs[fp->len] would
leave exit branches targeting past the real (shrunken) epilogue.
Because shrinkage in a later pass can move the epilogue offset, the
fixed two-pass loop is no longer sufficient: an exit that was out of
range in an earlier pass may fall in range once the epilogue offset
shrinks, shrinking the body further and overwriting the start of the
epilogue. Convert the code-generation loop to iterate until the
program size converges, bounded by CODEGEN_MAX_PASSES, and fail the
JIT if it does not converge.
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92
Fixes: 0ffdbce6f4a8 ("powerpc/bpf: Handle large branch ranges with BPF_EXIT")
Cc: stable@vger.kernel.org
Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
Signed-off-by: Abhishek Dubey <adubey@linux.ibm.com>
Signed-off-by: Saket Kumar Bhaskar <skb99@linux.ibm.com>
Tested-by: Yeswanth Krishna Tellakula <yeswanth@linux.ibm.com>
Tested-by: R Nageswara Sastry <rnsastry@linux.ibm.com>
Link: https://lore.kernel.org/bpf/20260529015855.364704-2-adubey@linux.ibm.com/T/#mfcb23909d977b949727cca4f59ee56a13fd69b92
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/eebffa997e07781b384c4480e2b03c5b87c1aeb1.1789982239.git.skb99@linux.ibm.com
[ sashal: Replaced goto out_err with fp = org_fp followed by goto out_addrs because the out_err label is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/net/bpf_jit.h | 7 +++++++
arch/powerpc/net/bpf_jit_comp.c | 35 +++++++++++++++++++++++++--------
2 files changed, 34 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h
index 8334cd667bba1..ae2c92a8b6e77 100644
--- a/arch/powerpc/net/bpf_jit.h
+++ b/arch/powerpc/net/bpf_jit.h
@@ -14,6 +14,13 @@
#include <asm/ppc-opcode.h>
#include <linux/build_bug.h>
+/*
+ * We need at least 2 passes for proper code generation, and may need
+ * additional passes if code size changes between passes.
+ */
+#define CODEGEN_MIN_PASSES 2
+#define CODEGEN_MAX_PASSES 3
+
#ifdef CONFIG_PPC64_ELF_ABI_V1
#define FUNCTION_DESCR_SIZE 24
#else
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c
index cedab25aa3a82..829b60ae485ff 100644
--- a/arch/powerpc/net/bpf_jit_comp.c
+++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -99,11 +99,10 @@ void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx)
int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr)
{
- if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) {
+ if (exit_addr && is_offset_in_branch_range(exit_addr - (long)(ctx->idx * 4))) {
PPC_JMP(exit_addr);
- } else if (ctx->alt_exit_addr) {
- if (WARN_ON(!is_offset_in_branch_range((long)ctx->alt_exit_addr - (ctx->idx * 4))))
- return -1;
+ } else if (ctx->alt_exit_addr && is_offset_in_branch_range(
+ (long)(ctx->alt_exit_addr) - (long)(ctx->idx * 4))) {
PPC_JMP(ctx->alt_exit_addr);
} else {
ctx->alt_exit_addr = ctx->idx * 4;
@@ -223,6 +222,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
*/
if (cgctx.seen & SEEN_TAILCALL || !is_offset_in_branch_range((long)cgctx.idx * 4)) {
cgctx.idx = 0;
+ cgctx.alt_exit_addr = 0;
if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false)) {
fp = org_fp;
goto out_addrs;
@@ -259,10 +259,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
code_base = (u32 *)(image + FUNCTION_DESCR_SIZE);
fcode_base = (u32 *)(fimage + FUNCTION_DESCR_SIZE);
- /* Code generation passes 1-2 */
- for (pass = 1; pass < 3; pass++) {
+ /* Code generation passes 1-2+, loop until program size converges. */
+ for (pass = 1; pass <= CODEGEN_MAX_PASSES; pass++) {
+ u32 prev_proglen = proglen;
+
/* Now build the prologue, body code & epilogue for real. */
cgctx.idx = 0;
+ cgctx.exentry_idx = 0;
cgctx.alt_exit_addr = 0;
bpf_jit_build_prologue(code_base, &cgctx);
if (bpf_jit_build_body(fp, code_base, fcode_base, &cgctx, addrs, pass,
@@ -272,11 +275,27 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
fp = org_fp;
goto out_addrs;
}
+ addrs[fp->len] = cgctx.idx * 4;
bpf_jit_build_epilogue(code_base, &cgctx);
+ proglen = cgctx.idx * 4;
+
if (bpf_jit_enable > 1)
pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass,
- proglen - (cgctx.idx * 4), cgctx.seen);
+ prev_proglen - proglen, cgctx.seen);
+
+ /* Check if program size has converged, but ensure minimum passes */
+ if (pass >= CODEGEN_MIN_PASSES && proglen == prev_proglen)
+ break;
+
+ if (pass == CODEGEN_MAX_PASSES && proglen != prev_proglen) {
+ pr_err("BPF JIT: Program did not converge after %d passes\n",
+ CODEGEN_MAX_PASSES);
+ bpf_arch_text_copy(&fhdr->size, &hdr->size, sizeof(hdr->size));
+ bpf_jit_binary_pack_free(fhdr, hdr);
+ fp = org_fp;
+ goto out_addrs;
+ }
}
if (bpf_jit_enable > 1)
@@ -336,7 +355,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass
u32 *fixup;
/* Populate extable entries only in the last pass */
- if (pass != 2)
+ if (pass < CODEGEN_MIN_PASSES)
return 0;
if (!fp->aux->extable ||
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 482/686] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (480 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 481/686] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 483/686] kho: do not reserve scratch memory in the kdump kernel Greg Kroah-Hartman
` (203 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ard Biesheuvel, Eric Biggers,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit dd2a4edb26e1c78823c50ba10c42f2d3de2e5ec4 upstream.
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 fa882108ba62c..2f2edeaf9de3e 100644
--- a/lib/crypto/Kconfig
+++ b/lib/crypto/Kconfig
@@ -142,7 +142,7 @@ config CRYPTO_LIB_SHA1_ARCH
depends on CRYPTO_LIB_SHA1 && !UML
default y if ARM
default y if ARM64 && KERNEL_MODE_NEON
- 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
@@ -160,7 +160,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
@@ -180,7 +180,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] 687+ messages in thread
* [PATCH 6.18 483/686] kho: do not reserve scratch memory in the kdump kernel
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (481 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 482/686] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 484/686] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D Greg Kroah-Hartman
` (202 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maxi Saparov,
Mike Rapoport (Microsoft), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maxi Saparov <masaparov@coreweave.com>
[ Upstream commit 48be325089e15077411785d0c41ddb9071a61081 ]
If a kernel with CONFIG_KEXEC_HANDOVER_ENABLE_DEFAULT=y (or kho=on)
does not receive a handover FDT, it reserves KHO scratch memory in
kho_reserve_scratch().
The kdump kernel always takes this path. Since commit a6715d7ec472
("kho: skip KHO for crash kernel"), the kernel does not add KHO
metadata to the crash kimage. As a result, the kdump kernel never
receives a handover FDT and always reserves scratch memory.
The kdump kernel boots in the small crashkernel= memory reservation.
On our x86 hosts, the kernel and initramfs make approximately 176 MB
of early reservations. The scratch areas then use approximately
650 MB more of the crashkernel memory. When a large early allocation
fails, the kdump kernel panics:
bio: can't create integrity buf pool
A kdump kernel has nothing to hand over: its only task is to dump the
memory of the old kernel and reboot. Fix is to disable KHO at the top of
kho_memory_init() so that the kdump kernel does not reserve scratch
memory.
Fixes: 3dc92c311498 ("kexec: add Kexec HandOver (KHO) generation helpers")
Cc: stable@vger.kernel.org
Signed-off-by: Maxi Saparov <masaparov@coreweave.com>
Link: https://patch.msgid.link/20260811161857.3096-1-maxi.saparov@gmail.com
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
[ sashal: adjusted context to apply the unchanged additions to the handover implementation at its older source location ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/kexec_handover.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/kexec_handover.c b/kernel/kexec_handover.c
index 9691f6bc2fba7..e503573e03190 100644
--- a/kernel/kexec_handover.c
+++ b/kernel/kexec_handover.c
@@ -10,6 +10,7 @@
#include <linux/cleanup.h>
#include <linux/cma.h>
+#include <linux/crash_dump.h>
#include <linux/count_zeros.h>
#include <linux/kexec.h>
#include <linux/kexec_handover.h>
@@ -1325,6 +1326,12 @@ void __init kho_memory_init(void)
{
struct folio *folio;
+ if (is_kdump_kernel()) {
+ kho_enable = false;
+ pr_info("disabled in the kdump kernel\n");
+ return;
+ }
+
if (kho_in.scratch_phys) {
kho_scratch = phys_to_virt(kho_in.scratch_phys);
kho_release_scratch();
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 484/686] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (482 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 483/686] kho: do not reserve scratch memory in the kdump kernel Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 485/686] media: i2c: imx219: Propagate errors from control range updates Greg Kroah-Hartman
` (201 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cheng Ming Lin, Michael Walle,
Russell Senior, Sasha Levin
6.18-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 context for the MX25L12805D entry because the upstream fixups assignment is absent ]
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] 687+ messages in thread
* [PATCH 6.18 485/686] media: i2c: imx219: Propagate errors from control range updates
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (483 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 484/686] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 486/686] media: imx219: The horizontal blanking step is 8 Greg Kroah-Hartman
` (200 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tarang Raval, Isaac Scott,
Dave Stevenson, Sakari Ailus, Hans Verkuil, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tarang Raval <tarang.raval@siliconsignals.io>
[ Upstream commit dff10c7044e8777bd14bba99444ff8a69d9bb2fe ]
Propagate return values from __v4l2_ctrl_modify_range() and
__v4l2_ctrl_s_ctrl() in imx219_set_ctrl() and imx219_set_pad_format().
This ensures proper error handling instead of ignoring possible
failures. Also return the result of imx219_set_pad_format() from
imx219_init_state().
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
Reviewed-by: Isaac Scott <isaac.scott@ideasonboard.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Stable-dep-of: 47576c541e9b ("media: imx219: The horizontal blanking step is 8")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/imx219.c | 61 +++++++++++++++++++++++++-------------
1 file changed, 40 insertions(+), 21 deletions(-)
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index 00aec91e3d499..ffb04a56419ad 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -463,10 +463,14 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
exposure_max = format->height + ctrl->val - 4;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
exposure_max : IMX219_EXPOSURE_DEFAULT;
- __v4l2_ctrl_modify_range(imx219->exposure,
- imx219->exposure->minimum,
- exposure_max, imx219->exposure->step,
- exposure_def);
+ ret = __v4l2_ctrl_modify_range(imx219->exposure,
+ imx219->exposure->minimum,
+ exposure_max,
+ imx219->exposure->step,
+ exposure_def);
+ if (ret)
+ return ret;
+
}
/*
@@ -858,6 +862,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
struct v4l2_rect *crop;
u8 bin_h, bin_v, binning;
u32 prev_line_len;
+ int ret;
format = v4l2_subdev_state_get_format(state, 0);
prev_line_len = format->width + imx219->hblank->val;
@@ -893,19 +898,28 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
int pixel_rate;
/* Update limits and set FPS to default */
- __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
- IMX219_FLL_MAX - mode->height, 1,
+ ret = __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
+ IMX219_FLL_MAX - mode->height, 1,
+ mode->fll_def - mode->height);
+ if (ret)
+ return ret;
+
+ ret = __v4l2_ctrl_s_ctrl(imx219->vblank,
mode->fll_def - mode->height);
- __v4l2_ctrl_s_ctrl(imx219->vblank,
- mode->fll_def - mode->height);
+ if (ret)
+ return ret;
+
/* Update max exposure while meeting expected vblanking */
exposure_max = mode->fll_def - 4;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
exposure_max : IMX219_EXPOSURE_DEFAULT;
- __v4l2_ctrl_modify_range(imx219->exposure,
- imx219->exposure->minimum,
- exposure_max, imx219->exposure->step,
- exposure_def);
+ ret = __v4l2_ctrl_modify_range(imx219->exposure,
+ imx219->exposure->minimum,
+ exposure_max,
+ imx219->exposure->step,
+ exposure_def);
+ if (ret)
+ return ret;
/*
* With analog binning the default minimum line length of 3448
@@ -916,9 +930,12 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
imx219_get_binning(state, &bin_h, &bin_v);
llp_min = (bin_h & bin_v) == IMX219_BINNING_X2_ANALOG ?
IMX219_BINNED_LLP_MIN : IMX219_LLP_MIN;
- __v4l2_ctrl_modify_range(imx219->hblank, llp_min - mode->width,
- IMX219_LLP_MAX - mode->width, 1,
- llp_min - mode->width);
+ ret = __v4l2_ctrl_modify_range(imx219->hblank,
+ llp_min - mode->width,
+ IMX219_LLP_MAX - mode->width, 1,
+ llp_min - mode->width);
+ if (ret)
+ return ret;
/*
* Retain PPL setting from previous mode so that the
* line time does not change on a mode change.
@@ -927,13 +944,17 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
* mode width subtracted.
*/
hblank = prev_line_len - mode->width;
- __v4l2_ctrl_s_ctrl(imx219->hblank, hblank);
+ ret = __v4l2_ctrl_s_ctrl(imx219->hblank, hblank);
+ if (ret)
+ return ret;
/* Scale the pixel rate based on the mode specific factor */
pixel_rate = imx219_get_pixel_rate(imx219) *
imx219_get_rate_factor(state);
- __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate,
- pixel_rate, 1, pixel_rate);
+ ret = __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate,
+ pixel_rate, 1, pixel_rate);
+ if (ret)
+ return ret;
}
return 0;
@@ -982,9 +1003,7 @@ static int imx219_init_state(struct v4l2_subdev *sd,
},
};
- imx219_set_pad_format(sd, state, &fmt);
-
- return 0;
+ return imx219_set_pad_format(sd, state, &fmt);
}
static const struct v4l2_subdev_video_ops imx219_video_ops = {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 486/686] media: imx219: The horizontal blanking step is 8
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (484 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 485/686] media: i2c: imx219: Propagate errors from control range updates Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 487/686] soc: qcom: pmic_glink: Fix device access from worker during suspend Greg Kroah-Hartman
` (199 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sakari Ailus, Dave Stevenson,
Laurent Pinchart, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <sakari.ailus@linux.intel.com>
[ Upstream commit 47576c541e9b473841742bd0686d4940f5c93564 ]
The step for the LINE_LENGTH_A register on imx219 is 8. Take this into
account in creating and modifying the horizontal blanking control. The
minimum line length in pixels as well as the horizontal blanking values
are already divisible by 8.
Fixes: cd5e2fd89923 ("media: i2c: imx219: make HBLANK r/w to allow longer exposures")
Cc: stable@vger.kernel.org
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/imx219.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index ffb04a56419ad..76e65cedbb32f 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -77,6 +77,7 @@
#define IMX219_LLP_MIN 0x0d78
#define IMX219_BINNED_LLP_MIN 0x0de8
#define IMX219_LLP_MAX 0x7ff0
+#define IMX219_LLP_STEP 8
#define IMX219_REG_X_ADD_STA_A CCI_REG16(0x0164)
#define IMX219_REG_X_ADD_END_A CCI_REG16(0x0166)
@@ -587,7 +588,8 @@ static int imx219_init_controls(struct imx219 *imx219)
imx219->hblank = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
V4L2_CID_HBLANK,
IMX219_LLP_MIN - mode->width,
- IMX219_LLP_MAX - mode->width, 1,
+ IMX219_LLP_MAX - mode->width,
+ IMX219_LLP_STEP,
IMX219_LLP_MIN - mode->width);
exposure_max = mode->fll_def - 4;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
@@ -932,7 +934,8 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
IMX219_BINNED_LLP_MIN : IMX219_LLP_MIN;
ret = __v4l2_ctrl_modify_range(imx219->hblank,
llp_min - mode->width,
- IMX219_LLP_MAX - mode->width, 1,
+ IMX219_LLP_MAX - mode->width,
+ IMX219_LLP_STEP,
llp_min - mode->width);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 487/686] soc: qcom: pmic_glink: Fix device access from worker during suspend
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (485 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 486/686] media: imx219: The horizontal blanking step is 8 Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 488/686] PCI: endpoint: pci-epf-vntb: Manage virtual NTB and PCI bus lifetime Greg Kroah-Hartman
` (198 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johan Hovold, Caleb Connolly,
Bjorn Andersson, Abel Vesa, Abel Vesa, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abel Vesa <abel.vesa@linaro.org>
[ Upstream commit 7d0767c5cd878707fd6711023731549c83563840 ]
For historical reasons, the GLINK smem interrupt is registered with
IRRQF_NO_SUSPEND flag set, which is the underlying problem here, since the
incoming messages can be delivered during late suspend and early
resume.
In this specific case, the pmic_glink_altmode_worker() currently gets
scheduled on the system_wq which can be scheduled to run while devices
are still suspended. This proves to be a problem when a Type-C retimer,
switch or mux that is controlled over a bus like I2C, because the I2C
controller is suspended.
This has been proven to be the case on the X Elite boards where such
retimers (ParadeTech PS8830) are used in order to handle Type-C
orientation and altmode configuration. The following warning is thrown:
[ 35.134876] i2c i2c-4: Transfer while suspended
[ 35.143865] WARNING: CPU: 0 PID: 99 at drivers/i2c/i2c-core.h:56 __i2c_transfer+0xb4/0x57c [i2c_core]
[ 35.352879] Workqueue: events pmic_glink_altmode_worker [pmic_glink_altmode]
[ 35.360179] pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--)
[ 35.455242] Call trace:
[ 35.457826] __i2c_transfer+0xb4/0x57c [i2c_core] (P)
[ 35.463086] i2c_transfer+0x98/0xf0 [i2c_core]
[ 35.467713] i2c_transfer_buffer_flags+0x54/0x88 [i2c_core]
[ 35.473502] regmap_i2c_write+0x20/0x48 [regmap_i2c]
[ 35.478659] _regmap_raw_write_impl+0x780/0x944
[ 35.483401] _regmap_bus_raw_write+0x60/0x7c
[ 35.487848] _regmap_write+0x134/0x184
[ 35.491773] regmap_write+0x54/0x78
[ 35.495418] ps883x_set+0x58/0xec [ps883x]
[ 35.499688] ps883x_sw_set+0x60/0x84 [ps883x]
[ 35.504223] typec_switch_set+0x48/0x74 [typec]
[ 35.508952] pmic_glink_altmode_worker+0x44/0x1fc [pmic_glink_altmode]
[ 35.515712] process_scheduled_works+0x1a0/0x2d0
[ 35.520525] worker_thread+0x2a8/0x3c8
[ 35.524449] kthread+0xfc/0x184
[ 35.527749] ret_from_fork+0x10/0x20
The proper solution here should be to not deliver these kind of messages
during system suspend at all, or at least make it configurable per glink
client. But simply dropping the IRQF_NO_SUSPEND flag entirely will break
other clients. The final shape of the rework of the pmic glink driver in
order to fulfill both the filtering of the messages that need to be able
to wake-up the system and the queueing of these messages until the system
has properly resumed is still being discussed and it is planned as a
future effort.
Meanwhile, the stop-gap fix here is to schedule the pmic glink altmode
worker on the system_freezable_wq instead of the system_wq. This will
result in the altmode worker not being scheduled to run until the
devices are resumed first, which will give the controllers like I2C a
chance to resume before the transfer is requested.
Reported-by: Johan Hovold <johan+linaro@kernel.org>
Closes: https://lore.kernel.org/lkml/Z1CCVjEZMQ6hJ-wK@hovoldconsulting.com/
Fixes: 080b4e24852b ("soc: qcom: pmic_glink: Introduce altmode support")
Cc: stable@vger.kernel.org # 6.3
Reviewed-by: Caleb Connolly <caleb.connolly@linaro.org>
Reviewed-by: Bjorn Andersson <andersson@kernel.org>
Signed-off-by: Abel Vesa <abel.vesa@linaro.org>
Signed-off-by: Abel Vesa <abel.vesa@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260819-b4-soc-qcom-pmic-glink-fix-device-access-on-worker-while-suspended-v3-1-169b00e0d9d4@oss.qualcomm.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
[ sashal: Adjusted SC8280XP hunk context for the existing payload parser, which lacks newer Thunderbolt/USB4 notification handling. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/soc/qcom/pmic_glink_altmode.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c
index 7f11acd33323b..22e4c1af745c8 100644
--- a/drivers/soc/qcom/pmic_glink_altmode.c
+++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -303,7 +303,7 @@ static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmod
alt_port->mode = mode;
alt_port->hpd_state = hpd_state;
alt_port->hpd_irq = hpd_irq;
- schedule_work(&alt_port->work);
+ queue_work(system_freezable_wq, &alt_port->work);
}
#define SC8280XP_DPAM_MASK 0x3f
@@ -346,7 +346,7 @@ static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmod
alt_port->mode = mode;
alt_port->hpd_state = hpd_state;
alt_port->hpd_irq = hpd_irq;
- schedule_work(&alt_port->work);
+ queue_work(system_freezable_wq, &alt_port->work);
}
static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 488/686] PCI: endpoint: pci-epf-vntb: Manage virtual NTB and PCI bus lifetime
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (486 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 487/686] soc: qcom: pmic_glink: Fix device access from worker during suspend Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 489/686] platform: int3472: discrete: Support multiple HIDs per GPIO map entry Greg Kroah-Hartman
` (197 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Koichiro Den, Manivannan Sadhasivam,
Bjorn Helgaas, Frank Li, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Koichiro Den <den@valinux.co.jp>
[ Upstream commit 5cdbd6d3a3a147fa9975e35f2602cbec9a72a932 ]
The virtual PCI driver registers an ntb_dev but has no remove callback.
Unbinding the endpoint function can therefore free BARs while the NTB
device and its client still use them. It also leaves the virtual PCI
devices and root bus allocated.
Allocate an ntb_dev for each virtual PCI probe and unregister it from the
matching remove callback. Start command processing only after registration.
Publish the device for doorbell IRQs at the same point. During remove, stop
the command work and drain IRQ handlers before unregistering the device.
Retain the root bus returned by pci_scan_bus() so it can be removed on
unbind. Unregister the virtual PCI driver before releasing endpoint
resources. Stop and remove the root bus under the PCI rescan/remove lock,
then release its host bridge.
Fixes: e35f56bb0330 ("PCI: endpoint: Support NTB transfer between RC and EP")
Signed-off-by: Koichiro Den <den@valinux.co.jp>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Cc: stable@vger.kernel.org # 6.0+
Link: https://patch.msgid.link/20260901063238.631166-3-den@valinux.co.jp
[ sashal: adapted doorbell changes to the existing polling implementation without IRQ handlers or a peer-doorbell worker ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/endpoint/functions/pci-epf-vntb.c | 69 +++++++++++++++----
1 file changed, 55 insertions(+), 14 deletions(-)
diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
index 68110855ea1c7..39d9844873f53 100644
--- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
+++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
@@ -118,7 +118,7 @@ struct epf_ntb_ctrl {
} __packed;
struct epf_ntb {
- struct ntb_dev ntb;
+ struct ntb_dev *ntb;
struct pci_epf *epf;
struct config_group group;
@@ -144,10 +144,15 @@ struct epf_ntb {
void __iomem *vpci_mw_addr[MAX_MW];
struct delayed_work cmd_handler;
+ struct pci_bus *vpci_bus;
};
#define to_epf_ntb(epf_group) container_of((epf_group), struct epf_ntb, group)
-#define ntb_ndev(__ntb) container_of(__ntb, struct epf_ntb, ntb)
+
+static struct epf_ntb *ntb_ndev(struct ntb_dev *ntb)
+{
+ return ntb->pdev->sysdata;
+}
static struct pci_epf_header epf_ntb_header = {
.vendorid = PCI_ANY_ID,
@@ -173,7 +178,7 @@ static int epf_ntb_link_up(struct epf_ntb *ntb, bool link_up)
else
ntb->reg->link_status &= ~LINK_STATUS_UP;
- ntb_link_event(&ntb->ntb);
+ ntb_link_event(ntb->ntb);
return 0;
}
@@ -261,7 +266,7 @@ static void epf_ntb_cmd_handler(struct work_struct *work)
for (i = 1; i < ntb->db_count; i++) {
if (ntb->epf_db[i]) {
ntb->db |= 1 << (i - 1);
- ntb_db_event(&ntb->ntb, i);
+ ntb_db_event(ntb->ntb, i);
ntb->epf_db[i] = 0;
}
}
@@ -796,7 +801,6 @@ static int epf_ntb_epc_init(struct epf_ntb *ntb)
}
INIT_DELAYED_WORK(&ntb->cmd_handler, epf_ntb_cmd_handler);
- queue_work(kpcintb_workqueue, &ntb->cmd_handler.work);
return 0;
@@ -1100,6 +1104,7 @@ static int vpci_scan_bus(void *sysdata)
pr_err("create pci bus failed\n");
return -EINVAL;
}
+ ndev->vpci_bus = vpci_bus;
pci_bus_add_devices(vpci_bus);
@@ -1144,7 +1149,7 @@ static int vntb_epf_mw_set_trans(struct ntb_dev *ndev, int pidx, int idx,
int ret;
struct device *dev;
- dev = &ntb->ntb.dev;
+ dev = &ndev->dev;
barno = ntb->epf_ntb_bar[BAR_MW1 + idx];
epf_bar = &ntb->epf->bar[barno];
epf_bar->phys_addr = addr;
@@ -1244,7 +1249,7 @@ static int vntb_epf_peer_db_set(struct ntb_dev *ndev, u64 db_bits)
ret = pci_epc_raise_irq(ntb->epf->epc, func_no, vfunc_no,
PCI_IRQ_MSI, interrupt_num + 1);
if (ret)
- dev_err(&ntb->ntb.dev, "Failed to raise IRQ\n");
+ dev_err(&ntb->epf->dev, "Failed to raise IRQ\n");
return ret;
}
@@ -1327,13 +1332,18 @@ static const struct ntb_dev_ops vntb_epf_ops = {
static int pci_vntb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
- int ret;
struct epf_ntb *ndev = (struct epf_ntb *)pdev->sysdata;
struct device *dev = &pdev->dev;
+ struct ntb_dev *ntb;
+ int ret;
- ndev->ntb.pdev = pdev;
- ndev->ntb.topo = NTB_TOPO_NONE;
- ndev->ntb.ops = &vntb_epf_ops;
+ ntb = devm_kzalloc(dev, sizeof(*ntb), GFP_KERNEL);
+ if (!ntb)
+ return -ENOMEM;
+
+ ntb->pdev = pdev;
+ ntb->topo = NTB_TOPO_NONE;
+ ntb->ops = &vntb_epf_ops;
ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
if (ret) {
@@ -1341,16 +1351,33 @@ static int pci_vntb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return ret;
}
- ret = ntb_register_device(&ndev->ntb);
+ ret = ntb_register_device(ntb);
if (ret) {
dev_err(dev, "Failed to register NTB device\n");
return ret;
}
+ /* Publish after ntb_register_device() succeeds */
+ smp_store_release(&ndev->ntb, ntb);
+ queue_delayed_work(kpcintb_workqueue, &ndev->cmd_handler, 0);
+
dev_dbg(dev, "PCI Virtual NTB driver loaded\n");
return 0;
}
+static void pci_vntb_remove(struct pci_dev *pdev)
+{
+ struct epf_ntb *ndev = pdev->sysdata;
+ struct ntb_dev *ntb;
+
+ /* Stop the work reader */
+ cancel_delayed_work_sync(&ndev->cmd_handler);
+
+ ntb = xchg(&ndev->ntb, NULL);
+
+ ntb_unregister_device(ntb);
+}
+
static struct pci_device_id pci_vntb_table[] = {
{
PCI_DEVICE(0xffff, 0xffff),
@@ -1362,6 +1389,7 @@ static struct pci_driver vntb_pci_driver = {
.name = "pci-vntb",
.id_table = pci_vntb_table,
.probe = pci_vntb_probe,
+ .remove = pci_vntb_remove,
};
/* ============ PCIe EPF Driver Bind ====================*/
@@ -1442,12 +1470,25 @@ static int epf_ntb_bind(struct pci_epf *epf)
*/
static void epf_ntb_unbind(struct pci_epf *epf)
{
+ struct pci_host_bridge *bridge;
struct epf_ntb *ntb = epf_get_drvdata(epf);
+ pci_unregister_driver(&vntb_pci_driver);
+
+ if (ntb->vpci_bus) {
+ bridge = to_pci_host_bridge(ntb->vpci_bus->bridge);
+
+ pci_lock_rescan_remove();
+ pci_stop_root_bus(ntb->vpci_bus);
+ pci_remove_root_bus(ntb->vpci_bus);
+ ntb->vpci_bus = NULL;
+ pci_unlock_rescan_remove();
+
+ pci_free_host_bridge(bridge);
+ }
+
epf_ntb_epc_cleanup(ntb);
epf_ntb_config_spad_bar_free(ntb);
-
- pci_unregister_driver(&vntb_pci_driver);
}
// EPF driver probe
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 489/686] platform: int3472: discrete: Support multiple HIDs per GPIO map entry
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (487 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 488/686] PCI: endpoint: pci-epf-vntb: Manage virtual NTB and PCI bus lifetime Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 490/686] platform/x86: int3472: Increase handshake GPIO delay to 200 ms Greg Kroah-Hartman
` (196 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, linux-media, Sakari Ailus,
Tarang Raval, Kate Hsuan, Hans de Goede, Daniel Scally,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tarang Raval <tarang.raval@siliconsignals.io>
[ Upstream commit edd0dd59aca038b7f32cf893170928d4a3b2297e ]
Each int3472_gpio_map entry currently maps exactly one ACPI HID to a
GPIO quirk. As more sensors needing the same quirk are identified, this
means adding a full duplicate table entry per HID, differing only in
the HID string, which does not scale.
Change int3472_gpio_map::hid to a NULL-terminated hids array so a
single entry can match any number of ACPI HIDs, letting new HIDs be
added to the relevant array instead of duplicating quirk entries.
Cc: linux-media@vger.kernel.org
Suggested-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
Tested-by: Kate Hsuan <hpa@redhat.com>
Reviewed-by: Kate Hsuan <hpa@redhat.com>
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Daniel Scally <dan.scally@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Keep the consolidated vana mapping for SONY471A and TBE20A0, which
were not previously listed, so the subsequent handshake-delay fix applies
unchanged. Perform the HID scan in the existing GPIO mapping routine
instead of introducing a separate matching helper.
Stable-dep-of: 844982d3b993 ("platform/x86: int3472: Increase handshake GPIO delay to 200 ms")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/intel/int3472/discrete.c | 45 ++++++++++++++++---
1 file changed, 39 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
index 96c33ba80002f..a4c24f1cd0a4d 100644
--- a/drivers/platform/x86/intel/int3472/discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -123,10 +123,31 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472,
return desc;
}
+/*
+ * Other vana-supply users (e.g. ST, Toshiba, Sony sensors) can be added to
+ * this array instead of adding new quirk table entries.
+ */
+static const char * const power_enable_hids_vana[] = {
+ "SONY471A", /* imx471 on Lenovo X9-14 and X9-15 */
+ "TBE20A0", /* imx471 on Lenovo X1 Carbon G14 */
+ NULL
+};
+
+static const char * const power_enable_hids_vdd[] = {
+ "INT33F0", /* mt9m114 */
+ NULL
+};
+
+static const char * const power_enable_hids_enable[] = {
+ "INT347E", /* ov7251 */
+ NULL
+};
+
/**
* struct int3472_gpio_map - Map GPIOs to whatever is expected by the
* sensor driver (as in DT bindings)
- * @hid: The ACPI HID of the device without the instance number e.g. INT347E
+ * @hids: NULL-terminated array of ACPI HIDs of the devices without the
+ * instance number e.g. INT347E
* @type_from: The GPIO type from ACPI ?SDT
* @type_to: The assigned GPIO type, typically same as @type_from
* @enable_time_us: Enable time in usec for GPIOs mapped to regulators
@@ -135,7 +156,7 @@ skl_int3472_gpiod_get_from_temp_lookup(struct int3472_discrete_device *int3472,
* GPIO_ACTIVE_HIGH otherwise
*/
struct int3472_gpio_map {
- const char *hid;
+ const char * const *hids;
u8 type_from;
u8 type_to;
bool polarity_low;
@@ -145,25 +166,32 @@ struct int3472_gpio_map {
static const struct int3472_gpio_map int3472_gpio_map[] = {
{ /* mt9m114 designs declare a powerdown pin which controls the regulators */
- .hid = "INT33F0",
+ .hids = power_enable_hids_vdd,
.type_from = INT3472_GPIO_TYPE_POWERDOWN,
.type_to = INT3472_GPIO_TYPE_POWER_ENABLE,
.con_id = "vdd",
.enable_time_us = GPIO_REGULATOR_ENABLE_TIME,
},
{ /* ov7251 driver / DT-bindings expect "enable" as con_id for reset */
- .hid = "INT347E",
+ .hids = power_enable_hids_enable,
.type_from = INT3472_GPIO_TYPE_RESET,
.type_to = INT3472_GPIO_TYPE_RESET,
.con_id = "enable",
},
{ /* ov08x40's handshake pin needs a 45 ms delay on some HP laptops */
- .hid = "OVTI08F4",
+ .hids = (const char * const[]) { "OVTI08F4", NULL },
.type_from = INT3472_GPIO_TYPE_HANDSHAKE,
.type_to = INT3472_GPIO_TYPE_HANDSHAKE,
.con_id = "dvdd",
.enable_time_us = 45 * USEC_PER_MSEC,
},
+ { /* Sensors which expect "vana" as con_id for power enable */
+ .hids = power_enable_hids_vana,
+ .type_from = INT3472_GPIO_TYPE_POWER_ENABLE,
+ .type_to = INT3472_GPIO_TYPE_POWER_ENABLE,
+ .con_id = "vana",
+ .enable_time_us = GPIO_REGULATOR_ENABLE_TIME,
+ },
};
static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3472, u8 *type,
@@ -171,6 +199,7 @@ static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3
unsigned int *enable_time_us)
{
struct acpi_device *adev = int3472->sensor;
+ const char * const *hids;
unsigned int i;
for (i = 0; i < ARRAY_SIZE(int3472_gpio_map); i++) {
@@ -182,7 +211,11 @@ static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3
if (*type != int3472_gpio_map[i].type_from)
continue;
- if (!acpi_dev_hid_uid_match(adev, int3472_gpio_map[i].hid, NULL))
+ for (hids = int3472_gpio_map[i].hids; *hids; hids++) {
+ if (acpi_dev_hid_uid_match(adev, *hids, NULL))
+ break;
+ }
+ if (!*hids)
continue;
dev_dbg(int3472->dev, "mapping type 0x%02x pin to 0x%02x %s\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 490/686] platform/x86: int3472: Increase handshake GPIO delay to 200 ms
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (488 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 489/686] platform: int3472: discrete: Support multiple HIDs per GPIO map entry Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 491/686] KVM: guest_memfd: Split bind() into prepare()+commit() phases Greg Kroah-Hartman
` (195 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Alexander, Hans de Goede,
Sakari Ailus, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <johannes.goede@oss.qualcomm.com>
[ Upstream commit 844982d3b99340c21dd2125f44e1ad04ace6a38e ]
There have been several reports of the sensor not properly powering on,
on laptops where an INT3472 handshake GPIO is used. Both with ov08x40 and
hi556 sensors.
Testing has shown that a delay of 200 ms is necessary in some cases.
The handshake GPIO is typically used to signal an extra bridge or other IC
with that IC running the full sensor power sequence based on the handshake
signal and also possible controlling I2C pass-through.
It seems that in some cases that extra IC takes up to 200 ms to before
the sensor is fully powered up and ready for I2C communication.
With the default handshake signal delay increased to 200 ms the quirk to
increase it to 45 ms for the ov08x40 is no longer necessary and is actually
undesirable since some ov08x40 setups also need the longer delay, drop it.
Fixes: 30359c239ba8 ("platform/x86: int3472: Increase ov08x40 handshake GPIO delay to 45 ms")
Closes: https://lore.kernel.org/platform-driver-x86/20260816204247.2844986-1-opensource@inspiredexperts.com/
Reported-by: James Alexander <opensource@inspiredexperts.com>
Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2333331
Closes: https://bugzilla.redhat.com/show_bug.cgi?id=2333647
Cc: stable@vger.kernel.org
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/intel/int3472/discrete.c | 12 +++---------
1 file changed, 3 insertions(+), 9 deletions(-)
diff --git a/drivers/platform/x86/intel/int3472/discrete.c b/drivers/platform/x86/intel/int3472/discrete.c
index a4c24f1cd0a4d..6ebfaa141a42d 100644
--- a/drivers/platform/x86/intel/int3472/discrete.c
+++ b/drivers/platform/x86/intel/int3472/discrete.c
@@ -15,6 +15,7 @@
#include <linux/platform_data/x86/int3472.h>
#include <linux/platform_device.h>
#include <linux/string_choices.h>
+#include <linux/time64.h>
#include <linux/uuid.h>
/*
@@ -178,13 +179,6 @@ static const struct int3472_gpio_map int3472_gpio_map[] = {
.type_to = INT3472_GPIO_TYPE_RESET,
.con_id = "enable",
},
- { /* ov08x40's handshake pin needs a 45 ms delay on some HP laptops */
- .hids = (const char * const[]) { "OVTI08F4", NULL },
- .type_from = INT3472_GPIO_TYPE_HANDSHAKE,
- .type_to = INT3472_GPIO_TYPE_HANDSHAKE,
- .con_id = "dvdd",
- .enable_time_us = 45 * USEC_PER_MSEC,
- },
{ /* Sensors which expect "vana" as con_id for power enable */
.hids = power_enable_hids_vana,
.type_from = INT3472_GPIO_TYPE_POWER_ENABLE,
@@ -259,8 +253,8 @@ static void int3472_get_con_id_and_polarity(struct int3472_discrete_device *int3
case INT3472_GPIO_TYPE_HANDSHAKE:
*con_id = "dvdd";
*gpio_flags = GPIO_ACTIVE_HIGH;
- /* Setups using a handshake pin need 25 ms enable delay */
- *enable_time_us = 25 * USEC_PER_MSEC;
+ /* Powering up the sensor through the handshake pin takes up to 200 ms */
+ *enable_time_us = 200 * USEC_PER_MSEC;
break;
default:
*con_id = "unknown";
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 491/686] KVM: guest_memfd: Split bind() into prepare()+commit() phases
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (489 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 490/686] platform/x86: int3472: Increase handshake GPIO delay to 200 ms Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 492/686] iio: light: isl29028: remove isl29028_set_pm_runtime_busy() helper Greg Kroah-Hartman
` (194 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Hildenbrand (Arm),
Sean Christopherson, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 83411f32b8ad96c6b05b1511d1a588daab44bd25 ]
Split binding a memslot to a guest_memfd instance into prepare() and
commit() phases so that KVM can separate preparing the memslot from binding
the memslot to the gmem instance, i.e. from committing the memslot. This
will allow waiting to commit the memslot+gmem binding until the memslot is
fully prepared, which is necessary as the memslot becomes reachable when
the binding is created.
As a bonus, drop the unwind-on-failure from the commit phase (other than
nullifying the bindings), as the only reason bind() did the full unwind is
because it technically didn't own the memslot, i.e. "needed" to leave
memslot in the same state it started in.
No functional change intended (the unwinding down on bind() failure was
effectively dead code since KVM simply deletes the memslot on failure,
i.e. there was nothing that could actually observe the unwind).
Cc: stable@vger.kernel.org
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Link: https://patch.msgid.link/20260922001332.1121266-5-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
[ sashal: adapted guest-memory interfaces to the existing header layout and u64/struct kvm_gmem types ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
virt/kvm/guest_memfd.c | 67 ++++++++++++++++++++++++------------------
virt/kvm/kvm_main.c | 18 +++++++++++-
virt/kvm/kvm_mm.h | 18 ++++++++----
3 files changed, 69 insertions(+), 34 deletions(-)
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 5f9a25fa0a09b..74f7b7ee28793 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -563,15 +563,14 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args)
return __kvm_gmem_create(kvm, size, flags);
}
-int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
- unsigned int fd, u64 offset)
+int kvm_gmem_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot *slot,
+ unsigned int fd, u64 offset)
{
u64 size = slot->npages << PAGE_SHIFT;
- unsigned long start, end;
struct kvm_gmem *gmem;
struct inode *inode;
struct file *file;
- int r = -EINVAL;
+
BUILD_BUG_ON(sizeof(gpa_t) != sizeof(offset));
BUILD_BUG_ON(sizeof(gfn_t) != sizeof(slot->gmem.pgoff));
@@ -595,43 +594,55 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
if (!PAGE_ALIGNED(offset) || offset + size > i_size_read(inode))
goto err;
- filemap_invalidate_lock(inode->i_mapping);
-
- start = offset >> PAGE_SHIFT;
- end = start + slot->npages;
-
- if (!xa_empty(&gmem->bindings) &&
- xa_find(&gmem->bindings, &start, end - 1, XA_PRESENT)) {
- filemap_invalidate_unlock(inode->i_mapping);
- goto err;
- }
-
/*
* memslots of flag KVM_MEM_GUEST_MEMFD are immutable to change, so
* kvm_gmem_bind() must occur on a new memslot. Because the memslot
* is not visible yet, kvm_gmem_get_pfn() is guaranteed to see the file.
*/
WRITE_ONCE(slot->gmem.file, file);
- slot->gmem.pgoff = start;
+ slot->gmem.pgoff = offset >> PAGE_SHIFT;
if (kvm_gmem_supports_mmap(inode))
slot->flags |= KVM_MEMSLOT_GMEM_ONLY;
- r = xa_err(xa_store_range(&gmem->bindings, start, end - 1, slot, GFP_KERNEL));
- if (r) {
- xa_store_range(&gmem->bindings, start, end - 1, NULL, GFP_KERNEL);
- slot->gmem.file = NULL;
- slot->gmem.pgoff = 0;
- slot->flags &= ~KVM_MEMSLOT_GMEM_ONLY;
- }
- filemap_invalidate_unlock(inode->i_mapping);
-
/*
- * Drop the reference to the file, even on success. The file pins KVM,
- * not the other way 'round. Active bindings are invalidated if the
- * file is closed before memslots are destroyed.
+ * Gift the caller a reference to the file. The reference will be
+ * dropped after bindings are established, or if installing the new
+ * memslot ultimately fails.
*/
+ return 0;
+
err:
fput(file);
+ return -EINVAL;
+}
+
+int kvm_gmem_commit_memory_region(struct kvm *kvm, struct kvm_memory_slot *slot)
+{
+ struct kvm_gmem *gmem = slot->gmem.file->private_data;
+ struct inode *inode = file_inode(slot->gmem.file);
+ unsigned long start, end;
+ int r;
+
+ if (WARN_ON_ONCE(slot->gmem.file->f_op != &kvm_gmem_fops))
+ return -EIO;
+
+ filemap_invalidate_lock(inode->i_mapping);
+
+ start = slot->gmem.pgoff;
+ end = start + slot->npages;
+
+ if (!xa_empty(&gmem->bindings) &&
+ xa_find(&gmem->bindings, &start, end - 1, XA_PRESENT)) {
+ filemap_invalidate_unlock(inode->i_mapping);
+ return -EEXIST;
+ }
+
+ r = xa_err(xa_store_range(&gmem->bindings, start, end - 1, slot, GFP_KERNEL));
+ if (r)
+ xa_store_range(&gmem->bindings, start, end - 1, NULL, GFP_KERNEL);
+
+ filemap_invalidate_unlock(inode->i_mapping);
+
return r;
}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 5521743d6e8cb..2354a4097dec4 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2128,7 +2128,23 @@ static int kvm_set_memory_region(struct kvm *kvm,
new->flags = mem->flags;
new->userspace_addr = mem->userspace_addr;
if (change == KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD)) {
- r = kvm_gmem_bind(kvm, new, mem->guest_memfd, mem->guest_memfd_offset);
+ r = kvm_gmem_prepare_memory_region(kvm, new, mem->guest_memfd,
+ mem->guest_memfd_offset);
+ if (r)
+ goto out;
+
+ r = kvm_gmem_commit_memory_region(kvm, new);
+
+ /*
+ * Drop the reference to the file, even on success. The file
+ * pins KVM, not the other way 'round. Active bindings are
+ * invalidated if the file is closed before memslots are
+ * destroyed.
+ */
+#ifdef CONFIG_KVM_GUEST_MEMFD
+ fput(new->gmem.file);
+#endif
+
if (r)
goto out;
}
diff --git a/virt/kvm/kvm_mm.h b/virt/kvm/kvm_mm.h
index 0e68675a8a630..9db0a64d9d541 100644
--- a/virt/kvm/kvm_mm.h
+++ b/virt/kvm/kvm_mm.h
@@ -73,8 +73,9 @@ static inline void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm,
#ifdef CONFIG_KVM_GUEST_MEMFD
void kvm_gmem_init(struct module *module);
int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args);
-int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
- unsigned int fd, u64 offset);
+int kvm_gmem_prepare_memory_region(struct kvm *kvm, struct kvm_memory_slot *slot,
+ unsigned int fd, u64 offset);
+int kvm_gmem_commit_memory_region(struct kvm *kvm, struct kvm_memory_slot *slot);
void kvm_gmem_unbind(struct kvm_memory_slot *slot);
#else
static inline void kvm_gmem_init(struct module *module)
@@ -82,9 +83,16 @@ static inline void kvm_gmem_init(struct module *module)
}
-static inline int kvm_gmem_bind(struct kvm *kvm,
- struct kvm_memory_slot *slot,
- unsigned int fd, u64 offset)
+static inline int kvm_gmem_prepare_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
+ unsigned int fd, u64 offset)
+{
+ WARN_ON_ONCE(1);
+ return -EIO;
+}
+
+static inline int kvm_gmem_commit_memory_region(struct kvm *kvm,
+ struct kvm_memory_slot *slot)
{
WARN_ON_ONCE(1);
return -EIO;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 492/686] iio: light: isl29028: remove isl29028_set_pm_runtime_busy() helper
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (490 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 491/686] KVM: guest_memfd: Split bind() into prepare()+commit() phases Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 493/686] iio: light: isl29028: fix runtime PM reference leak on error paths Greg Kroah-Hartman
` (193 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jonathan Cameron, Sang-Heon Jeon,
Brian Masney, Jonathan Cameron, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Heon Jeon <ekffu200098@gmail.com>
[ Upstream commit 7f61f41a3f5e8f9aa6c264833504995c89712cfc ]
isl29028_set_pm_runtime_busy() just calls pm_runtime_resume_and_get()
or pm_runtime_put_autosuspend() depending on its bool argument. Call
them directly and remove the helper.
No functional change.
Suggested-by: Jonathan Cameron <jic23@kernel.org>
Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Stable-dep-of: 0e30d15b1564 ("iio: light: isl29028: fix runtime PM reference leak on error paths")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/light/isl29028.c | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/drivers/iio/light/isl29028.c b/drivers/iio/light/isl29028.c
index f89c5d9ee5240..7590efcf8dedb 100644
--- a/drivers/iio/light/isl29028.c
+++ b/drivers/iio/light/isl29028.c
@@ -333,16 +333,6 @@ static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
return isl29028_read_als_ir(chip, ir_data);
}
-static int isl29028_set_pm_runtime_busy(struct isl29028_chip *chip, bool on)
-{
- struct device *dev = regmap_get_device(chip->regmap);
-
- if (on)
- return pm_runtime_resume_and_get(dev);
-
- return pm_runtime_put_autosuspend(dev);
-}
-
/* Channel IO */
static int isl29028_write_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
@@ -352,7 +342,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
struct device *dev = regmap_get_device(chip->regmap);
int ret;
- ret = isl29028_set_pm_runtime_busy(chip, true);
+ ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
@@ -405,7 +395,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
if (ret < 0)
return ret;
- ret = isl29028_set_pm_runtime_busy(chip, false);
+ ret = pm_runtime_put_autosuspend(dev);
if (ret < 0)
return ret;
@@ -420,7 +410,7 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
struct device *dev = regmap_get_device(chip->regmap);
int ret, pm_ret;
- ret = isl29028_set_pm_runtime_busy(chip, true);
+ ret = pm_runtime_resume_and_get(dev);
if (ret < 0)
return ret;
@@ -476,10 +466,10 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
/**
* Preserve the ret variable if the call to
- * isl29028_set_pm_runtime_busy() is successful so the reading
+ * pm_runtime_put_autosuspend() is successful so the reading
* (if applicable) is returned to user space.
*/
- pm_ret = isl29028_set_pm_runtime_busy(chip, false);
+ pm_ret = pm_runtime_put_autosuspend(dev);
if (pm_ret < 0)
return pm_ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 493/686] iio: light: isl29028: fix runtime PM reference leak on error paths
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (491 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 492/686] iio: light: isl29028: remove isl29028_set_pm_runtime_busy() helper Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 494/686] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Greg Kroah-Hartman
` (192 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joshua Crofts, Fabio Cesari,
Jonathan Cameron, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Cesari <fabio.cesari@gmail.com>
[ Upstream commit 0e30d15b15647df786e60022650613e16dd70645 ]
isl29028_read_raw() and isl29028_write_raw() take a runtime PM reference
with pm_runtime_resume_and_get() but return directly on their error
paths without dropping it. The usage count never balances again and the
device stops entering autosuspend for good. In isl29028_read_raw() this
needs a regmap access to fail; in isl29028_write_raw() one rejected
sysfs write is enough, for example
echo 200 > in_proximity_sampling_frequency
which is outside the [1:100] range and returns -EINVAL with the
reference still held.
Take the reference with PM_RUNTIME_ACQUIRE_AUTOSUSPEND() instead, so it
is released on every return path.
This also stops the return value of pm_runtime_put_autosuspend() from
reaching userspace. That value only says whether the device could be
suspended right away, so -EAGAIN or -EPERM turns a successful access
into a failure, and with CONFIG_PM=n the stub returns -ENOSYS on every
access.
Fixes: 2db5054ac28d ("staging: iio: isl29028: add runtime power management support")
Suggested-by: Joshua Crofts <joshua.crofts1@gmail.com>
Cc: stable@vger.kernel.org
Assisted-by: LLM coccinelle
Signed-off-by: Fabio Cesari <fabio.cesari@gmail.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/light/isl29028.c | 33 ++++++++-------------------------
1 file changed, 8 insertions(+), 25 deletions(-)
diff --git a/drivers/iio/light/isl29028.c b/drivers/iio/light/isl29028.c
index 7590efcf8dedb..408b32d096a86 100644
--- a/drivers/iio/light/isl29028.c
+++ b/drivers/iio/light/isl29028.c
@@ -342,8 +342,9 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
struct device *dev = regmap_get_device(chip->regmap);
int ret;
- ret = pm_runtime_resume_and_get(dev);
- if (ret < 0)
+ PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev, pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret)
return ret;
mutex_lock(&chip->lock);
@@ -392,14 +393,7 @@ static int isl29028_write_raw(struct iio_dev *indio_dev,
mutex_unlock(&chip->lock);
- if (ret < 0)
- return ret;
-
- ret = pm_runtime_put_autosuspend(dev);
- if (ret < 0)
- return ret;
-
- return 0;
+ return ret;
}
static int isl29028_read_raw(struct iio_dev *indio_dev,
@@ -408,10 +402,11 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
{
struct isl29028_chip *chip = iio_priv(indio_dev);
struct device *dev = regmap_get_device(chip->regmap);
- int ret, pm_ret;
+ int ret;
- ret = pm_runtime_resume_and_get(dev);
- if (ret < 0)
+ PM_RUNTIME_ACQUIRE_AUTOSUSPEND(dev, pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret)
return ret;
mutex_lock(&chip->lock);
@@ -461,18 +456,6 @@ static int isl29028_read_raw(struct iio_dev *indio_dev,
mutex_unlock(&chip->lock);
- if (ret < 0)
- return ret;
-
- /**
- * Preserve the ret variable if the call to
- * pm_runtime_put_autosuspend() is successful so the reading
- * (if applicable) is returned to user space.
- */
- pm_ret = pm_runtime_put_autosuspend(dev);
- if (pm_ret < 0)
- return pm_ret;
-
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 494/686] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (492 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 493/686] iio: light: isl29028: fix runtime PM reference leak on error paths Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 495/686] KVM: arm64: ptdump: Check the page tables arent freed when accessing Greg Kroah-Hartman
` (191 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Fuad Tabba,
Vincent Donnefort, Marc Zyngier, Sasha Levin
6.18-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>
[ sashal: Adapted upstream kvm_s2_fault_desc and kvm_s2_fault_vma_info usage to existing gmem_abort() arguments and local variables. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/mmu.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index af50fed5b5975..e8029ac82da74 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -1536,6 +1536,8 @@ static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (ret)
return ret;
+ fault_ipa = ALIGN_DOWN(fault_ipa, PAGE_SIZE);
+
if (nested)
gfn = kvm_s2_trans_output(nested) >> PAGE_SHIFT;
else
@@ -1552,7 +1554,7 @@ static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
ret = kvm_gmem_get_pfn(kvm, memslot, gfn, &pfn, &page, NULL);
if (ret) {
- kvm_prepare_memory_fault_exit(vcpu, fault_ipa, PAGE_SIZE,
+ kvm_prepare_memory_fault_exit(vcpu, gfn_to_gpa(gfn), PAGE_SIZE,
write_fault, exec_fault, false);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 495/686] KVM: arm64: ptdump: Check the page tables arent freed when accessing
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (493 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 494/686] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 496/686] media: microchip-isc: store the unshifted PFE_CFG0 BPS value Greg Kroah-Hartman
` (190 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko AI, Vincent Donnefort,
Itaru Kitayama, Wei-Lin Chang, Marc Zyngier, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wei-Lin Chang <weilin.chang@arm.com>
[ Upstream commit 7d7199bdf77a3a6ed74d0037133f435a7febe97c ]
An open debugfs file keeps the KVM structure alive, but does not prevent
mmu notifier release from freeing the stage-2 page tables when the VMM’s
address space is torn down. Therefore page tables belonging to the mmus
could have been freed when a thread opens or reads the ptdump files.
Take the mmu_lock and check mmu->pgt is still alive before accessing the
page tables.
Also for the ipa_range file and stage2_levels file, switch from keeping
the pointer to the page tables to keeping the pointer to the mmu.
Fixes: 7c4f73548ed1 ("KVM: arm64: Register ptdump with debugfs on guest creation")
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/kvmarm/20260623144054.B91D21F000E9@smtp.kernel.org/
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Tested-by: Vincent Donnefort <vdonnefort@google.com>
Tested-by: Itaru Kitayama <itaru.kitayama@fujitsu.com>
Signed-off-by: Wei-Lin Chang <weilin.chang@arm.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260924094951.727352-2-weilin.chang@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
[ sashal: copied ia_bits alongside start_level under mmu_lock to accommodate parser initialization during open ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/ptdump.c | 50 +++++++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/kvm/ptdump.c b/arch/arm64/kvm/ptdump.c
index dc5acfb00af91..8e4966194be49 100644
--- a/arch/arm64/kvm/ptdump.c
+++ b/arch/arm64/kvm/ptdump.c
@@ -97,22 +97,35 @@ static struct kvm_ptdump_guest_state *kvm_ptdump_parser_create(struct kvm *kvm)
{
struct kvm_ptdump_guest_state *st;
struct kvm_s2_mmu *mmu = &kvm->arch.mmu;
- struct kvm_pgtable *pgtable = mmu->pgt;
+ s8 start_level;
+ u32 ia_bits;
int ret;
+ /*
+ * We only need the pgt start level and IPA size to initialize the ptdump,
+ * get them while holding the mmu_lock. It's fine if the pgt gets freed
+ * afterwards, we'll check again when doing the actual dump.
+ */
+ scoped_guard(read_lock, &kvm->mmu_lock) {
+ if (!mmu->pgt)
+ return ERR_PTR(-ENOENT);
+ start_level = mmu->pgt->start_level;
+ ia_bits = mmu->pgt->ia_bits;
+ }
+
st = kzalloc(sizeof(struct kvm_ptdump_guest_state), GFP_KERNEL_ACCOUNT);
if (!st)
return ERR_PTR(-ENOMEM);
- ret = kvm_ptdump_build_levels(&st->level[0], pgtable->start_level);
+ ret = kvm_ptdump_build_levels(&st->level[0], start_level);
if (ret) {
kfree(st);
return ERR_PTR(ret);
}
st->ipa_marker[0].name = "Guest IPA";
- st->ipa_marker[1].start_address = BIT(pgtable->ia_bits);
- st->range[0].end = BIT(pgtable->ia_bits);
+ st->ipa_marker[1].start_address = BIT(ia_bits);
+ st->range[0].end = BIT(ia_bits);
st->kvm = kvm;
st->parser_state = (struct ptdump_pg_state) {
@@ -141,9 +154,11 @@ static int kvm_ptdump_guest_show(struct seq_file *m, void *unused)
parser_state->seq = m;
- write_lock(&kvm->mmu_lock);
+ guard(write_lock)(&kvm->mmu_lock);
+ if (!mmu->pgt)
+ return 0;
+
ret = kvm_pgtable_walk(mmu->pgt, 0, BIT(mmu->pgt->ia_bits), &walker);
- write_unlock(&kvm->mmu_lock);
return ret;
}
@@ -193,17 +208,27 @@ static const struct file_operations kvm_ptdump_guest_fops = {
static int kvm_pgtable_range_show(struct seq_file *m, void *unused)
{
- struct kvm_pgtable *pgtable = m->private;
+ struct kvm_s2_mmu *mmu = m->private;
+ struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
+
+ guard(read_lock)(&kvm->mmu_lock);
+
+ if (mmu->pgt)
+ seq_printf(m, "%2u\n", mmu->pgt->ia_bits);
- seq_printf(m, "%2u\n", pgtable->ia_bits);
return 0;
}
static int kvm_pgtable_levels_show(struct seq_file *m, void *unused)
{
- struct kvm_pgtable *pgtable = m->private;
+ struct kvm_s2_mmu *mmu = m->private;
+ struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
+
+ guard(read_lock)(&kvm->mmu_lock);
+
+ if (mmu->pgt)
+ seq_printf(m, "%1d\n", KVM_PGTABLE_MAX_LEVELS - mmu->pgt->start_level);
- seq_printf(m, "%1d\n", KVM_PGTABLE_MAX_LEVELS - pgtable->start_level);
return 0;
}
@@ -211,15 +236,12 @@ static int kvm_pgtable_debugfs_open(struct inode *m, struct file *file,
int (*show)(struct seq_file *, void *))
{
struct kvm *kvm = m->i_private;
- struct kvm_pgtable *pgtable;
int ret;
if (!kvm_get_kvm_safe(kvm))
return -ENOENT;
- pgtable = kvm->arch.mmu.pgt;
-
- ret = single_open(file, show, pgtable);
+ ret = single_open(file, show, &kvm->arch.mmu);
if (ret < 0)
kvm_put_kvm(kvm);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 496/686] media: microchip-isc: store the unshifted PFE_CFG0 BPS value
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (494 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 495/686] KVM: arm64: ptdump: Check the page tables arent freed when accessing Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 497/686] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo Greg Kroah-Hartman
` (189 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eugen Hristev, Balakrishnan Sambath,
Hans Verkuil, Sasha Levin
6.18-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: bb96c78c5f87 ("media: microchip-isc: fix SBGGR10 Bayer pattern")
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 85cd86bed7ba9..963d5fd53b589 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 166f57e6ed5d7..cabecf128b37a 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] 687+ messages in thread
* [PATCH 6.18 497/686] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (495 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 496/686] media: microchip-isc: store the unshifted PFE_CFG0 BPS value Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 498/686] media: microchip-isc: fix SBGGR10 Bayer pattern Greg Kroah-Hartman
` (188 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Balakrishnan Sambath, Eugen Hristev,
Hans Verkuil, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 498/686] media: microchip-isc: fix SBGGR10 Bayer pattern
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (496 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 497/686] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 499/686] media: i2c: imx219: Replace exposure magic value with named constant Greg Kroah-Hartman
` (187 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Balakrishnan Sambath, Eugen Hristev,
Hans Verkuil, Sasha Levin
6.18-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] 687+ messages in thread
* [PATCH 6.18 499/686] media: i2c: imx219: Replace exposure magic value with named constant
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (497 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 498/686] media: microchip-isc: fix SBGGR10 Bayer pattern Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 500/686] media: imx219: Account rate_factor in setting upper exposure limit Greg Kroah-Hartman
` (186 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tarang Raval, Dave Stevenson,
Kieran Bingham, Sakari Ailus, Hans Verkuil, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tarang Raval <tarang.raval@siliconsignals.io>
[ Upstream commit 9a9ba098e7ba6b89efaddeabf0716a84a0f54c99 ]
Introduce IMX219_EXPOSURE_OFFSET (4) and use it instead of the literal
'4' when computing the maximum coarse exposure. The IMX219 datasheet
specifies the maximum storage time as frame_length_lines - 4.
(Ref: Datasheet section 5-7-1)
Also fix one indentation issue for consistency.
Signed-off-by: Tarang Raval <tarang.raval@siliconsignals.io>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Stable-dep-of: 57043aef0a04 ("media: imx219: Account for rate_factor in control steps")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/imx219.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index 76e65cedbb32f..4160a482fdce3 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -68,6 +68,7 @@
#define IMX219_EXPOSURE_STEP 1
#define IMX219_EXPOSURE_DEFAULT 0x640
#define IMX219_EXPOSURE_MAX 65535
+#define IMX219_EXPOSURE_OFFSET 4
/* V_TIMING internal */
#define IMX219_REG_FRM_LENGTH_A CCI_REG16(0x0160)
@@ -461,9 +462,9 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
int exposure_max, exposure_def;
/* Update max exposure while meeting expected vblanking */
- exposure_max = format->height + ctrl->val - 4;
+ exposure_max = format->height + ctrl->val - IMX219_EXPOSURE_OFFSET;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
- exposure_max : IMX219_EXPOSURE_DEFAULT;
+ exposure_max : IMX219_EXPOSURE_DEFAULT;
ret = __v4l2_ctrl_modify_range(imx219->exposure,
imx219->exposure->minimum,
exposure_max,
@@ -591,9 +592,9 @@ static int imx219_init_controls(struct imx219 *imx219)
IMX219_LLP_MAX - mode->width,
IMX219_LLP_STEP,
IMX219_LLP_MIN - mode->width);
- exposure_max = mode->fll_def - 4;
+ exposure_max = mode->fll_def - IMX219_EXPOSURE_OFFSET;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
- exposure_max : IMX219_EXPOSURE_DEFAULT;
+ exposure_max : IMX219_EXPOSURE_DEFAULT;
imx219->exposure = v4l2_ctrl_new_std(ctrl_hdlr, &imx219_ctrl_ops,
V4L2_CID_EXPOSURE,
IMX219_EXPOSURE_MIN, exposure_max,
@@ -912,9 +913,9 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
return ret;
/* Update max exposure while meeting expected vblanking */
- exposure_max = mode->fll_def - 4;
+ exposure_max = mode->fll_def - IMX219_EXPOSURE_OFFSET;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
- exposure_max : IMX219_EXPOSURE_DEFAULT;
+ exposure_max : IMX219_EXPOSURE_DEFAULT;
ret = __v4l2_ctrl_modify_range(imx219->exposure,
imx219->exposure->minimum,
exposure_max,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 500/686] media: imx219: Account rate_factor in setting upper exposure limit
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (498 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 499/686] media: i2c: imx219: Replace exposure magic value with named constant Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 501/686] media: imx219: Account for rate_factor in control steps Greg Kroah-Hartman
` (185 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sakari Ailus, Dave Stevenson,
Laurent Pinchart, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <sakari.ailus@linux.intel.com>
[ Upstream commit db111b66f2db7f3f79d9359f4a9762e832d6fde9 ]
The rate_factor multiplier is used to multiply a few values in the
sensor's timing configuration and the exposure time is one of them. This
also needs to be taken into account in exposure time margin: multiply it
by rate_factor so that sensor's exposure time margin is respected.
Fixes: f513997119f4 ("media: i2c: imx219: Scale the pixel rate for analog binning")
Cc: stable@vger.kernel.org
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Stable-dep-of: 57043aef0a04 ("media: imx219: Account for rate_factor in control steps")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/imx219.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index 4160a482fdce3..87c4d8942135c 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -462,7 +462,8 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
int exposure_max, exposure_def;
/* Update max exposure while meeting expected vblanking */
- exposure_max = format->height + ctrl->val - IMX219_EXPOSURE_OFFSET;
+ exposure_max = format->height + ctrl->val -
+ IMX219_EXPOSURE_OFFSET * rate_factor;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
exposure_max : IMX219_EXPOSURE_DEFAULT;
ret = __v4l2_ctrl_modify_range(imx219->exposure,
@@ -895,6 +896,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
crop->top = (IMX219_NATIVE_HEIGHT - crop->height) / 2;
if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+ int rate_factor = imx219_get_rate_factor(state);
int exposure_max;
int exposure_def;
int hblank, llp_min;
@@ -913,7 +915,8 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
return ret;
/* Update max exposure while meeting expected vblanking */
- exposure_max = mode->fll_def - IMX219_EXPOSURE_OFFSET;
+ exposure_max = mode->fll_def -
+ IMX219_EXPOSURE_OFFSET * rate_factor;
exposure_def = (exposure_max < IMX219_EXPOSURE_DEFAULT) ?
exposure_max : IMX219_EXPOSURE_DEFAULT;
ret = __v4l2_ctrl_modify_range(imx219->exposure,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 501/686] media: imx219: Account for rate_factor in control steps
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (499 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 500/686] media: imx219: Account rate_factor in setting upper exposure limit Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 502/686] media: iris: Fix iova allocation from restrict region Greg Kroah-Hartman
` (184 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sakari Ailus, Dave Stevenson,
Laurent Pinchart, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <sakari.ailus@linux.intel.com>
[ Upstream commit 57043aef0a04bd96d97881422590e71c1e4c45b1 ]
The controls that are divided by the rate_factor before writing them to
the registers have the step of the value of the rate_factor. Take this
into account when the control's range is modified. The controls are
created in a configuration where rate_factor is always 1, hence there's no
need to change the code adding new controls.
Fixes: f513997119f4 ("media: i2c: imx219: Scale the pixel rate for analog binning")
Cc: stable@vger.kernel.org
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/imx219.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/drivers/media/i2c/imx219.c b/drivers/media/i2c/imx219.c
index 87c4d8942135c..e399a87f99266 100644
--- a/drivers/media/i2c/imx219.c
+++ b/drivers/media/i2c/imx219.c
@@ -326,13 +326,13 @@ static const struct imx219_mode supported_modes[] = {
/* 2x2 binned 60fps mode */
.width = 1640,
.height = 1232,
- .fll_def = 1707,
+ .fll_def = 1706,
},
{
/* 640x480 60fps mode */
.width = 640,
.height = 480,
- .fll_def = 1707,
+ .fll_def = 1706,
},
};
@@ -469,8 +469,7 @@ static int imx219_set_ctrl(struct v4l2_ctrl *ctrl)
ret = __v4l2_ctrl_modify_range(imx219->exposure,
imx219->exposure->minimum,
exposure_max,
- imx219->exposure->step,
- exposure_def);
+ rate_factor, exposure_def);
if (ret)
return ret;
@@ -904,7 +903,8 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
/* Update limits and set FPS to default */
ret = __v4l2_ctrl_modify_range(imx219->vblank, IMX219_VBLANK_MIN,
- IMX219_FLL_MAX - mode->height, 1,
+ IMX219_FLL_MAX - mode->height,
+ rate_factor,
mode->fll_def - mode->height);
if (ret)
return ret;
@@ -922,8 +922,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
ret = __v4l2_ctrl_modify_range(imx219->exposure,
imx219->exposure->minimum,
exposure_max,
- imx219->exposure->step,
- exposure_def);
+ rate_factor, exposure_def);
if (ret)
return ret;
@@ -956,8 +955,7 @@ static int imx219_set_pad_format(struct v4l2_subdev *sd,
return ret;
/* Scale the pixel rate based on the mode specific factor */
- pixel_rate = imx219_get_pixel_rate(imx219) *
- imx219_get_rate_factor(state);
+ pixel_rate = imx219_get_pixel_rate(imx219) * rate_factor;
ret = __v4l2_ctrl_modify_range(imx219->pixel_rate, pixel_rate,
pixel_rate, 1, pixel_rate);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 502/686] media: iris: Fix iova allocation from restrict region
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (500 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 501/686] media: imx219: Account for rate_factor in control steps Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 503/686] iio: adc: ad7192: Revert "properly check spi_get_device_match_data()" Greg Kroah-Hartman
` (183 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vikash Garodia, Dmitry Baryshkov,
Vishnu Reddy, Bryan ODonoghue, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
[ Upstream commit 200473c198b201c308dfb916fb3233074d9407fa ]
The VPU issues DMA through several SMMU streams, and the hardware does
not give every stream the same addressable range. The non-pixel stream
cannot address the low 600MB of IOVA space, while the pixel stream can
address the full range:
+-----------------------------------------------------------+
| non-pixel stream addressable range (600 MB - 3.5 GB) |
| 0x25800000 - 0xe0000000 |
+-----------------------------------------------------------+
| pixel stream addressable range (0 - 3.5 GB) |
| 0x00000000 - 0xe0000000 |
+-----------------------------------------------------------+
A single "iommus" property on the video-codec node puts every stream
in one IOMMU domain sharing one IOVA space, so nothing stops a
non-pixel buffer from landing below 600MB. Once an allocation lands
below that boundary the hardware faults, which shows up as unhandled
SMMU page faults and spontaneous reboots.
https://gitlab.freedesktop.org/drm/msm/-/work_items/100
Fix this by reserving the 0-600MB range, below the boundary the
non-pixel stream cannot address, using dma_iova_try_alloc() so the
IOMMU-DMA core never hands that range out to a real DMA mapping. This
reserves only IOVA space, it does not allocate any physical memory.
Since sub-nodes for non-pixel, pixel, and secure streams do not exist
yet and only a single device is available, the restriction is applied
to both non-pixel and pixel stream IDs.
Fixes: d7378f84e94e ("media: iris: introduce iris core state management with shared queues")
Cc: stable@vger.kernel.org
Reviewed-by: Vikash Garodia <vikash.garodia@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
[ sashal: Adjusted iris_probe() context to retain iris_session_init_caps(core) immediately before the IOVA reservation. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/qcom/iris/iris_core.h | 6 ++
drivers/media/platform/qcom/iris/iris_probe.c | 62 ++++++++++++++++++-
2 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_core.h b/drivers/media/platform/qcom/iris/iris_core.h
index fb194c967ad4f..530fe14c3a477 100644
--- a/drivers/media/platform/qcom/iris/iris_core.h
+++ b/drivers/media/platform/qcom/iris/iris_core.h
@@ -7,6 +7,7 @@
#define __IRIS_CORE_H__
#include <linux/types.h>
+#include <linux/dma-mapping.h>
#include <linux/pm_domain.h>
#include <media/v4l2-device.h>
@@ -25,6 +26,9 @@ struct icc_info {
#define IRIS_FW_VERSION_LENGTH 128
#define IFACEQ_CORE_PKT_SIZE (1024 * 4)
+#define IRIS_NP_RESERVE_IOVA_START 0x0
+#define IRIS_NP_RESERVE_IOVA_SIZE 0x25800000
+
enum domain_type {
ENCODER = BIT(0),
DECODER = BIT(1),
@@ -73,6 +77,7 @@ enum domain_type {
* @instances: a list_head of all instances
* @inst_fw_caps_dec: an array of supported instance capabilities by decoder
* @inst_fw_caps_enc: an array of supported instance capabilities by encoder
+ * @iova_state: a pointer to an array of dma_iova_state entries reserved for restricted IOVA region
*/
struct iris_core {
@@ -117,6 +122,7 @@ struct iris_core {
/* encoder and decoder have overlapping caps, so two different arrays are required */
struct platform_inst_fw_cap inst_fw_caps_dec[INST_FW_CAP_MAX];
struct platform_inst_fw_cap inst_fw_caps_enc[INST_FW_CAP_MAX];
+ struct dma_iova_state *iova_state;
};
int iris_core_init(struct iris_core *core);
diff --git a/drivers/media/platform/qcom/iris/iris_probe.c b/drivers/media/platform/qcom/iris/iris_probe.c
index cdeb78ba605ae..b6251493bd9cc 100644
--- a/drivers/media/platform/qcom/iris/iris_probe.c
+++ b/drivers/media/platform/qcom/iris/iris_probe.c
@@ -153,6 +153,57 @@ static int iris_init_resources(struct iris_core *core)
return iris_init_resets(core);
}
+static void iris_unreserve_iova_region(struct device *dev, struct dma_iova_state *iova_state)
+{
+ unsigned int i;
+
+ for (i = 0; dma_iova_size(&iova_state[i]); i++)
+ dma_iova_free(dev, &iova_state[i]);
+}
+
+static int iris_reserve_iova_region(struct device *dev, struct dma_iova_state **iova_state,
+ unsigned long start, unsigned long size)
+{
+ unsigned long dma_limit = dev->bus_dma_limit;
+ unsigned long end, rem, chunk;
+ struct dma_iova_state *state;
+ unsigned int count = 0;
+ int ret = -ENOMEM;
+
+ state = devm_kcalloc(dev, BITS_PER_TYPE(dma_addr_t) + 1, sizeof(*state), GFP_KERNEL);
+ if (!state)
+ return ret;
+
+ end = start + size;
+ rem = end - max(start, PAGE_SIZE);
+ dev->bus_dma_limit = end - 1;
+
+ while (rem) {
+ chunk = min(end & -end, (u64)1 << (fls64(rem) - 1));
+
+ if (!dma_iova_try_alloc(dev, &state[count], 0, chunk))
+ goto err_free_iova;
+
+ if (state[count].addr != end - chunk || state[count].__size != chunk)
+ goto err_free_iova;
+
+ rem -= chunk;
+ end -= chunk;
+ count++;
+ }
+
+ *iova_state = state;
+ dev->bus_dma_limit = dma_limit;
+
+ return 0;
+
+err_free_iova:
+ iris_unreserve_iova_region(dev, state);
+ dev->bus_dma_limit = dma_limit;
+
+ return ret;
+}
+
static int iris_register_video_device(struct iris_core *core, enum domain_type type)
{
struct video_device *vdev;
@@ -210,6 +261,8 @@ static void iris_remove(struct platform_device *pdev)
v4l2_device_unregister(&core->v4l2_dev);
+ iris_unreserve_iova_region(core->dev, core->iova_state);
+
mutex_destroy(&core->lock);
}
@@ -272,10 +325,15 @@ static int iris_probe(struct platform_device *pdev)
iris_session_init_caps(core);
- ret = v4l2_device_register(dev, &core->v4l2_dev);
+ ret = iris_reserve_iova_region(dev, &core->iova_state, IRIS_NP_RESERVE_IOVA_START,
+ IRIS_NP_RESERVE_IOVA_SIZE);
if (ret)
return ret;
+ ret = v4l2_device_register(dev, &core->v4l2_dev);
+ if (ret)
+ goto err_unresv_iova_region;
+
ret = iris_register_video_device(core, DECODER);
if (ret)
goto err_v4l2_unreg;
@@ -309,6 +367,8 @@ static int iris_probe(struct platform_device *pdev)
video_unregister_device(core->vdev_dec);
err_v4l2_unreg:
v4l2_device_unregister(&core->v4l2_dev);
+err_unresv_iova_region:
+ iris_unreserve_iova_region(dev, core->iova_state);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 503/686] iio: adc: ad7192: Revert "properly check spi_get_device_match_data()"
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (501 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 502/686] media: iris: Fix iova allocation from restrict region Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 504/686] iio: adc: ad7192: reject devices without match data Greg Kroah-Hartman
` (182 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harshit Mogalapalli, Andy Shevchenko,
Jonathan Cameron, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 0309e66abea141f3ec339b064b8f8b8003d2a634 ]
This reverts commit b7f99fa1b64af2f696b13cec581cb4cd7d3982b8.
The added code is currently a dead code. Moreover, the driver is not
designed to have any defaults effectively making driver data a mandatory
information to work with. Taking all together, revert unneeded change.
Discussion at #1 concluded in agreeing a new policy on this for IIO.
Link: https://lore.kernel.org/linux-iio/20260217080514.1288115-1-andriy.shevchenko@linux.intel.com/ #1
Reported-by: Harshit Mogalapalli <harshit.m.mogalapalli@oracle.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Stable-dep-of: 7f7a119a370e ("iio: adc: ad7192: reject devices without match data")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/ad7192.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c
index 530e1d307860e..8b1664f6b102c 100644
--- a/drivers/iio/adc/ad7192.c
+++ b/drivers/iio/adc/ad7192.c
@@ -1402,9 +1402,6 @@ static int ad7192_probe(struct spi_device *spi)
st->int_vref_mv = ret == -ENODEV ? avdd_mv : ret / MILLI;
st->chip_info = spi_get_device_match_data(spi);
- if (!st->chip_info)
- return -ENODEV;
-
indio_dev->name = st->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = st->chip_info->info;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 504/686] iio: adc: ad7192: reject devices without match data
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (502 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 503/686] iio: adc: ad7192: Revert "properly check spi_get_device_match_data()" Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 505/686] ALSA: core: Clean up file_operations definitions Greg Kroah-Hartman
` (181 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiale Yao, Jonathan Cameron,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiale Yao <yaojiale02@163.com>
[ Upstream commit 7f7a119a370ecf6c8d4ab9e9ee0a8cdd77afedd3 ]
SPI driver_override allows a device to bind to this driver without
matching either the OF or SPI device ID table. In that case,
spi_get_device_match_data() returns NULL.
ad7192_probe() immediately dereferences the returned chip information
to initialize the IIO device, causing a NULL pointer dereference.
Commit 572a00852635 ("iio: dac: ad5686: missing NULL check on match
data") fixed the same driver_override issue in another SPI driver.
Reject devices without match data before using the chip information.
Fixes: c3708c829a06 ("iio: adc: ad7192: Convert from of specific to fwnode property handling")
Cc: stable@vger.kernel.org
Signed-off-by: Jiale Yao <yaojiale02@163.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/ad7192.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/iio/adc/ad7192.c b/drivers/iio/adc/ad7192.c
index 8b1664f6b102c..394137a127abb 100644
--- a/drivers/iio/adc/ad7192.c
+++ b/drivers/iio/adc/ad7192.c
@@ -1402,6 +1402,9 @@ static int ad7192_probe(struct spi_device *spi)
st->int_vref_mv = ret == -ENODEV ? avdd_mv : ret / MILLI;
st->chip_info = spi_get_device_match_data(spi);
+ if (!st->chip_info)
+ return -ENODATA;
+
indio_dev->name = st->chip_info->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = st->chip_info->info;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 505/686] ALSA: core: Clean up file_operations definitions
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (503 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 504/686] iio: adc: ad7192: reject devices without match data Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 506/686] ALSA: timer: Handle userspace-driven timer ioctls from 32-bit tasks Greg Kroah-Hartman
` (180 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, bui duc phuc, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: bui duc phuc <phucduc.bui@gmail.com>
[ Upstream commit 307835a6eb50e548e58ee604bf91909d4faa4203 ]
Align file_operations initializers with tabs to match the standard
kernel coding style and improve readability.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
Link: https://patch.msgid.link/20260708140624.562403-1-phucduc.bui@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 1bbc033983b7 ("ALSA: timer: Handle userspace-driven timer ioctls from 32-bit tasks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/core/compress_offload.c | 18 +++++++-------
sound/core/control.c | 19 +++++++--------
sound/core/hwdep.c | 23 +++++++++---------
sound/core/init.c | 23 +++++++++---------
sound/core/jack.c | 38 ++++++++++++++---------------
sound/core/oss/mixer_oss.c | 13 +++++-----
sound/core/oss/pcm_oss.c | 21 ++++++++--------
sound/core/pcm_native.c | 44 +++++++++++++++++-----------------
sound/core/rawmidi.c | 16 ++++++-------
sound/core/seq/oss/seq_oss.c | 21 ++++++++--------
sound/core/seq/seq_clientmgr.c | 19 +++++++--------
sound/core/sound.c | 9 ++++---
sound/core/timer.c | 25 ++++++++++---------
13 files changed, 140 insertions(+), 149 deletions(-)
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index e1b2da84f7782..b965eabf96844 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -1399,17 +1399,17 @@ static long snd_compr_ioctl_compat(struct file *file, unsigned int cmd,
#endif
static const struct file_operations snd_compr_file_ops = {
- .owner = THIS_MODULE,
- .open = snd_compr_open,
- .release = snd_compr_free,
- .write = snd_compr_write,
- .read = snd_compr_read,
- .unlocked_ioctl = snd_compr_ioctl,
+ .owner = THIS_MODULE,
+ .open = snd_compr_open,
+ .release = snd_compr_free,
+ .write = snd_compr_write,
+ .read = snd_compr_read,
+ .unlocked_ioctl = snd_compr_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = snd_compr_ioctl_compat,
+ .compat_ioctl = snd_compr_ioctl_compat,
#endif
- .mmap = snd_compr_mmap,
- .poll = snd_compr_poll,
+ .mmap = snd_compr_mmap,
+ .poll = snd_compr_poll,
};
static int snd_compress_dev_register(struct snd_device *device)
diff --git a/sound/core/control.c b/sound/core/control.c
index 1d13352afed2b..750bb3f52d26d 100644
--- a/sound/core/control.c
+++ b/sound/core/control.c
@@ -2269,16 +2269,15 @@ EXPORT_SYMBOL_GPL(snd_ctl_disconnect_layer);
* INIT PART
*/
-static const struct file_operations snd_ctl_f_ops =
-{
- .owner = THIS_MODULE,
- .read = snd_ctl_read,
- .open = snd_ctl_open,
- .release = snd_ctl_release,
- .poll = snd_ctl_poll,
- .unlocked_ioctl = snd_ctl_ioctl,
- .compat_ioctl = snd_ctl_ioctl_compat,
- .fasync = snd_ctl_fasync,
+static const struct file_operations snd_ctl_f_ops = {
+ .owner = THIS_MODULE,
+ .read = snd_ctl_read,
+ .open = snd_ctl_open,
+ .release = snd_ctl_release,
+ .poll = snd_ctl_poll,
+ .unlocked_ioctl = snd_ctl_ioctl,
+ .compat_ioctl = snd_ctl_ioctl_compat,
+ .fasync = snd_ctl_fasync,
};
/* call lops under rwsems; called from snd_ctl_dev_*() below() */
diff --git a/sound/core/hwdep.c b/sound/core/hwdep.c
index 10a32004398ff..4334162bc0b22 100644
--- a/sound/core/hwdep.c
+++ b/sound/core/hwdep.c
@@ -324,18 +324,17 @@ static int snd_hwdep_control_ioctl(struct snd_card *card,
*/
-static const struct file_operations snd_hwdep_f_ops =
-{
- .owner = THIS_MODULE,
- .llseek = snd_hwdep_llseek,
- .read = snd_hwdep_read,
- .write = snd_hwdep_write,
- .open = snd_hwdep_open,
- .release = snd_hwdep_release,
- .poll = snd_hwdep_poll,
- .unlocked_ioctl = snd_hwdep_ioctl,
- .compat_ioctl = snd_hwdep_ioctl_compat,
- .mmap = snd_hwdep_mmap,
+static const struct file_operations snd_hwdep_f_ops = {
+ .owner = THIS_MODULE,
+ .llseek = snd_hwdep_llseek,
+ .read = snd_hwdep_read,
+ .write = snd_hwdep_write,
+ .open = snd_hwdep_open,
+ .release = snd_hwdep_release,
+ .poll = snd_hwdep_poll,
+ .unlocked_ioctl = snd_hwdep_ioctl,
+ .compat_ioctl = snd_hwdep_ioctl_compat,
+ .mmap = snd_hwdep_mmap,
};
static void snd_hwdep_free(struct snd_hwdep *hwdep)
diff --git a/sound/core/init.c b/sound/core/init.c
index 2bf98de846f61..779729738b128 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -461,20 +461,19 @@ static int snd_disconnect_fasync(int fd, struct file *file, int on)
return -ENODEV;
}
-static const struct file_operations snd_shutdown_f_ops =
-{
- .owner = THIS_MODULE,
- .llseek = snd_disconnect_llseek,
- .read = snd_disconnect_read,
- .write = snd_disconnect_write,
- .release = snd_disconnect_release,
- .poll = snd_disconnect_poll,
- .unlocked_ioctl = snd_disconnect_ioctl,
+static const struct file_operations snd_shutdown_f_ops = {
+ .owner = THIS_MODULE,
+ .llseek = snd_disconnect_llseek,
+ .read = snd_disconnect_read,
+ .write = snd_disconnect_write,
+ .release = snd_disconnect_release,
+ .poll = snd_disconnect_poll,
+ .unlocked_ioctl = snd_disconnect_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = snd_disconnect_ioctl,
+ .compat_ioctl = snd_disconnect_ioctl,
#endif
- .mmap = snd_disconnect_mmap,
- .fasync = snd_disconnect_fasync
+ .mmap = snd_disconnect_mmap,
+ .fasync = snd_disconnect_fasync
};
/**
diff --git a/sound/core/jack.c b/sound/core/jack.c
index 93e357a23f171..71607d904e061 100644
--- a/sound/core/jack.c
+++ b/sound/core/jack.c
@@ -306,41 +306,41 @@ static ssize_t jack_type_read(struct file *file,
}
static const struct file_operations jack_type_fops = {
- .open = simple_open,
- .read = jack_type_read,
- .llseek = default_llseek,
+ .open = simple_open,
+ .read = jack_type_read,
+ .llseek = default_llseek,
};
#endif
static const struct file_operations sw_inject_enable_fops = {
- .open = simple_open,
- .read = sw_inject_enable_read,
- .write = sw_inject_enable_write,
- .llseek = default_llseek,
+ .open = simple_open,
+ .read = sw_inject_enable_read,
+ .write = sw_inject_enable_write,
+ .llseek = default_llseek,
};
static const struct file_operations jackin_inject_fops = {
- .open = simple_open,
- .write = jackin_inject_write,
- .llseek = default_llseek,
+ .open = simple_open,
+ .write = jackin_inject_write,
+ .llseek = default_llseek,
};
static const struct file_operations jack_kctl_id_fops = {
- .open = simple_open,
- .read = jack_kctl_id_read,
- .llseek = default_llseek,
+ .open = simple_open,
+ .read = jack_kctl_id_read,
+ .llseek = default_llseek,
};
static const struct file_operations jack_kctl_mask_bits_fops = {
- .open = simple_open,
- .read = jack_kctl_mask_bits_read,
- .llseek = default_llseek,
+ .open = simple_open,
+ .read = jack_kctl_mask_bits_read,
+ .llseek = default_llseek,
};
static const struct file_operations jack_kctl_status_fops = {
- .open = simple_open,
- .read = jack_kctl_status_read,
- .llseek = default_llseek,
+ .open = simple_open,
+ .read = jack_kctl_status_read,
+ .llseek = default_llseek,
};
static int snd_jack_debugfs_add_inject_node(struct snd_jack *jack,
diff --git a/sound/core/oss/mixer_oss.c b/sound/core/oss/mixer_oss.c
index aa98caaaea3c5..a7d66ea7c795d 100644
--- a/sound/core/oss/mixer_oss.c
+++ b/sound/core/oss/mixer_oss.c
@@ -407,13 +407,12 @@ static long snd_mixer_oss_ioctl_compat(struct file *file, unsigned int cmd,
* REGISTRATION PART
*/
-static const struct file_operations snd_mixer_oss_f_ops =
-{
- .owner = THIS_MODULE,
- .open = snd_mixer_oss_open,
- .release = snd_mixer_oss_release,
- .unlocked_ioctl = snd_mixer_oss_ioctl,
- .compat_ioctl = snd_mixer_oss_ioctl_compat,
+static const struct file_operations snd_mixer_oss_f_ops = {
+ .owner = THIS_MODULE,
+ .open = snd_mixer_oss_open,
+ .release = snd_mixer_oss_release,
+ .unlocked_ioctl = snd_mixer_oss_ioctl,
+ .compat_ioctl = snd_mixer_oss_ioctl_compat,
};
/*
diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c
index 59d5153d11132..6d49451b730cd 100644
--- a/sound/core/oss/pcm_oss.c
+++ b/sound/core/oss/pcm_oss.c
@@ -3120,17 +3120,16 @@ static inline void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
* ENTRY functions
*/
-static const struct file_operations snd_pcm_oss_f_reg =
-{
- .owner = THIS_MODULE,
- .read = snd_pcm_oss_read,
- .write = snd_pcm_oss_write,
- .open = snd_pcm_oss_open,
- .release = snd_pcm_oss_release,
- .poll = snd_pcm_oss_poll,
- .unlocked_ioctl = snd_pcm_oss_ioctl,
- .compat_ioctl = snd_pcm_oss_ioctl_compat,
- .mmap = snd_pcm_oss_mmap,
+static const struct file_operations snd_pcm_oss_f_reg = {
+ .owner = THIS_MODULE,
+ .read = snd_pcm_oss_read,
+ .write = snd_pcm_oss_write,
+ .open = snd_pcm_oss_open,
+ .release = snd_pcm_oss_release,
+ .poll = snd_pcm_oss_poll,
+ .unlocked_ioctl = snd_pcm_oss_ioctl,
+ .compat_ioctl = snd_pcm_oss_ioctl_compat,
+ .mmap = snd_pcm_oss_mmap,
};
static void register_oss_dsp(struct snd_pcm *pcm, int index)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 304b7e4965e3f..553fad5300e10 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -4228,29 +4228,29 @@ static unsigned long snd_pcm_get_unmapped_area(struct file *file,
const struct file_operations snd_pcm_f_ops[2] = {
{
- .owner = THIS_MODULE,
- .write = snd_pcm_write,
- .write_iter = snd_pcm_writev,
- .open = snd_pcm_playback_open,
- .release = snd_pcm_release,
- .poll = snd_pcm_poll,
- .unlocked_ioctl = snd_pcm_ioctl,
- .compat_ioctl = snd_pcm_ioctl_compat,
- .mmap = snd_pcm_mmap,
- .fasync = snd_pcm_fasync,
- .get_unmapped_area = snd_pcm_get_unmapped_area,
+ .owner = THIS_MODULE,
+ .write = snd_pcm_write,
+ .write_iter = snd_pcm_writev,
+ .open = snd_pcm_playback_open,
+ .release = snd_pcm_release,
+ .poll = snd_pcm_poll,
+ .unlocked_ioctl = snd_pcm_ioctl,
+ .compat_ioctl = snd_pcm_ioctl_compat,
+ .mmap = snd_pcm_mmap,
+ .fasync = snd_pcm_fasync,
+ .get_unmapped_area = snd_pcm_get_unmapped_area,
},
{
- .owner = THIS_MODULE,
- .read = snd_pcm_read,
- .read_iter = snd_pcm_readv,
- .open = snd_pcm_capture_open,
- .release = snd_pcm_release,
- .poll = snd_pcm_poll,
- .unlocked_ioctl = snd_pcm_ioctl,
- .compat_ioctl = snd_pcm_ioctl_compat,
- .mmap = snd_pcm_mmap,
- .fasync = snd_pcm_fasync,
- .get_unmapped_area = snd_pcm_get_unmapped_area,
+ .owner = THIS_MODULE,
+ .read = snd_pcm_read,
+ .read_iter = snd_pcm_readv,
+ .open = snd_pcm_capture_open,
+ .release = snd_pcm_release,
+ .poll = snd_pcm_poll,
+ .unlocked_ioctl = snd_pcm_ioctl,
+ .compat_ioctl = snd_pcm_ioctl_compat,
+ .mmap = snd_pcm_mmap,
+ .fasync = snd_pcm_fasync,
+ .get_unmapped_area = snd_pcm_get_unmapped_area,
}
};
diff --git a/sound/core/rawmidi.c b/sound/core/rawmidi.c
index 7508d99c1e441..63c8978c98750 100644
--- a/sound/core/rawmidi.c
+++ b/sound/core/rawmidi.c
@@ -1784,14 +1784,14 @@ static void snd_rawmidi_proc_info_read(struct snd_info_entry *entry,
*/
static const struct file_operations snd_rawmidi_f_ops = {
- .owner = THIS_MODULE,
- .read = snd_rawmidi_read,
- .write = snd_rawmidi_write,
- .open = snd_rawmidi_open,
- .release = snd_rawmidi_release,
- .poll = snd_rawmidi_poll,
- .unlocked_ioctl = snd_rawmidi_ioctl,
- .compat_ioctl = snd_rawmidi_ioctl_compat,
+ .owner = THIS_MODULE,
+ .read = snd_rawmidi_read,
+ .write = snd_rawmidi_write,
+ .open = snd_rawmidi_open,
+ .release = snd_rawmidi_release,
+ .poll = snd_rawmidi_poll,
+ .unlocked_ioctl = snd_rawmidi_ioctl,
+ .compat_ioctl = snd_rawmidi_ioctl_compat,
};
static int snd_rawmidi_alloc_substreams(struct snd_rawmidi *rmidi,
diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
index 02d30d8b6c3a8..4ecb43b6ad3ba 100644
--- a/sound/core/seq/oss/seq_oss.c
+++ b/sound/core/seq/oss/seq_oss.c
@@ -206,17 +206,16 @@ odev_poll(struct file *file, poll_table * wait)
* registration of sequencer minor device
*/
-static const struct file_operations seq_oss_f_ops =
-{
- .owner = THIS_MODULE,
- .read = odev_read,
- .write = odev_write,
- .open = odev_open,
- .release = odev_release,
- .poll = odev_poll,
- .unlocked_ioctl = odev_ioctl,
- .compat_ioctl = odev_ioctl_compat,
- .llseek = noop_llseek,
+static const struct file_operations seq_oss_f_ops = {
+ .owner = THIS_MODULE,
+ .read = odev_read,
+ .write = odev_write,
+ .open = odev_open,
+ .release = odev_release,
+ .poll = odev_poll,
+ .unlocked_ioctl = odev_ioctl,
+ .compat_ioctl = odev_ioctl_compat,
+ .llseek = noop_llseek,
};
static int __init
diff --git a/sound/core/seq/seq_clientmgr.c b/sound/core/seq/seq_clientmgr.c
index e73c1becb6e15..9a92a37602586 100644
--- a/sound/core/seq/seq_clientmgr.c
+++ b/sound/core/seq/seq_clientmgr.c
@@ -2661,16 +2661,15 @@ void snd_seq_info_clients_read(struct snd_info_entry *entry,
* REGISTRATION PART
*/
-static const struct file_operations snd_seq_f_ops =
-{
- .owner = THIS_MODULE,
- .read = snd_seq_read,
- .write = snd_seq_write,
- .open = snd_seq_open,
- .release = snd_seq_release,
- .poll = snd_seq_poll,
- .unlocked_ioctl = snd_seq_ioctl,
- .compat_ioctl = snd_seq_ioctl_compat,
+static const struct file_operations snd_seq_f_ops = {
+ .owner = THIS_MODULE,
+ .read = snd_seq_read,
+ .write = snd_seq_write,
+ .open = snd_seq_open,
+ .release = snd_seq_release,
+ .poll = snd_seq_poll,
+ .unlocked_ioctl = snd_seq_ioctl,
+ .compat_ioctl = snd_seq_ioctl_compat,
};
static struct device *seq_dev;
diff --git a/sound/core/sound.c b/sound/core/sound.c
index 7980b60f4ba0b..5ce042db47559 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -167,11 +167,10 @@ static int snd_open(struct inode *inode, struct file *file)
return err;
}
-static const struct file_operations snd_fops =
-{
- .owner = THIS_MODULE,
- .open = snd_open,
- .llseek = noop_llseek,
+static const struct file_operations snd_fops = {
+ .owner = THIS_MODULE,
+ .open = snd_open,
+ .llseek = noop_llseek,
};
#ifdef CONFIG_SND_DYNAMIC_MINORS
diff --git a/sound/core/timer.c b/sound/core/timer.c
index c5f0e895ea024..9838cc6636427 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -2101,9 +2101,9 @@ static long snd_utimer_ioctl(struct file *file, unsigned int ioctl, unsigned lon
}
static const struct file_operations snd_utimer_fops = {
- .llseek = noop_llseek,
- .release = snd_utimer_release,
- .unlocked_ioctl = snd_utimer_ioctl,
+ .llseek = noop_llseek,
+ .release = snd_utimer_release,
+ .unlocked_ioctl = snd_utimer_ioctl,
};
static int snd_utimer_start(struct snd_timer *t)
@@ -2455,16 +2455,15 @@ static __poll_t snd_timer_user_poll(struct file *file, poll_table * wait)
#define snd_timer_user_ioctl_compat NULL
#endif
-static const struct file_operations snd_timer_f_ops =
-{
- .owner = THIS_MODULE,
- .read = snd_timer_user_read,
- .open = snd_timer_user_open,
- .release = snd_timer_user_release,
- .poll = snd_timer_user_poll,
- .unlocked_ioctl = snd_timer_user_ioctl,
- .compat_ioctl = snd_timer_user_ioctl_compat,
- .fasync = snd_timer_user_fasync,
+static const struct file_operations snd_timer_f_ops = {
+ .owner = THIS_MODULE,
+ .read = snd_timer_user_read,
+ .open = snd_timer_user_open,
+ .release = snd_timer_user_release,
+ .poll = snd_timer_user_poll,
+ .unlocked_ioctl = snd_timer_user_ioctl,
+ .compat_ioctl = snd_timer_user_ioctl_compat,
+ .fasync = snd_timer_user_fasync,
};
/* unregister the system timer */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 506/686] ALSA: timer: Handle userspace-driven timer ioctls from 32-bit tasks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (504 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 505/686] ALSA: core: Clean up file_operations definitions Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 507/686] ALSA: usb-audio: keep MIDI input running for Roland TD-11 Greg Kroah-Hartman
` (179 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Danish Khateeb, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danish Khateeb <danishkhateeb03@gmail.com>
[ Upstream commit 1bbc033983b76f41d51d4a48838bf94c5e6b6f50 ]
32-bit tasks on a 64-bit kernel can't use userspace-driven timers. The
compat handler for /dev/snd/timer doesn't list SNDRV_TIMER_IOCTL_CREATE,
so creating a timer fails with -ENOTTY. The file returned for a timer
has no .compat_ioctl either, so SNDRV_TIMER_IOCTL_TRIGGER fails with
-ENOTTY too.
struct snd_timer_uinfo has the same layout for 32-bit and 64-bit tasks,
and SNDRV_TIMER_IOCTL_TRIGGER takes no argument, so both commands can
be passed through unchanged.
The utimer selftest doesn't catch this when built with -m32: it takes
-ENOTTY from SNDRV_TIMER_IOCTL_CREATE to mean CONFIG_SND_UTIMER=n and
skips.
Fixes: 37745918e0e7 ("ALSA: timer: Introduce virtual userspace-driven timers")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Danish Khateeb <danishkhateeb03@gmail.com>
Link: https://patch.msgid.link/20260928182352.309457-1-danishkhateeb03@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/core/timer.c | 1 +
sound/core/timer_compat.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/sound/core/timer.c b/sound/core/timer.c
index 9838cc6636427..64bffc21295d4 100644
--- a/sound/core/timer.c
+++ b/sound/core/timer.c
@@ -2104,6 +2104,7 @@ static const struct file_operations snd_utimer_fops = {
.llseek = noop_llseek,
.release = snd_utimer_release,
.unlocked_ioctl = snd_utimer_ioctl,
+ .compat_ioctl = snd_utimer_ioctl,
};
static int snd_utimer_start(struct snd_timer *t)
diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
index 4ae9eaeb5afb1..7b648edcb9cba 100644
--- a/sound/core/timer_compat.c
+++ b/sound/core/timer_compat.c
@@ -98,6 +98,7 @@ static long __snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd,
case SNDRV_TIMER_IOCTL_PAUSE:
case SNDRV_TIMER_IOCTL_PAUSE_OLD:
case SNDRV_TIMER_IOCTL_NEXT_DEVICE:
+ case SNDRV_TIMER_IOCTL_CREATE:
return __snd_timer_user_ioctl(file, cmd, (unsigned long)argp, true);
case SNDRV_TIMER_IOCTL_GPARAMS32:
return snd_timer_user_gparams_compat(file, argp);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 507/686] ALSA: usb-audio: keep MIDI input running for Roland TD-11
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (505 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 506/686] ALSA: timer: Handle userspace-driven timer ioctls from 32-bit tasks Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 508/686] ALSA: usb-audio: Protect Roland control activation Greg Kroah-Hartman
` (178 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Hobson, Takashi Iwai,
Sasha Levin
6.18-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 787956252e800..30d0684920319 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;
};
@@ -1168,7 +1169,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) {
@@ -2258,6 +2259,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;
@@ -2465,7 +2470,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);
@@ -2640,6 +2645,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] 687+ messages in thread
* [PATCH 6.18 508/686] ALSA: usb-audio: Protect Roland control activation
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (506 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 507/686] ALSA: usb-audio: keep MIDI input running for Roland TD-11 Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 509/686] hwmon: (tmp102) Fix jiffies wraparound in conversion-ready check Greg Kroah-Hartman
` (177 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Takashi Iwai,
Sasha Levin
6.18-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 30d0684920319..c404412ae53b9 100644
--- a/sound/usb/midi.c
+++ b/sound/usb/midi.c
@@ -1146,41 +1146,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] 687+ messages in thread
* [PATCH 6.18 509/686] hwmon: (tmp102) Fix jiffies wraparound in conversion-ready check
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (507 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 508/686] ALSA: usb-audio: Protect Roland control activation Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 510/686] gfs2: reject invalid inode sizes Greg Kroah-Hartman
` (176 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Verdonck, Guenter Roeck,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Verdonck <tom.verdonck@inspiral.be>
[ Upstream commit 56c1d32323e773b8b927316f8beeae9238576335 ]
tmp102 records a one-shot deadline in ->ready_time at probe (and resume)
and, on every temperature read, refuses the read with -EAGAIN while
time_before(jiffies, ready_time) is true, in order to skip the first
~35 ms conversion.
->ready_time is an unsigned long compared with time_before(), whose
signed difference is only meaningful while the two values are within
LONG_MAX jiffies of each other. Because ->ready_time is set once and
never refreshed, jiffies keeps advancing away from it, and after 2^31
jiffies the difference flips sign. On a 32-bit HZ=100 kernel that
happens ~248.5 days after boot: time_before() then permanently reports
"not ready" and the driver returns -EAGAIN on every read, without ever
touching the sensor, until the next reboot.
Store the deadline as a 64-bit jiffies value and compare it with
get_jiffies_64()/time_before64(), which does not wrap in any practical
uptime.
Fixes: 3d8f7a89a197 ("hwmon: (tmp102) Improve handling of initial read delay")
Cc: stable@vger.kernel.org
Signed-off-by: Tom Verdonck <tom.verdonck@inspiral.be>
Link: https://patch.msgid.link/2952f070f82913aea96eec25d28008d3b9058656.1790358356.git.tom.verdonck@inspiral.be
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
[ sashal: Adjusted struct tmp102 context to account for the missing sample_time field. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/tmp102.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c
index 376e0eac8cc1c..62a7bee9e4b95 100644
--- a/drivers/hwmon/tmp102.c
+++ b/drivers/hwmon/tmp102.c
@@ -56,7 +56,7 @@ struct tmp102 {
const char *label;
struct regmap *regmap;
u16 config_orig;
- unsigned long ready_time;
+ u64 ready_time;
};
/* convert left adjusted 13-bit TMP102 register value to milliCelsius */
@@ -91,7 +91,7 @@ static int tmp102_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_before(jiffies, tmp102->ready_time)) {
+ if (time_before64(get_jiffies_64(), tmp102->ready_time)) {
dev_dbg(dev, "%s: Conversion not ready yet..\n", __func__);
return -EAGAIN;
}
@@ -270,7 +270,7 @@ static int tmp102_probe(struct i2c_client *client)
* Mark that we are not ready with data until the first
* conversion is complete
*/
- tmp102->ready_time = jiffies + msecs_to_jiffies(CONVERSION_TIME_MS);
+ tmp102->ready_time = get_jiffies_64() + msecs_to_jiffies(CONVERSION_TIME_MS);
hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name,
tmp102,
@@ -303,7 +303,7 @@ static int tmp102_resume(struct device *dev)
err = regmap_update_bits(tmp102->regmap, TMP102_CONF_REG,
TMP102_CONF_SD, 0);
- tmp102->ready_time = jiffies + msecs_to_jiffies(CONVERSION_TIME_MS);
+ tmp102->ready_time = get_jiffies_64() + msecs_to_jiffies(CONVERSION_TIME_MS);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 510/686] gfs2: reject invalid inode sizes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (508 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 509/686] hwmon: (tmp102) Fix jiffies wraparound in conversion-ready check Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 511/686] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams Greg Kroah-Hartman
` (175 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiaming Zhang, Andreas Gruenbacher,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiaming Zhang <r772577952@gmail.com>
[ Upstream commit 33ed0a0567e0abe66ea65e89dad2e35082890fbe ]
A corrupted GFS2 image can store a dinode size that is larger than what VFS
i_size can represent. gfs2_dinode_in() reads the on-disk di_size as a u64 and
writes it directly into inode->i_size. If the value is larger than S64_MAX, the
incore i_size becomes negative. That negative value can bypass the existing
stuffed inode size check:
inode->i_size > gfs2_max_stuffed_size(ip)
Later, gfs2_quotad may try to sync the quota file and unstuff the quota inode.
gfs2_unstuffer_folio() reads the negative i_size into an unsigned length and
passes it to memcpy(), turning it into a huge copy size and triggering a
out-of-bound issue.
Reject dinodes whose size exceeds sb->s_maxbytes before storing the value in
inode->i_size. Also make the stuffed inode check use the raw on-disk size while
it is still unsigned.
Fixes: 70376c7ff312 ("gfs2: Always check inode size of inline inodes")
Closes: https://lore.kernel.org/lkml/CANypQFaF6bvORKKbRALvEL0k_epFaneFiOQqco4gjdmKVbdURg@mail.gmail.com/
Assisted-by: Codex:gpt-5.5-xhigh
Cc: stable@vger.kernel.org
Signed-off-by: Jiaming Zhang <r772577952@gmail.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
[ sashal: adjusted context for direct inode->i_state access and the absent adjacent directory-consistency check ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/gfs2/glops.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index 242e47926b39d..35ad44d13e8b6 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -392,6 +392,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
umode_t mode = be32_to_cpu(str->di_mode);
struct inode *inode = &ip->i_inode;
bool is_new = inode->i_state & I_NEW;
+ u64 size;
if (unlikely(ip->i_no_addr != be64_to_cpu(str->di_num.no_addr))) {
gfs2_consist_inode(ip);
@@ -417,7 +418,12 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
i_uid_write(inode, be32_to_cpu(str->di_uid));
i_gid_write(inode, be32_to_cpu(str->di_gid));
set_nlink(inode, be32_to_cpu(str->di_nlink));
- i_size_write(inode, be64_to_cpu(str->di_size));
+ size = be64_to_cpu(str->di_size);
+ if (unlikely(size > inode->i_sb->s_maxbytes)) {
+ gfs2_consist_inode(ip);
+ return -EIO;
+ }
+ i_size_write(inode, size);
gfs2_set_inode_blocks(inode, be64_to_cpu(str->di_blocks));
atime.tv_sec = be64_to_cpu(str->di_atime);
atime.tv_nsec = be32_to_cpu(str->di_atime_nsec);
@@ -456,7 +462,7 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
ip->i_depth = (u8)depth;
ip->i_entries = be32_to_cpu(str->di_entries);
- if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip)) {
+ if (gfs2_is_stuffed(ip) && size > gfs2_max_stuffed_size(ip)) {
gfs2_consist_inode(ip);
return -EIO;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 511/686] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (509 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 510/686] gfs2: reject invalid inode sizes Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 512/686] media: i2c: og01a1b: power off sensor on remove Greg Kroah-Hartman
` (174 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vladimir Zapolskiy, Sakari Ailus,
Mauro Carvalho Chehab, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
[ Upstream commit 3a594bb454ba1ecb005f753007fa1bb5c5e68bae ]
The change allows to simplify the driver code, in particular the explicit
locking scheme for stream on/off or format update serialization can be
dropped in favour to the one provided by the V4L2 core internals.
Signed-off-by: Vladimir Zapolskiy <vladimir.zapolskiy@linaro.org>
[Sakari Ailus: Fix error handling for enable_streams callback.]
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Stable-dep-of: a26c5ac46191 ("media: i2c: og01a1b: power off sensor on remove")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/og01a1b.c | 90 ++++++++++++++-----------------------
1 file changed, 34 insertions(+), 56 deletions(-)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index 7b892b26203c0..4b6b9ac24594b 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -442,9 +442,6 @@ struct og01a1b {
/* Current mode */
const struct og01a1b_mode *cur_mode;
-
- /* To serialize asynchronus callbacks */
- struct mutex mutex;
};
static u64 to_pixel_rate(u32 f_index)
@@ -616,7 +613,6 @@ static int og01a1b_init_controls(struct og01a1b *og01a1b)
if (ret)
return ret;
- ctrl_hdlr->lock = &og01a1b->mutex;
og01a1b->link_freq = v4l2_ctrl_new_int_menu(ctrl_hdlr,
&og01a1b_ctrl_ops,
V4L2_CID_LINK_FREQ,
@@ -686,74 +682,66 @@ static void og01a1b_update_pad_format(const struct og01a1b_mode *mode,
fmt->field = V4L2_FIELD_NONE;
}
-static int og01a1b_start_streaming(struct og01a1b *og01a1b)
+static int og01a1b_enable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
+ struct og01a1b *og01a1b = to_og01a1b(sd);
+ unsigned int link_freq_index = og01a1b->cur_mode->link_freq_index;
const struct og01a1b_reg_list *reg_list;
- int link_freq_index, ret;
+ int ret;
- link_freq_index = og01a1b->cur_mode->link_freq_index;
- reg_list = &link_freq_configs[link_freq_index].reg_list;
+ ret = pm_runtime_resume_and_get(og01a1b->dev);
+ if (ret)
+ return ret;
+ reg_list = &link_freq_configs[link_freq_index].reg_list;
ret = og01a1b_write_reg_list(og01a1b, reg_list);
if (ret) {
- dev_err(og01a1b->dev, "failed to set plls");
- return ret;
+ dev_err(og01a1b->dev, "failed to set plls: %d\n", ret);
+ goto error;
}
reg_list = &og01a1b->cur_mode->reg_list;
ret = og01a1b_write_reg_list(og01a1b, reg_list);
if (ret) {
- dev_err(og01a1b->dev, "failed to set mode");
- return ret;
+ dev_err(og01a1b->dev, "failed to set mode: %d\n", ret);
+ goto error;
}
ret = __v4l2_ctrl_handler_setup(og01a1b->sd.ctrl_handler);
if (ret)
- return ret;
+ goto error;
ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
OG01A1B_REG_VALUE_08BIT,
OG01A1B_MODE_STREAMING);
if (ret) {
- dev_err(og01a1b->dev, "failed to set stream");
- return ret;
+ dev_err(og01a1b->dev, "failed to start streaming: %d\n", ret);
+ goto error;
}
return 0;
-}
-static void og01a1b_stop_streaming(struct og01a1b *og01a1b)
-{
- if (og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
- OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY))
- dev_err(og01a1b->dev, "failed to set stream");
+error:
+ pm_runtime_put_autosuspend(og01a1b->dev);
+
+ return ret;
}
-static int og01a1b_set_stream(struct v4l2_subdev *sd, int enable)
+static int og01a1b_disable_streams(struct v4l2_subdev *sd,
+ struct v4l2_subdev_state *state, u32 pad,
+ u64 streams_mask)
{
struct og01a1b *og01a1b = to_og01a1b(sd);
- int ret = 0;
-
- mutex_lock(&og01a1b->mutex);
- if (enable) {
- ret = pm_runtime_resume_and_get(og01a1b->dev);
- if (ret) {
- mutex_unlock(&og01a1b->mutex);
- return ret;
- }
+ int ret;
- ret = og01a1b_start_streaming(og01a1b);
- if (ret) {
- enable = 0;
- og01a1b_stop_streaming(og01a1b);
- pm_runtime_put(og01a1b->dev);
- }
- } else {
- og01a1b_stop_streaming(og01a1b);
- pm_runtime_put(og01a1b->dev);
- }
+ ret = og01a1b_write_reg(og01a1b, OG01A1B_REG_MODE_SELECT,
+ OG01A1B_REG_VALUE_08BIT, OG01A1B_MODE_STANDBY);
+ if (ret)
+ dev_err(og01a1b->dev, "failed to stop streaming: %d\n", ret);
- mutex_unlock(&og01a1b->mutex);
+ pm_runtime_put_autosuspend(og01a1b->dev);
return ret;
}
@@ -771,7 +759,6 @@ static int og01a1b_set_format(struct v4l2_subdev *sd,
height, fmt->format.width,
fmt->format.height);
- mutex_lock(&og01a1b->mutex);
og01a1b_update_pad_format(mode, &fmt->format);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
*v4l2_subdev_state_get_format(sd_state, fmt->pad) = fmt->format;
@@ -794,8 +781,6 @@ static int og01a1b_set_format(struct v4l2_subdev *sd,
h_blank);
}
- mutex_unlock(&og01a1b->mutex);
-
return 0;
}
@@ -805,15 +790,12 @@ static int og01a1b_get_format(struct v4l2_subdev *sd,
{
struct og01a1b *og01a1b = to_og01a1b(sd);
- mutex_lock(&og01a1b->mutex);
if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
fmt->format = *v4l2_subdev_state_get_format(sd_state,
fmt->pad);
else
og01a1b_update_pad_format(og01a1b->cur_mode, &fmt->format);
- mutex_unlock(&og01a1b->mutex);
-
return 0;
}
@@ -849,18 +831,14 @@ static int og01a1b_enum_frame_size(struct v4l2_subdev *sd,
static int og01a1b_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
- struct og01a1b *og01a1b = to_og01a1b(sd);
-
- mutex_lock(&og01a1b->mutex);
og01a1b_update_pad_format(&supported_modes[0],
v4l2_subdev_state_get_format(fh->state, 0));
- mutex_unlock(&og01a1b->mutex);
return 0;
}
static const struct v4l2_subdev_video_ops og01a1b_video_ops = {
- .s_stream = og01a1b_set_stream,
+ .s_stream = v4l2_subdev_s_stream_helper,
};
static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = {
@@ -868,6 +846,8 @@ static const struct v4l2_subdev_pad_ops og01a1b_pad_ops = {
.get_fmt = og01a1b_get_format,
.enum_mbus_code = og01a1b_enum_mbus_code,
.enum_frame_size = og01a1b_enum_frame_size,
+ .enable_streams = og01a1b_enable_streams,
+ .disable_streams = og01a1b_disable_streams,
};
static const struct v4l2_subdev_ops og01a1b_subdev_ops = {
@@ -1046,7 +1026,6 @@ static void og01a1b_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
pm_runtime_disable(og01a1b->dev);
- mutex_destroy(&og01a1b->mutex);
}
static int og01a1b_probe(struct i2c_client *client)
@@ -1135,7 +1114,6 @@ static int og01a1b_probe(struct i2c_client *client)
goto power_off;
}
- mutex_init(&og01a1b->mutex);
og01a1b->cur_mode = &supported_modes[0];
ret = og01a1b_init_controls(og01a1b);
if (ret) {
@@ -1143,6 +1121,7 @@ static int og01a1b_probe(struct i2c_client *client)
goto probe_error_v4l2_ctrl_handler_free;
}
+ og01a1b->sd.state_lock = og01a1b->ctrl_handler.lock;
og01a1b->sd.internal_ops = &og01a1b_internal_ops;
og01a1b->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
og01a1b->sd.entity.ops = &og01a1b_subdev_entity_ops;
@@ -1183,7 +1162,6 @@ static int og01a1b_probe(struct i2c_client *client)
probe_error_v4l2_ctrl_handler_free:
v4l2_ctrl_handler_free(og01a1b->sd.ctrl_handler);
- mutex_destroy(&og01a1b->mutex);
power_off:
og01a1b_power_off(og01a1b->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 512/686] media: i2c: og01a1b: power off sensor on remove
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (510 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 511/686] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 513/686] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio() Greg Kroah-Hartman
` (173 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Sakari Ailus,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
[ Upstream commit a26c5ac46191ae34b3413f7a45d6241f63e15d42 ]
og01a1b_probe() powers the sensor on explicitly before identifying and
initializing it. After a successful probe, runtime PM is enabled and
pm_runtime_idle() is used to allow the runtime suspend callback to
power the sensor off.
The probe error path explicitly calls og01a1b_power_off(), but the
normal remove path only disables runtime PM. pm_runtime_disable() does
not guarantee that an active device is runtime suspended, so the
sensor can remain powered when the driver is removed. This also leaves
the xvclk enable performed by og01a1b_power_on() unbalanced.
After disabling runtime PM, check whether the device is already
suspended. If it is still active, power the sensor off explicitly and
update the runtime PM state accordingly. Avoid powering it off again
when runtime suspend has already done so.
This issue was found by manual code inspection.
Fixes: a95ffde28783 ("media: i2c: og01a1b: Add support of xvclk supply clock in power management")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/og01a1b.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/media/i2c/og01a1b.c b/drivers/media/i2c/og01a1b.c
index 4b6b9ac24594b..68ebf44876781 100644
--- a/drivers/media/i2c/og01a1b.c
+++ b/drivers/media/i2c/og01a1b.c
@@ -1026,6 +1026,11 @@ static void og01a1b_remove(struct i2c_client *client)
media_entity_cleanup(&sd->entity);
v4l2_ctrl_handler_free(sd->ctrl_handler);
pm_runtime_disable(og01a1b->dev);
+
+ if (!pm_runtime_status_suspended(og01a1b->dev)) {
+ og01a1b_power_off(og01a1b->dev);
+ pm_runtime_set_suspended(og01a1b->dev);
+ }
}
static int og01a1b_probe(struct i2c_client *client)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 513/686] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (511 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 512/686] media: i2c: og01a1b: power off sensor on remove Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 514/686] m68k: Fix task info flags handling for 68000 Greg Kroah-Hartman
` (172 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Zhiguo Niu, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.18-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: used the existing sbi parameter in f2fs_in_warm_node_list() without changing its signature or callers ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/checkpoint.c | 4 ++--
fs/f2fs/data.c | 5 +++--
fs/f2fs/f2fs.h | 8 ++++----
fs/f2fs/gc.c | 2 +-
fs/f2fs/node.c | 16 ++++++++--------
5 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 66d3714dda32a..4c54d75c8981e 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -93,7 +93,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;
}
@@ -439,7 +439,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
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 eba1e025b9d6e..a9a829315c305 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -153,7 +153,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,7 +360,7 @@ static void f2fs_write_end_io(struct bio *bio)
STOP_CP_REASON_WRITE_FAIL);
}
- 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));
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index ec1b9831e5afe..82c3c4ebcb3e6 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -2222,14 +2222,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)
diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c
index e85d7f239e7d0..e3ae70e297c82 100644
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -1418,7 +1418,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 60969e5f1201b..1b67184df3dd6 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -327,7 +327,7 @@ static unsigned int __gang_lookup_nat_set(struct f2fs_nm_info *nm_i,
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)
@@ -1266,7 +1266,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);
}
@@ -1579,7 +1579,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;
}
@@ -1698,7 +1698,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;
@@ -1930,7 +1930,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;
@@ -1988,7 +1988,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;
@@ -2066,7 +2066,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;
@@ -2138,7 +2138,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;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 514/686] m68k: Fix task info flags handling for 68000
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (512 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 513/686] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 515/686] m68k: Fix seccomp filtering on ColdFire and 68000 Greg Kroah-Hartman
` (171 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Plattner, Daniel Palmer,
Greg Ungerer, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Palmer <daniel@0x0f.com>
[ Upstream commit 2c6805145e1605cef39459f78979f7edee251b41 ]
The logic for deciding what to do after a syscall should be checking
if any of the lower byte bits are set and then checking if the reschedule
bit is set.
Currently we are loading the top word, checking if any bits are set
(which never seems to be true) and thus jumping over loading the
whole long and checking if the reschedule bit is set.
We get the thread info in two places so split that logic out in
a macro and then fix the code so that it loads the byte of the flags
we need to check, checks if anything is set and then checks if
the reschedule bit in particular is set.
Reported-by: Christoph Plattner <christoph.plattner@gmx.at>
Signed-off-by: Daniel Palmer <daniel@0x0f.com>
Signed-off-by: Greg Ungerer <gerg@kernel.org>
Stable-dep-of: 48859f8018d9 ("m68k: Fix seccomp filtering on ColdFire and 68000")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/m68k/68000/entry.S | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/arch/m68k/68000/entry.S b/arch/m68k/68000/entry.S
index 72e95663b62ff..c257cc415c478 100644
--- a/arch/m68k/68000/entry.S
+++ b/arch/m68k/68000/entry.S
@@ -18,6 +18,13 @@
.text
+/* get thread_info pointer into a2 */
+ .macro getthreadinfo
+ movel %sp,%d1
+ andl #-THREAD_SIZE,%d1
+ movel %d1,%a2
+ .endm
+
.globl system_call
.globl resume
.globl ret_from_exception
@@ -70,9 +77,8 @@ ENTRY(system_call)
movel %sp@(PT_OFF_ORIG_D0),%d0
- movel %sp,%d1 /* get thread_info pointer */
- andl #-THREAD_SIZE,%d1
- movel %d1,%a2
+ /* Doing a trace ? */
+ getthreadinfo
btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
jne do_trace
cmpl #NR_syscalls,%d0
@@ -96,16 +102,15 @@ Luser_return:
/* heavy interrupt load*/
andw #ALLOWINT,%sr
- movel %sp,%d1 /* get thread_info pointer */
- andl #-THREAD_SIZE,%d1
- movel %d1,%a2
+ getthreadinfo
1:
- move %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
+ /* check if any of the flags are set */
+ moveb %a2@(TINFO_FLAGS + 3),%d1 /* thread_info->flags (low 8 bits) */
jne Lwork_to_do
RESTORE_ALL
Lwork_to_do:
- movel %a2@(TINFO_FLAGS),%d1 /* thread_info->flags */
+ /* check if reschedule needs to be called */
btst #TIF_NEED_RESCHED,%d1
jne reschedule
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 515/686] m68k: Fix seccomp filtering on ColdFire and 68000
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (513 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 514/686] m68k: Fix task info flags handling for 68000 Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 516/686] powerpc/pseries/iommu: Add TCEs for 16GB pages when RAM is pre-mapped Greg Kroah-Hartman
` (170 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andreas Schwab, Christopher Lusk,
Greg Ungerer, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christopher Lusk <clusk@northecho.dev>
[ Upstream commit 48859f8018d93bd93ef35f7430fdf5b97f2f9715 ]
m68k selects HAVE_ARCH_SECCOMP_FILTER for all configurations, but the
ColdFire and 68000 syscall entry paths only branch to
syscall_trace_enter() for TIF_SYSCALL_TRACE. TIF_SECCOMP alone falls
through to syscall dispatch, leaving installed filters ineffective.
Test the combined TIF_SYSCALL_TRACE and TIF_SECCOMP mask in both paths
and route either flag through the existing slow path. Leave the classic
MMU syscall entry implementation unchanged.
Validated the combined test under QEMU mcf5208evb (ColdFire): filters
denying getpid, openat, unlinkat, and reboot each returned -EPERM. A
classic-MMU control (q800) denied the filtered getpid syscall both before
and after this change. The 68000 path shares the same source-level
omission and receives the identical masked test but was not separately
emulated. Compile-tested W=1 with CONFIG_SECCOMP_FILTER=y on both
m5208evb_defconfig and a custom no-MMU UCSIMM configuration; the latter
built arch/m68k/68000/entry.o and vmlinux.
Fixes: 6baaade15594 ("m68k: Add kernel seccomp support")
Cc: stable@vger.kernel.org # v6.3+
Suggested-by: Andreas Schwab <schwab@linux-m68k.org>
Assisted-by: Claude:claude-opus-4-8
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Christopher Lusk <clusk@northecho.dev>
Signed-off-by: Greg Ungerer <gerg@linux-m68k.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/m68k/68000/entry.S | 3 ++-
arch/m68k/coldfire/entry.S | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/m68k/68000/entry.S b/arch/m68k/68000/entry.S
index c257cc415c478..0d3cbededc43c 100644
--- a/arch/m68k/68000/entry.S
+++ b/arch/m68k/68000/entry.S
@@ -79,7 +79,8 @@ ENTRY(system_call)
/* Doing a trace ? */
getthreadinfo
- btst #(TIF_SYSCALL_TRACE%8),%a2@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
+ moveb %a2@(TINFO_FLAGS+2),%d1
+ andl #((_TIF_SYSCALL_TRACE + _TIF_SECCOMP) >> 8),%d1
jne do_trace
cmpl #NR_syscalls,%d0
jcc badsys
diff --git a/arch/m68k/coldfire/entry.S b/arch/m68k/coldfire/entry.S
index 4ea08336e2fb0..d658abdc52075 100644
--- a/arch/m68k/coldfire/entry.S
+++ b/arch/m68k/coldfire/entry.S
@@ -72,7 +72,8 @@ ENTRY(system_call)
movel %d2,%a0
movel %a0@,%a1 /* save top of frame */
movel %sp,%a1@(TASK_THREAD+THREAD_ESP0)
- btst #(TIF_SYSCALL_TRACE%8),%a0@(TINFO_FLAGS+(31-TIF_SYSCALL_TRACE)/8)
+ moveb %a0@(TINFO_FLAGS+2),%d2
+ andl #((_TIF_SYSCALL_TRACE + _TIF_SECCOMP) >> 8),%d2
bnes 1f
movel %d3,%a0
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 516/686] powerpc/pseries/iommu: Add TCEs for 16GB pages when RAM is pre-mapped
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (514 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 515/686] m68k: Fix seccomp filtering on ColdFire and 68000 Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 517/686] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly Greg Kroah-Hartman
` (169 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gaurav Batra, Ritesh Harjani (IBM),
Madhavan Srinivasan, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gaurav Batra <gbatra@linux.ibm.com>
[ Upstream commit 0b8b0c17a8998709ecb2852d56442ea981102941 ]
In powerPC, if Dynamic DMA Window is big enough, RAM is pre-mapped. To
determine the size of RAM, a PAPR+ property "ibm,lrdr-capacity" is used.
This OF property dictates what is the max size of RAM an LPAR can have,
including DR added memory.
In PowerPC, 16GB pages can be allocated at machine level and then
assigned to LPARs. These 16GB pages are added to LPAR memory at the time
of boot. The address range for these 16GB pages is above MAX RAM an LPAR
can have (ibm,lrdr-capacity). In the current implementation, these 16GB
pages are being excluded from pre-mapped TCEs. A driver can have DMA
buffers allocated from 16GB pages. This results in platform to raise an
EEH when DMA is attempted on buffers in 16GB memory range.
commit 6aa989ab2bd0 ("powerpc/pseries/iommu: memory notifier incorrectly
adds TCEs for pmemory")
Prior to the above patch, memblock_end_of_DRAM() was being used to
determine the MAX memory of an LPAR. This included 16GB pages as well.
The issue with using memblock_end_of_DRAM() is that when pmemory is
converted to RAM via daxctl command, the DDW engine will incorrectly try
to add TCEs for pmemory as well.
Below is the address distribution of RAM, 16GB pages and pmemory for an
LPAR with max memory of 256GB, memory allocated 64GB, 2 16GB pages and
assigned pmemory of 8GB.
RANGE SIZE STATE REMOVABLE BLOCK
0x0000000000000000-0x0000000fffffffff 64G online yes 0-255
0x0000004000000000-0x00000047ffffffff 32G online yes 1024-1151
cat /sys/bus/nd/devices/region0/resource
0x40100000000
cat /sys/bus/nd/devices/region0/size
8589934592
The approach to fix this problem is to revert back the code changes
introduced by the above patch and to stash away the MAX memory of an
LPAR, including 16GB pages, at the LPAR boot time. This value is then
used whenever TCEs are needed to be pre-mapped - enable_DDW() or,
iommu_mem_notifier()
Fixes: 6aa989ab2bd0 ("powerpc/pseries/iommu: memory notifier incorrectly adds TCEs for pmemory")
Cc: stable@vger.kernel.org
Signed-off-by: Gaurav Batra <gbatra@linux.ibm.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260806205027.86428-1-gbatra@linux.ibm.com
[ sashal: retained the existing bus_dma_limit condition because the coherent-DMA bypass changes are absent ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/platforms/pseries/iommu.c | 67 +++++++++++++++++---------
1 file changed, 45 insertions(+), 22 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 4bcb6f2220658..aad5200b7bc1c 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -69,6 +69,8 @@ static struct iommu_table *iommu_pseries_alloc_table(int node)
return tbl;
}
+static phys_addr_t pseries_ddw_max_ram __ro_after_init;
+
#ifdef CONFIG_IOMMU_API
static struct iommu_table_group_ops spapr_tce_table_group_ops;
#endif
@@ -1284,15 +1286,19 @@ struct failed_ddw_pdn {
static LIST_HEAD(failed_ddw_pdn_list);
-static phys_addr_t ddw_memory_hotplug_max(void)
+static phys_addr_t __init ddw_memory_hotplug_max(void)
{
- resource_size_t max_addr;
+ resource_size_t max_addr = memory_hotplug_max();
+ struct device_node *memory;
-#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG)
- max_addr = hot_add_drconf_memory_max();
-#else
- max_addr = memblock_end_of_DRAM();
-#endif
+ for_each_node_by_type(memory, "memory") {
+ struct resource res;
+
+ if (of_address_to_resource(memory, 0, &res))
+ continue;
+
+ max_addr = max_t(resource_size_t, max_addr, res.end + 1);
+ }
return max_addr;
}
@@ -1447,7 +1453,7 @@ static struct property *ddw_property_create(const char *propname, u32 liobn, u64
static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mask)
{
int len = 0, ret;
- int max_ram_len = order_base_2(ddw_memory_hotplug_max());
+ int max_ram_len = order_base_2(pseries_ddw_max_ram);
struct ddw_query_response query;
struct ddw_create_response create;
int page_shift;
@@ -1617,12 +1623,12 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mas
if (default_win_removed && pmem_present && !direct_mapping) {
/* DDW is big enough to be split */
if ((1ULL << ddw_sz) >=
- MIN_DDW_VPMEM_DMA_WINDOW + (1ULL << max_ram_len)) {
+ MIN_DDW_VPMEM_DMA_WINDOW + pseries_ddw_max_ram) {
direct_mapping = true;
/* offset of the Dynamic part of DDW */
- dynamic_offset = 1ULL << max_ram_len;
+ dynamic_offset = pseries_ddw_max_ram;
}
/* DDW will at least have dynamic allocation */
@@ -1669,7 +1675,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mas
if (direct_mapping) {
/* DDW maps the whole partition, so enable direct DMA mapping */
- ret = walk_system_ram_range(0, ddw_memory_hotplug_max() >> PAGE_SHIFT,
+ ret = walk_system_ram_range(0, pseries_ddw_max_ram >> PAGE_SHIFT,
win64->value, tce_setrange_multi_pSeriesLP_walk);
if (ret) {
dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n",
@@ -1774,8 +1780,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mas
* to directly map both RAM and vPMEM, then we need to set DMA limit.
*/
if (pmem_present && direct_mapping && len != MAX_PHYSMEM_BITS)
- dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset +
- (1ULL << max_ram_len);
+ dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + pseries_ddw_max_ram;
dev_info(&dev->dev, "lsa_required: %x, lsa_enabled: %x, direct mapping: %x\n",
limited_addr_req, limited_addr_enabled, direct_mapping);
@@ -2422,23 +2427,35 @@ static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
{
struct dma_win *window;
struct memory_notify *arg = data;
+ unsigned long limit = arg->nr_pages;
+ unsigned long max_ram_pages = pseries_ddw_max_ram >> PAGE_SHIFT;
int ret = 0;
/* This notifier can get called when onlining persistent memory as well.
* TCEs are not pre-mapped for persistent memory. Persistent memory will
- * always be above ddw_memory_hotplug_max()
+ * always be above pseries_ddw_max_ram
*/
+ if (arg->start_pfn >= max_ram_pages)
+ return NOTIFY_OK;
+
+ /* RAM is being DLPAR'ed. The range should never exceed max ram.
+ * Just in case, clamp the range and throw a warning.
+ */
+ if (arg->start_pfn + limit > max_ram_pages) {
+ limit = max_ram_pages - arg->start_pfn;
+ WARN_ONCE(1, "Limiting Page Range %lx - %lx to Max Mem Pages: %lx\n",
+ arg->start_pfn, arg->start_pfn + arg->nr_pages,
+ max_ram_pages);
+ }
switch (action) {
case MEM_GOING_ONLINE:
spin_lock(&dma_win_list_lock);
list_for_each_entry(window, &dma_win_list, list) {
- if (window->direct && (arg->start_pfn << PAGE_SHIFT) <
- ddw_memory_hotplug_max()) {
+ if (window->direct) {
ret |= tce_setrange_multi_pSeriesLP(arg->start_pfn,
- arg->nr_pages, window->prop);
+ limit, window->prop);
}
- /* XXX log error */
}
spin_unlock(&dma_win_list_lock);
break;
@@ -2446,12 +2463,10 @@ static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
case MEM_OFFLINE:
spin_lock(&dma_win_list_lock);
list_for_each_entry(window, &dma_win_list, list) {
- if (window->direct && (arg->start_pfn << PAGE_SHIFT) <
- ddw_memory_hotplug_max()) {
+ if (window->direct) {
ret |= tce_clearrange_multi_pSeriesLP(arg->start_pfn,
- arg->nr_pages, window->prop);
+ limit, window->prop);
}
- /* XXX log error */
}
spin_unlock(&dma_win_list_lock);
break;
@@ -2535,6 +2550,14 @@ void __init iommu_init_early_pSeries(void)
register_memory_notifier(&iommu_mem_nb);
set_pci_dma_ops(&dma_iommu_ops);
+
+ /* During init determine the max memory an LPAR can have and set it. This
+ * will be used for pre-mapping RAM in DDW. memblock_end_of_DRAM() can
+ * change during the running of LPAR - daxctl can add pmemory as
+ * "system-ram". This memory range should not be pre-mapped in DDW since
+ * the address of pmemory can be much higher than the DDW size.
+ */
+ pseries_ddw_max_ram = ddw_memory_hotplug_max();
}
static int __init disable_multitce(char *str)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 517/686] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (515 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 516/686] powerpc/pseries/iommu: Add TCEs for 16GB pages when RAM is pre-mapped Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 518/686] iio: light: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
` (168 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Chao Yu, Jaegeuk Kim,
Sasha Levin
6.18-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 cached-block continuity tracking to the folio-based f2fs_sync_meta_pages() implementation. ]
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 4c54d75c8981e..14db6b571bc28 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -411,7 +411,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
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;
@@ -430,9 +430,8 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
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;
}
@@ -460,7 +459,7 @@ long f2fs_sync_meta_pages(struct f2fs_sb_info *sbi, enum page_type type,
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] 687+ messages in thread
* [PATCH 6.18 518/686] iio: light: Remove redundant dev_err()/dev_err_probe()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (516 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 517/686] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 519/686] iio: light: ltr501: Power down chip if request irq fails Greg Kroah-Hartman
` (167 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pan Chuang, Andy Shevchenko,
Joshua Crofts, Jonathan Cameron, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pan Chuang <panchuang@vivo.com>
[ Upstream commit 9cf89c342bc2508b79b4ab8823df90da8f77f1f1 ]
Since commit
55b48e23f5c4 ("genirq/devres: Add error handling in devm_request_*_irq()"),
devm_request_irq() and devm_request_threaded_irq() automatically log
detailed error messages on failure. Remove the now-redundant
driver-specific dev_err() and dev_err_probe() calls.
Standardize error check on if (ret) rather than if (ret < 0).
Signed-off-by: Pan Chuang <panchuang@vivo.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Reviewed-by: Joshua Crofts <joshua.crofts1@gmail.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Stable-dep-of: 8a9bcd587d7d ("iio: light: ltr501: Power down chip if request irq fails")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/light/adux1020.c | 4 +---
drivers/iio/light/apds9160.c | 7 ++-----
drivers/iio/light/apds9300.c | 4 +---
drivers/iio/light/apds9306.c | 3 +--
drivers/iio/light/apds9960.c | 4 +---
drivers/iio/light/bh1745.c | 3 +--
drivers/iio/light/cm3605.c | 4 +---
drivers/iio/light/gp2ap002.c | 4 +---
drivers/iio/light/ltr390.c | 3 +--
drivers/iio/light/ltr501.c | 5 +----
drivers/iio/light/opt4060.c | 2 +-
drivers/iio/light/rpr0521.c | 5 +----
drivers/iio/light/si1145.c | 4 +---
drivers/iio/light/st_uvis25_core.c | 5 +----
drivers/iio/light/stk3310.c | 5 +----
drivers/iio/light/tsl2563.c | 2 +-
drivers/iio/light/tsl2772.c | 5 +----
drivers/iio/light/veml6030.c | 4 +---
drivers/iio/light/vl6180.c | 2 +-
19 files changed, 20 insertions(+), 55 deletions(-)
diff --git a/drivers/iio/light/adux1020.c b/drivers/iio/light/adux1020.c
index 66ff9c5fb66a2..df8a85826d19f 100644
--- a/drivers/iio/light/adux1020.c
+++ b/drivers/iio/light/adux1020.c
@@ -808,10 +808,8 @@ static int adux1020_probe(struct i2c_client *client)
NULL, adux1020_interrupt_handler,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
ADUX1020_DRV_NAME, indio_dev);
- if (ret) {
- dev_err(&client->dev, "irq request error %d\n", -ret);
+ if (ret)
return ret;
- }
}
return devm_iio_device_register(&client->dev, indio_dev);
diff --git a/drivers/iio/light/apds9160.c b/drivers/iio/light/apds9160.c
index 9b8af11b7b67a..fc8a9fbd09746 100644
--- a/drivers/iio/light/apds9160.c
+++ b/drivers/iio/light/apds9160.c
@@ -1545,11 +1545,8 @@ static int apds9160_probe(struct i2c_client *client)
apds9160_irq_handler,
IRQF_ONESHOT, "apds9160_event",
indio_dev);
- if (ret) {
- return dev_err_probe(dev, ret,
- "request irq (%d) failed\n",
- client->irq);
- }
+ if (ret)
+ return ret;
} else {
indio_dev->info = &apds9160_info_no_events;
indio_dev->channels = apds9160_channels_without_events;
diff --git a/drivers/iio/light/apds9300.c b/drivers/iio/light/apds9300.c
index 05ba216750632..7053b310cb92b 100644
--- a/drivers/iio/light/apds9300.c
+++ b/drivers/iio/light/apds9300.c
@@ -432,10 +432,8 @@ static int apds9300_probe(struct i2c_client *client)
NULL, apds9300_interrupt_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"apds9300_event", indio_dev);
- if (ret) {
- dev_err(&client->dev, "irq request error %d\n", -ret);
+ if (ret)
goto err;
- }
}
ret = iio_device_register(indio_dev);
diff --git a/drivers/iio/light/apds9306.c b/drivers/iio/light/apds9306.c
index fc07518faec77..dbcd8939e0716 100644
--- a/drivers/iio/light/apds9306.c
+++ b/drivers/iio/light/apds9306.c
@@ -1286,8 +1286,7 @@ static int apds9306_probe(struct i2c_client *client)
apds9306_irq_handler, IRQF_ONESHOT,
"apds9306_event", indio_dev);
if (ret)
- return dev_err_probe(dev, ret,
- "failed to assign interrupt.\n");
+ return ret;
} else {
indio_dev->info = &apds9306_info_no_events;
indio_dev->channels = apds9306_channels_without_events;
diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c
index 79b202c59a0f1..ddcc94d398cde 100644
--- a/drivers/iio/light/apds9960.c
+++ b/drivers/iio/light/apds9960.c
@@ -1098,10 +1098,8 @@ static int apds9960_probe(struct i2c_client *client)
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"apds9960_event",
indio_dev);
- if (ret) {
- dev_err(&client->dev, "request irq (%d) failed\n", client->irq);
+ if (ret)
goto error_power_down;
- }
ret = iio_device_register(indio_dev);
if (ret)
diff --git a/drivers/iio/light/bh1745.c b/drivers/iio/light/bh1745.c
index 10b00344bbedb..31e94813b111b 100644
--- a/drivers/iio/light/bh1745.c
+++ b/drivers/iio/light/bh1745.c
@@ -784,8 +784,7 @@ static int bh1745_setup_triggered_buffer(struct iio_dev *indio_dev,
IRQF_ONESHOT,
"bh1745_interrupt", indio_dev);
if (ret)
- return dev_err_probe(dev, ret,
- "Request for IRQ failed\n");
+ return ret;
}
return 0;
diff --git a/drivers/iio/light/cm3605.c b/drivers/iio/light/cm3605.c
index 0c17378e27d19..1690e3ce42839 100644
--- a/drivers/iio/light/cm3605.c
+++ b/drivers/iio/light/cm3605.c
@@ -233,10 +233,8 @@ static int cm3605_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(dev, irq, cm3605_prox_irq,
NULL, 0, "cm3605", indio_dev);
- if (ret) {
- dev_err(dev, "unable to request IRQ\n");
+ if (ret)
goto out_disable_aset;
- }
/* Just name the trigger the same as the driver */
led_trigger_register_simple("cm3605", &cm3605->led);
diff --git a/drivers/iio/light/gp2ap002.c b/drivers/iio/light/gp2ap002.c
index bb17ef2a829b7..0a8eee74c494a 100644
--- a/drivers/iio/light/gp2ap002.c
+++ b/drivers/iio/light/gp2ap002.c
@@ -580,10 +580,8 @@ static int gp2ap002_probe(struct i2c_client *client)
ret = devm_request_threaded_irq(dev, client->irq, NULL,
gp2ap002_prox_irq, IRQF_ONESHOT,
"gp2ap002", indio_dev);
- if (ret) {
- dev_err(dev, "unable to request IRQ\n");
+ if (ret)
goto out_put_pm;
- }
gp2ap002->irq = client->irq;
/*
diff --git a/drivers/iio/light/ltr390.c b/drivers/iio/light/ltr390.c
index a2b804e9089aa..d40bd98dfd111 100644
--- a/drivers/iio/light/ltr390.c
+++ b/drivers/iio/light/ltr390.c
@@ -838,8 +838,7 @@ static int ltr390_probe(struct i2c_client *client)
"ltr390_thresh_event",
indio_dev);
if (ret)
- return dev_err_probe(dev, ret,
- "request irq (%d) failed\n", client->irq);
+ return ret;
}
ret = ltr390_pm_init(data);
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index 022e0693983bd..36fe40fec2329 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -1538,11 +1538,8 @@ static int ltr501_probe(struct i2c_client *client)
IRQF_ONESHOT,
"ltr501_thresh_event",
indio_dev);
- if (ret) {
- dev_err(&client->dev, "request irq (%d) failed\n",
- client->irq);
+ if (ret)
return ret;
- }
} else {
indio_dev->info = data->chip_info->info_no_irq;
}
diff --git a/drivers/iio/light/opt4060.c b/drivers/iio/light/opt4060.c
index 9be752535d750..70aa8b46784a5 100644
--- a/drivers/iio/light/opt4060.c
+++ b/drivers/iio/light/opt4060.c
@@ -1223,7 +1223,7 @@ static int opt4060_setup_trigger(struct opt4060_chip *chip, struct iio_dev *idev
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
name, idev);
if (ret)
- return dev_err_probe(chip->dev, ret, "Could not request IRQ\n");
+ return ret;
init_completion(&chip->completion);
diff --git a/drivers/iio/light/rpr0521.c b/drivers/iio/light/rpr0521.c
index 9341c1d58cbe3..13e498492092b 100644
--- a/drivers/iio/light/rpr0521.c
+++ b/drivers/iio/light/rpr0521.c
@@ -988,11 +988,8 @@ static int rpr0521_probe(struct i2c_client *client)
rpr0521_drdy_irq_handler, rpr0521_drdy_irq_thread,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
"rpr0521_event", indio_dev);
- if (ret < 0) {
- dev_err(&client->dev, "request irq %d for trigger0 failed\n",
- client->irq);
+ if (ret)
goto err_pm_disable;
- }
ret = devm_iio_trigger_register(indio_dev->dev.parent,
data->drdy_trigger0);
diff --git a/drivers/iio/light/si1145.c b/drivers/iio/light/si1145.c
index ef0abc4499b74..a36d1d0346a8e 100644
--- a/drivers/iio/light/si1145.c
+++ b/drivers/iio/light/si1145.c
@@ -1251,10 +1251,8 @@ static int si1145_probe_trigger(struct iio_dev *indio_dev)
IRQF_TRIGGER_FALLING | IRQF_NO_THREAD,
"si1145_irq",
trig);
- if (ret < 0) {
- dev_err(&client->dev, "irq request failed\n");
+ if (ret)
return ret;
- }
ret = devm_iio_trigger_register(&client->dev, trig);
if (ret)
diff --git a/drivers/iio/light/st_uvis25_core.c b/drivers/iio/light/st_uvis25_core.c
index bcd729a9924ea..94d5261b26634 100644
--- a/drivers/iio/light/st_uvis25_core.c
+++ b/drivers/iio/light/st_uvis25_core.c
@@ -196,11 +196,8 @@ static int st_uvis25_allocate_trigger(struct iio_dev *iio_dev)
st_uvis25_trigger_handler_thread,
irq_type | IRQF_ONESHOT,
iio_dev->name, hw);
- if (err) {
- dev_err(dev, "failed to request trigger irq %d\n",
- hw->irq);
+ if (err)
return err;
- }
hw->trig = devm_iio_trigger_alloc(dev, "%s-trigger",
iio_dev->name);
diff --git a/drivers/iio/light/stk3310.c b/drivers/iio/light/stk3310.c
index 3be6934218866..ca1cb5dd776a6 100644
--- a/drivers/iio/light/stk3310.c
+++ b/drivers/iio/light/stk3310.c
@@ -661,11 +661,8 @@ static int stk3310_probe(struct i2c_client *client)
IRQF_TRIGGER_FALLING |
IRQF_ONESHOT,
"stk3310_event", indio_dev);
- if (ret < 0) {
- dev_err(&client->dev, "request irq %d failed\n",
- client->irq);
+ if (ret)
goto err_standby;
- }
}
ret = iio_device_register(indio_dev);
diff --git a/drivers/iio/light/tsl2563.c b/drivers/iio/light/tsl2563.c
index f2af1cd7c2d1f..4e3daae227ae1 100644
--- a/drivers/iio/light/tsl2563.c
+++ b/drivers/iio/light/tsl2563.c
@@ -755,7 +755,7 @@ static int tsl2563_probe(struct i2c_client *client)
"tsl2563_event",
indio_dev);
if (err)
- return dev_err_probe(dev, err, "irq request error\n");
+ return err;
}
err = tsl2563_configure(chip);
diff --git a/drivers/iio/light/tsl2772.c b/drivers/iio/light/tsl2772.c
index ffbde15401141..e54265f605ddf 100644
--- a/drivers/iio/light/tsl2772.c
+++ b/drivers/iio/light/tsl2772.c
@@ -1837,11 +1837,8 @@ static int tsl2772_probe(struct i2c_client *clientp)
IRQF_ONESHOT,
"TSL2772_event",
indio_dev);
- if (ret) {
- dev_err(&clientp->dev,
- "%s: irq request failed\n", __func__);
+ if (ret)
return ret;
- }
} else {
indio_dev->channels = chip->chip_info->channel_without_events;
}
diff --git a/drivers/iio/light/veml6030.c b/drivers/iio/light/veml6030.c
index da8c32cabfd68..ad3bf9ab07e7c 100644
--- a/drivers/iio/light/veml6030.c
+++ b/drivers/iio/light/veml6030.c
@@ -925,9 +925,7 @@ static int veml6030_set_info(struct iio_dev *indio_dev)
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
indio_dev->name, indio_dev);
if (ret < 0)
- return dev_err_probe(&client->dev, ret,
- "irq %d request failed\n",
- client->irq);
+ return ret;
indio_dev->info = &veml6030_info;
} else {
diff --git a/drivers/iio/light/vl6180.c b/drivers/iio/light/vl6180.c
index c1314b144367f..127904704df3c 100644
--- a/drivers/iio/light/vl6180.c
+++ b/drivers/iio/light/vl6180.c
@@ -722,7 +722,7 @@ static int vl6180_probe(struct i2c_client *client)
IRQF_ONESHOT,
indio_dev->name, indio_dev);
if (ret)
- return dev_err_probe(&client->dev, ret, "devm_request_irq error\n");
+ return ret;
init_completion(&data->completion);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 519/686] iio: light: ltr501: Power down chip if request irq fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (517 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 518/686] iio: light: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 520/686] media: redrat3: Error path leaves device in transmitting state Greg Kroah-Hartman
` (166 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuppuswamy Sathyanarayanan,
Andy Shevchenko, Esben Haabendal, Jonathan Cameron, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Esben Haabendal <esben@geanix.com>
[ Upstream commit 8a9bcd587d7d768e6c8e9fff88bb89645e412731 ]
In case devm_request_threaded_irq() failed, we were leaving the chip
powered instead of powering it down again. Power down the chip switching
ALS and PS modes to standby.
Fixes: 7ac702b3144b ("iio: ltr501: Add interrupt support")
Cc: stable@vger.kernel.org
Acked-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Esben Haabendal <esben@geanix.com>
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/light/ltr501.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/light/ltr501.c b/drivers/iio/light/ltr501.c
index 36fe40fec2329..a38cf1490e13b 100644
--- a/drivers/iio/light/ltr501.c
+++ b/drivers/iio/light/ltr501.c
@@ -1539,7 +1539,7 @@ static int ltr501_probe(struct i2c_client *client)
"ltr501_thresh_event",
indio_dev);
if (ret)
- return ret;
+ goto powerdown_on_error;
} else {
indio_dev->info = data->chip_info->info_no_irq;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 520/686] media: redrat3: Error path leaves device in transmitting state
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (518 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 519/686] iio: light: ltr501: Power down chip if request irq fails Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 521/686] media: i2c: ov5647: fix power cleanup on remove Greg Kroah-Hartman
` (165 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sean Young, Hans Verkuil,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Young <sean@mess.org>
[ Upstream commit 8024d5e84531d828535365718278f1cf0ce67db0 ]
In the allocation failure error path, the transmitting boolean is not
cleared. If this error path is followed the transmitter cannot be
used again until the device is replugged or the module reloaded.
Fix the error path by moving the assignment statement.
Remove the check for the transmitting state in transmit, since rc-core
ensures there is never a reentrant call to the driver transmit function;
the transmit function is always called with dev->lock held.
The transmitting boolean is only used for interpretting firmware errors.
Fixes: fac59136bc22 ("[media] RedRat3: Return directly after a failed kcalloc() in redrat3_transmit_ir()")"
Signed-off-by: Sean Young <sean@mess.org>
Cc: stable@vger.kernel.org
Reviewed-by: Hans Verkuil <hverkuil+cisco@kernel.org>
[ sashal: Adjusted allocation context to retain existing kcalloc() and kzalloc() calls instead of kzalloc_objs() and kzalloc_obj(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/rc/redrat3.c | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index c9a5c030f7726..080207aa888ce 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -773,17 +773,9 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
u8 curlencheck = 0;
unsigned i, sendbuf_len;
- if (rr3->transmitting) {
- dev_warn(dev, "%s: transmitter already in use\n", __func__);
- return -EAGAIN;
- }
-
if (count > RR3_MAX_SIG_SIZE - RR3_TX_TRAILER_LEN)
return -EINVAL;
- /* rr3 will disable rc detector on transmit */
- rr3->transmitting = true;
-
sample_lens = kcalloc(RR3_DRIVER_MAXLENS,
sizeof(*sample_lens),
GFP_KERNEL);
@@ -796,6 +788,9 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
goto out;
}
+ /* rr3 will disable rc detector on transmit */
+ rr3->transmitting = true;
+
for (i = 0; i < count; i++) {
cur_sample_len = redrat3_us_to_len(txbuf[i]);
if (cur_sample_len > 0xffff) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 521/686] media: i2c: ov5647: fix power cleanup on remove
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (519 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 520/686] media: redrat3: Error path leaves device in transmitting state Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 522/686] KVM: guest_memfd: Establish memslot<=>guest_memfd bindings *after* memslot is ready Greg Kroah-Hartman
` (164 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Dave Stevenson,
Sakari Ailus, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
[ Upstream commit 6e81cfc38548109021ab761b94ecdd01f8753154 ]
ov5647_remove() disables runtime PM without powering off the sensor if
it is still runtime active. pm_runtime_disable() does not invoke the
runtime suspend callback, so the sensor can remain powered on.
If the device is not already runtime suspended, call ov5647_power_off()
and mark the runtime PM state as suspended.
This issue was found by manual code inspection.
Fixes: 089b7c70f0d8 ("media: ov5647: Use pm_runtime infrastructure")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Reviewed-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
[ sashal: Retained mutex_destroy(&sensor->lock) in ov5647_remove() because the driver still uses its private mutex. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/i2c/ov5647.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/media/i2c/ov5647.c b/drivers/media/i2c/ov5647.c
index 5fb10e02ba6e2..36460440059ab 100644
--- a/drivers/media/i2c/ov5647.c
+++ b/drivers/media/i2c/ov5647.c
@@ -1480,6 +1480,10 @@ static void ov5647_remove(struct i2c_client *client)
v4l2_ctrl_handler_free(&sensor->ctrls);
v4l2_device_unregister_subdev(sd);
pm_runtime_disable(&client->dev);
+ if (!pm_runtime_status_suspended(&client->dev)) {
+ ov5647_power_off(&client->dev);
+ pm_runtime_set_suspended(&client->dev);
+ }
mutex_destroy(&sensor->lock);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 522/686] KVM: guest_memfd: Establish memslot<=>guest_memfd bindings *after* memslot is ready
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (520 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 521/686] media: i2c: ov5647: fix power cleanup on remove Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 523/686] ublk: keep a canceled FETCH round canceling until the server is gone Greg Kroah-Hartman
` (163 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko Bot, Sean Christopherson,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <seanjc@google.com>
[ Upstream commit 3fe5d2944e5ac3fc5073344b0982c73703332e18 ]
Wait to bind a memslot to a guest_memfd instance until *after* the memslot
is fully prepared, as creating the binding in guest_memfd will effectively
expose the memslot to readers. As pointed out by Sashiko, binding the
memslot before it's ready to be exposed to the rest of the world can break
various memslot assumption and rules. E.g. x86 could observe a NULL rmap
pointer if a PUNCH_HOLE hit the guest_memfd after the binding was created,
but before KVM made it through kvm_prepare_memory_region().
Fixes: a7800aa80ea4 ("KVM: Add KVM_CREATE_GUEST_MEMFD ioctl() for guest-specific backing memory")
Cc: stable@vger.kernel.org
Reported-by: Sashiko Bot <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260826170551.BEF801F000E9@smtp.kernel.org
Link: https://patch.msgid.link/20260922001332.1121266-6-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
virt/kvm/kvm_main.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 2354a4097dec4..723463fe60380 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1955,6 +1955,15 @@ static int kvm_set_memslot(struct kvm *kvm,
if (r)
goto err;
+ if (change == KVM_MR_CREATE && (new->flags & KVM_MEM_GUEST_MEMFD)) {
+ r = kvm_gmem_commit_memory_region(kvm, new);
+ if (r) {
+ kvm_arch_free_memslot(kvm, new);
+ kvm_destroy_dirty_bitmap(new);
+ goto err;
+ }
+ }
+
/*
* For DELETE and MOVE, the working slot is now active as the INVALID
* version of the old slot. MOVE is particularly special as it reuses
@@ -2132,32 +2141,25 @@ static int kvm_set_memory_region(struct kvm *kvm,
mem->guest_memfd_offset);
if (r)
goto out;
+ }
- r = kvm_gmem_commit_memory_region(kvm, new);
+ r = kvm_set_memslot(kvm, old, new, change);
- /*
- * Drop the reference to the file, even on success. The file
- * pins KVM, not the other way 'round. Active bindings are
- * invalidated if the file is closed before memslots are
- * destroyed.
- */
+ /*
+ * Drop the reference to the gmem file, even on success. The file pins
+ * KVM, not the other way 'round. Active bindings are invalidated if
+ * the file is closed before memslots are destroyed.
+ */
#ifdef CONFIG_KVM_GUEST_MEMFD
- fput(new->gmem.file);
+ if (change == KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD))
+ fput(new->gmem.file);
#endif
- if (r)
- goto out;
- }
-
- r = kvm_set_memslot(kvm, old, new, change);
if (r)
- goto out_unbind;
+ goto out;
return 0;
-out_unbind:
- if (change == KVM_MR_CREATE && (mem->flags & KVM_MEM_GUEST_MEMFD))
- kvm_gmem_unbind(new);
out:
kfree(new);
return r;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 523/686] ublk: keep a canceled FETCH round canceling until the server is gone
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (521 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 522/686] KVM: guest_memfd: Establish memslot<=>guest_memfd bindings *after* memslot is ready Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 524/686] misc: fastrpc: Rename phys to dma_addr for clarity Greg Kroah-Hartman
` (162 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Ming Lei, Jens Axboe,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei <tom.leiming@gmail.com>
[ Upstream commit 4c454b5b2634d982caf797fbe477770c3edfc983 ]
A cancel completes a fetched io command and sets io->cmd to NULL, but
the io still counts as ready. Only ubq->canceling stops ublk_queue_rq()
from using the NULL io->cmd. Two paths clear that flag too early:
partial FETCH round recovery, two queues
------------------- --------------------
task A: FETCH tags 0-2 q0 ready: q0->canceling = false
task A exits: q0 task exits:
start_cancel(): mark queues start_cancel(): ub->canceling
tags 0-2: io->cmd = NULL is still set -> q0 not marked
task B: FETCH tag 3 q0: io->cmd = NULL
queue ready: canceling = false q1 ready
START_DEV END_USER_RECOVERY
read -> ublk_queue_cmd(NULL) read on q0 -> ublk_queue_cmd(NULL)
A FETCH round runs from the open of /dev/ublkcN until
ublk_reset_ch_dev() resets the queues. A canceled command can't be
fetched again in the same round. So the ready check only needs one
fact: did this round see a cancel? ub->canceling already records it:
ublk_start_cancel() sets it under cancel_mutex before any command is
taken. It is only cleared too early, when all queues are ready.
Fix:
- clear ub->canceling only in ublk_reset_ch_dev()
- when a queue gets ready, clear ubq->canceling only if ub->canceling
is not set, and check it under cancel_mutex
The check and the marking are ordered by cancel_mutex:
check first: queue cleared -> start_cancel() marks it again
-> command taken
cancel first: check sees ub->canceling -> queue stays canceling
While ub->canceling is set, no queue clears its flag. So the "all
queues marked" shortcut in ublk_start_cancel() is correct again.
UBLK_F_BATCH_IO follows the same rule. It does not dispatch through
io->cmd, so it never hit the oops, but a round which lost a fetch
command is treated the same way: it has to start over.
Fixes: 728cbac5fe21 ("ublk: move device reset into ublk_ch_release()")
Fixes: 3f3850785594 ("ublk: fix batch I/O recovery -ENODEV error")
Cc: stable@vger.kernel.org # v6.17+: needs cancel_mutex
Reported-by: Josef Bacik <josef@toxicpanda.com>
Closes: https://lore.kernel.org/linux-block/20260928-b4-ublk-cancel-stop-v1-0-4a4360232a46@toxicpanda.com/
Tested-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20261011063555.1142277-2-tom.leiming@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[ sashal: Adapted per-queue readiness handling to the existing device-wide ublk_reset_io_flags() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/ublk_drv.c | 31 ++++++++++++++++++++++++-------
1 file changed, 24 insertions(+), 7 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index 6b2035c46daa3..c0e4f94cc43b0 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -233,6 +233,11 @@ struct ublk_device {
u32 nr_io_ready;
bool unprivileged_daemons;
struct mutex cancel_mutex;
+ /*
+ * A cancel started in this FETCH round. Set by ublk_set_canceling(),
+ * cleared only by ublk_reset_ch_dev() when a new round starts. While
+ * it is set, no queue clears its ->canceling.
+ */
bool canceling;
pid_t ublksrv_tgid;
struct delayed_work exit_work;
@@ -1637,6 +1642,11 @@ static void ublk_reset_ch_dev(struct ublk_device *ub)
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
ublk_queue_reinit(ub, ublk_get_queue(ub, i));
+ /* a new FETCH round starts, the queues stay canceling until ready */
+ mutex_lock(&ub->cancel_mutex);
+ ub->canceling = false;
+ mutex_unlock(&ub->cancel_mutex);
+
/* set to NULL, otherwise new tasks cannot mmap io_cmd_buf */
ub->mm = NULL;
ub->nr_io_ready = 0;
@@ -2152,8 +2162,15 @@ static void ublk_reset_io_flags(struct ublk_device *ub)
for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
ublk_get_queue(ub, i)->fail_io = false;
+ /*
+ * A cancel in this FETCH round took a command which still counts as
+ * ready, so the queues have to stay canceling. ub->canceling is set
+ * under cancel_mutex before any command is taken: either we see it
+ * here, or the cancel marks these queues again later.
+ */
mutex_lock(&ub->cancel_mutex);
- ublk_set_canceling(ub, false);
+ if (!ub->canceling)
+ ublk_set_canceling(ub, false);
mutex_unlock(&ub->cancel_mutex);
}
@@ -2173,9 +2190,8 @@ static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq,
ub->nr_io_ready++;
if (ublk_dev_ready(ub)) {
/*
- * now we are ready for handling ublk io request, clear
- * device-level canceling flag and wake ublk_dev_ready()
- * waiters
+ * Reset queue flags unless this round saw a cancel, and
+ * wake ublk_dev_ready() waiters.
*/
ublk_reset_io_flags(ub);
wake_up_var(&ub->nr_io_ready);
@@ -2996,9 +3012,10 @@ static bool ublk_validate_user_pid(struct ublk_device *ub, pid_t ublksrv_pid)
/*
* Wait until all queues have fetched their I/O commands, and return with
- * ub->mutex held and readiness guaranteed: then every queue's ->canceling
- * is cleared. Ready may regress between wakeup and mutex_lock() (daemon
- * death), so re-check it under the mutex and wait again.
+ * ub->mutex held and readiness guaranteed. The queues stay canceling if
+ * this round saw a cancel, see ublk_reset_io_flags(). Ready may regress
+ * between wakeup and mutex_lock() (daemon death), so re-check it under
+ * the mutex and wait again.
*/
static int ublk_wait_dev_ready_and_lock(struct ublk_device *ub)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 524/686] misc: fastrpc: Rename phys to dma_addr for clarity
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (522 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 523/686] ublk: keep a canceled FETCH round canceling until the server is gone Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 525/686] misc: fastrpc: fix double-free in fastrpc_map_attach() error path Greg Kroah-Hartman
` (161 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kumari Pallavi, Dmitry Baryshkov,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumari Pallavi <kumari.pallavi@oss.qualcomm.com>
[ Upstream commit 428b2f2b60c37f69e0723a225135da1f352d2602 ]
The fields buf->phys and map->phys currently store DMA addresses
returned by dma_map_*() APIs, not physical addresses. This naming
is misleading and may lead to incorrect assumptions about the
address type and its translation.
Rename these fields from phys to dma_addr to improve code clarity
and align with kernel conventions for dma_addr_t usage.
Signed-off-by: Kumari Pallavi <kumari.pallavi@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Link: https://patch.msgid.link/20251226070534.602021-3-kumari.pallavi@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 09fa66ec1b48 ("misc: fastrpc: fix double-free in fastrpc_map_attach() error path")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/fastrpc.c | 77 ++++++++++++++++++++++--------------------
1 file changed, 41 insertions(+), 36 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 29f9003999a07..891f28e933537 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -106,7 +106,7 @@
#define miscdev_to_fdevice(d) container_of(d, struct fastrpc_device, miscdev)
struct fastrpc_phy_page {
- u64 addr; /* physical address */
+ dma_addr_t addr; /* dma address */
u64 size; /* size of contiguous region */
};
@@ -171,7 +171,7 @@ struct fastrpc_msg {
u64 ctx; /* invoke caller context */
u32 handle; /* handle to invoke */
u32 sc; /* scalars structure describing the data */
- u64 addr; /* physical address */
+ dma_addr_t addr; /* dma address */
u64 size; /* size of contiguous region */
};
@@ -194,7 +194,7 @@ struct fastrpc_buf {
struct dma_buf *dmabuf;
struct device *dev;
void *virt;
- u64 phys;
+ dma_addr_t dma_addr;
u64 size;
/* Lock for dma buf attachments */
struct mutex lock;
@@ -217,7 +217,7 @@ struct fastrpc_map {
struct dma_buf *buf;
struct sg_table *table;
struct dma_buf_attachment *attach;
- u64 phys;
+ dma_addr_t dma_addr;
u64 size;
void *va;
u64 len;
@@ -322,11 +322,12 @@ static void fastrpc_free_map(struct kref *ref)
perm.vmid = QCOM_SCM_VMID_HLOS;
perm.perm = QCOM_SCM_PERM_RWX;
- err = qcom_scm_assign_mem(map->phys, map->len,
+ err = qcom_scm_assign_mem(map->dma_addr, map->len,
&src_perms, &perm, 1);
if (err) {
- dev_err(map->fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
- map->phys, map->len, err);
+ dev_err(map->fl->sctx->dev,
+ "Failed to assign memory dma_addr %pad size 0x%llx err %d\n",
+ &map->dma_addr, map->len, err);
return;
}
}
@@ -397,7 +398,7 @@ static int fastrpc_map_lookup(struct fastrpc_user *fl, int fd,
static void fastrpc_buf_free(struct fastrpc_buf *buf)
{
dma_free_coherent(buf->dev, buf->size, buf->virt,
- FASTRPC_PHYS(buf->phys));
+ FASTRPC_PHYS(buf->dma_addr));
kfree(buf);
}
@@ -416,12 +417,12 @@ static int __fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev,
buf->fl = fl;
buf->virt = NULL;
- buf->phys = 0;
+ buf->dma_addr = 0;
buf->size = size;
buf->dev = dev;
buf->raddr = 0;
- buf->virt = dma_alloc_coherent(dev, buf->size, (dma_addr_t *)&buf->phys,
+ buf->virt = dma_alloc_coherent(dev, buf->size, &buf->dma_addr,
GFP_KERNEL);
if (!buf->virt) {
mutex_destroy(&buf->lock);
@@ -447,7 +448,7 @@ static int fastrpc_buf_alloc(struct fastrpc_user *fl, struct device *dev,
buf = *obuf;
if (fl->sctx && fl->sctx->sid)
- buf->phys += ((u64)fl->sctx->sid << 32);
+ buf->dma_addr += ((u64)fl->sctx->sid << 32);
return 0;
}
@@ -740,7 +741,7 @@ static int fastrpc_dma_buf_attach(struct dma_buf *dmabuf,
return -ENOMEM;
ret = dma_get_sgtable(buffer->dev, &a->sgt, buffer->virt,
- FASTRPC_PHYS(buffer->phys), buffer->size);
+ FASTRPC_PHYS(buffer->dma_addr), buffer->size);
if (ret < 0) {
dev_err(buffer->dev, "failed to get scatterlist from DMA API\n");
kfree(a);
@@ -789,7 +790,7 @@ static int fastrpc_mmap(struct dma_buf *dmabuf,
dma_resv_assert_held(dmabuf->resv);
return dma_mmap_coherent(buf->dev, vma, buf->virt,
- FASTRPC_PHYS(buf->phys), size);
+ FASTRPC_PHYS(buf->dma_addr), size);
}
static const struct dma_buf_ops fastrpc_dma_buf_ops = {
@@ -841,10 +842,10 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
map->table = table;
if (attr & FASTRPC_ATTR_SECUREMAP) {
- map->phys = sg_phys(map->table->sgl);
+ map->dma_addr = sg_phys(map->table->sgl);
} else {
- map->phys = sg_dma_address(map->table->sgl);
- map->phys += ((u64)fl->sctx->sid << 32);
+ map->dma_addr = sg_dma_address(map->table->sgl);
+ map->dma_addr += ((u64)fl->sctx->sid << 32);
}
for_each_sg(map->table->sgl, sgl, map->table->nents,
sgl_index)
@@ -871,10 +872,11 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
dst_perms[1].vmid = fl->cctx->vmperms[0].vmid;
dst_perms[1].perm = QCOM_SCM_PERM_RWX;
map->attr = attr;
- err = qcom_scm_assign_mem(map->phys, (u64)map->len, &src_perms, dst_perms, 2);
+ err = qcom_scm_assign_mem(map->dma_addr, (u64)map->len, &src_perms, dst_perms, 2);
if (err) {
- dev_err(sess->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
- map->phys, map->len, err);
+ dev_err(sess->dev,
+ "Failed to assign memory with dma_addr %pad size 0x%llx err %d\n",
+ &map->dma_addr, map->len, err);
goto map_err;
}
}
@@ -1056,7 +1058,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx)
struct vm_area_struct *vma = NULL;
rpra[i].buf.pv = (u64) ctx->args[i].ptr;
- pages[i].addr = ctx->maps[i]->phys;
+ pages[i].addr = ctx->maps[i]->dma_addr;
mmap_read_lock(current->mm);
vma = vma_lookup(current->mm, ctx->args[i].ptr);
@@ -1083,7 +1085,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx)
goto bail;
rpra[i].buf.pv = args - ctx->olaps[oix].offset;
- pages[i].addr = ctx->buf->phys -
+ pages[i].addr = ctx->buf->dma_addr -
ctx->olaps[oix].offset +
(pkt_size - rlen);
pages[i].addr = pages[i].addr & PAGE_MASK;
@@ -1115,7 +1117,7 @@ static int fastrpc_get_args(u32 kernel, struct fastrpc_invoke_ctx *ctx)
list[i].num = ctx->args[i].length ? 1 : 0;
list[i].pgidx = i;
if (ctx->maps[i]) {
- pages[i].addr = ctx->maps[i]->phys;
+ pages[i].addr = ctx->maps[i]->dma_addr;
pages[i].size = ctx->maps[i]->size;
}
rpra[i].dma.fd = ctx->args[i].fd;
@@ -1197,7 +1199,7 @@ static int fastrpc_invoke_send(struct fastrpc_session_ctx *sctx,
msg->ctx = ctx->ctxid | fl->pd;
msg->handle = handle;
msg->sc = ctx->sc;
- msg->addr = ctx->buf ? ctx->buf->phys : 0;
+ msg->addr = ctx->buf ? ctx->buf->dma_addr : 0;
msg->size = roundup(ctx->msg_sz, PAGE_SIZE);
fastrpc_context_get(ctx);
@@ -1357,13 +1359,15 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
if (fl->cctx->vmcount) {
u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
- err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
+ err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
(u64)fl->cctx->remote_heap->size,
&src_perms,
fl->cctx->vmperms, fl->cctx->vmcount);
if (err) {
- dev_err(fl->sctx->dev, "Failed to assign memory with phys 0x%llx size 0x%llx err %d\n",
- fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
+ dev_err(fl->sctx->dev,
+ "Failed to assign memory with dma_addr %pad size 0x%llx err %d\n",
+ &fl->cctx->remote_heap->dma_addr,
+ fl->cctx->remote_heap->size, err);
goto err_map;
}
scm_done = true;
@@ -1381,7 +1385,7 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
args[1].length = inbuf.namelen;
args[1].fd = -1;
- pages[0].addr = fl->cctx->remote_heap->phys;
+ pages[0].addr = fl->cctx->remote_heap->dma_addr;
pages[0].size = fl->cctx->remote_heap->size;
args[2].ptr = (u64)(uintptr_t) pages;
@@ -1410,12 +1414,12 @@ static int fastrpc_init_create_static_process(struct fastrpc_user *fl,
dst_perms.vmid = QCOM_SCM_VMID_HLOS;
dst_perms.perm = QCOM_SCM_PERM_RWX;
- err = qcom_scm_assign_mem(fl->cctx->remote_heap->phys,
+ err = qcom_scm_assign_mem(fl->cctx->remote_heap->dma_addr,
(u64)fl->cctx->remote_heap->size,
&src_perms, &dst_perms, 1);
if (err)
- dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d\n",
- fl->cctx->remote_heap->phys, fl->cctx->remote_heap->size, err);
+ dev_err(fl->sctx->dev, "Failed to assign memory dma_addr %pad size 0x%llx err %d\n",
+ &fl->cctx->remote_heap->dma_addr, fl->cctx->remote_heap->size, err);
}
err_map:
fastrpc_buf_free(fl->cctx->remote_heap);
@@ -1505,7 +1509,7 @@ static int fastrpc_init_create_process(struct fastrpc_user *fl,
args[2].length = inbuf.filelen;
args[2].fd = init.filefd;
- pages[0].addr = imem->phys;
+ pages[0].addr = imem->dma_addr;
pages[0].size = imem->size;
args[3].ptr = (u64)(uintptr_t) pages;
@@ -1945,7 +1949,7 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
args[0].ptr = (u64) (uintptr_t) &req_msg;
args[0].length = sizeof(req_msg);
- pages.addr = buf->phys;
+ pages.addr = buf->dma_addr;
pages.size = buf->size;
args[1].ptr = (u64) (uintptr_t) &pages;
@@ -1973,11 +1977,12 @@ static int fastrpc_req_mmap(struct fastrpc_user *fl, char __user *argp)
if (req.flags == ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) {
u64 src_perms = BIT(QCOM_SCM_VMID_HLOS);
- err = qcom_scm_assign_mem(buf->phys, (u64)buf->size,
+ err = qcom_scm_assign_mem(buf->dma_addr, (u64)buf->size,
&src_perms, fl->cctx->vmperms, fl->cctx->vmcount);
if (err) {
- dev_err(fl->sctx->dev, "Failed to assign memory phys 0x%llx size 0x%llx err %d",
- buf->phys, buf->size, err);
+ dev_err(fl->sctx->dev,
+ "Failed to assign memory dma_addr %pad size 0x%llx err %d",
+ &buf->dma_addr, buf->size, err);
goto err_assign;
}
}
@@ -2091,7 +2096,7 @@ static int fastrpc_req_mem_map(struct fastrpc_user *fl, char __user *argp)
args[0].ptr = (u64) (uintptr_t) &req_msg;
args[0].length = sizeof(req_msg);
- pages.addr = map->phys;
+ pages.addr = map->dma_addr;
pages.size = map->len;
args[1].ptr = (u64) (uintptr_t) &pages;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 525/686] misc: fastrpc: fix double-free in fastrpc_map_attach() error path
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (523 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 524/686] misc: fastrpc: Rename phys to dma_addr for clarity Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 526/686] cxl/port: Cleanup handling of the nr_dports 0 -> 1 transition Greg Kroah-Hartman
` (160 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yifei Gao, Ekansh Gupta,
Srinivas Kandagatla, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifei Gao <gyf161023@gmail.com>
[ Upstream commit 09fa66ec1b4896ab841da085ca58b6433f28f07f ]
map->table is assigned right after dma_buf_map_attachment_unlocked()
succeeds. The two failure checks that follow, the len > map->size test
and, where subsystem VMIDs are configured, a failed qcom_scm_assign_mem(),
jump to map_err with map->table already set.
map_err manually calls dma_buf_detach() and dma_buf_put() and then falls
through to fastrpc_map_put(). Since that change the error path tail is
fastrpc_map_put() -> fastrpc_free_map(), and fastrpc_free_map() already
unmaps, detaches and puts the dma-buf whenever map->table is set.
The two operations therefore run twice: the second dma_buf_put() drops an
extra reference on map->buf, and dma_buf_unmap_attachment_unlocked()
dereferences the map->attach already freed by the manual dma_buf_detach().
kref_init() sets the refcount to 1 with no intervening get, so the final
fastrpc_map_put() frees the map synchronously and the redundant cleanup is
deterministic.
The len > map->size branch is reachable by an unprivileged process via
FASTRPC_IOCTL_MEM_MAP with an fd whose dma-buf is smaller than the
requested length, before any DSP invocation.
Route both map->table-is-set failure branches to get_err instead of
map_err, so fastrpc_free_map() is the single owner of the
unmap/detach/put sequence. map_err is retained for the
dma_buf_map_attachment_unlocked() failure, which is reached with
map->table still NULL and an attachment that fastrpc_free_map() will not
clean up, so its dma_buf_detach()/dma_buf_put() must still run manually.
Fixes: 334f1a1cbe03 ("misc: fastrpc: Use fastrpc_map_put in fastrpc_map_create on fail")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Yifei Gao <gyf161023@gmail.com>
Reviewed-by: Ekansh Gupta <ekansh.gupta@oss.qualcomm.com>
Signed-off-by: Srinivas Kandagatla <srini@kernel.org>
Link: https://patch.msgid.link/20261002101220.1084101-2-srinivas.kandagatla@oss.qualcomm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/misc/fastrpc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 891f28e933537..9d596f4fd4dcd 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -854,7 +854,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
dev_dbg(sess->dev, "Bad size passed len 0x%llx map size 0x%llx\n",
len, map->size);
err = -EINVAL;
- goto map_err;
+ goto get_err;
}
map->va = sg_virt(map->table->sgl);
map->len = len;
@@ -877,7 +877,7 @@ static int fastrpc_map_attach(struct fastrpc_user *fl, int fd,
dev_err(sess->dev,
"Failed to assign memory with dma_addr %pad size 0x%llx err %d\n",
&map->dma_addr, map->len, err);
- goto map_err;
+ goto get_err;
}
}
spin_lock(&fl->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 526/686] cxl/port: Cleanup handling of the nr_dports 0 -> 1 transition
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (524 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 525/686] misc: fastrpc: fix double-free in fastrpc_map_attach() error path Greg Kroah-Hartman
@ 2026-11-13 15:50 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 527/686] cxl/port: Clear cached dport pointers when a dport is removed Greg Kroah-Hartman
` (159 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:50 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Jiang, Jonathan Cameron,
Terry Bowman, Dan Williams, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams <dan.j.williams@intel.com>
[ Upstream commit 47fec713d97fb6b823026f723435b58af541bd8d ]
There are multiple setup actions that can occur for a switch port after it
is known that it has at least one active downstream link. That work is
currently split between __devm_cxl_add_dport(), the add_dport() helper, and
cxl_port_add_dport() where decoder setup occurs.
Clean this up by moving all @dport object setup responsibilities into
add_dport() and all port effects into cxl_port_add_dport().
add_dport() handles taking a reference on @dport->dport_dev, and
cxl_port_add_dport() grows the awareness to setup the port component
registers. This removes an awkward open-coded xa_erase() from the middle of
__devm_cxl_add_dport() and instead tasks cxl_port_add_dport() with calling
the common @dport destruction path if anything goes wrong.
After this @port->nr_dports is always the count of @dports in the
@port->dports xarray, and cxl_dport_remove() is symmetric with add_dport().
With ->nr_dports now reliably tracking the number of dports the use of
ida_is_empty() can be dropped. Recall that the ida is only cleared on
"release" of decoder objects, and release can be arbitrarily delayed past
unregistration.
Lastly port->component_reg_phys is no longer reset to CXL_RESOURCE_NONE
post setup, no reason is seen to carry that forward.
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Tested-by: Terry Bowman <terry.bowman@amd.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Link: https://patch.msgid.link/20260131000403.2135324-2-dan.j.williams@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Stable-dep-of: 019560d23450 ("cxl/port: Clear cached dport pointers when a dport is removed")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cxl/core/port.c | 31 +++++++++++++++----------------
1 file changed, 15 insertions(+), 16 deletions(-)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index 599aa9d9eddca..a7d3497f82c05 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1073,11 +1073,15 @@ static int add_dport(struct cxl_port *port, struct cxl_dport *dport)
return -EBUSY;
}
+ /* Arrange for dport_dev to be valid through remove_dport() */
+ struct device *dev __free(put_device) = get_device(dport->dport_dev);
+
rc = xa_insert(&port->dports, (unsigned long)dport->dport_dev, dport,
GFP_KERNEL);
if (rc)
return rc;
+ retain_and_null_ptr(dev);
port->nr_dports++;
return 0;
}
@@ -1106,6 +1110,7 @@ static void cxl_dport_remove(void *data)
struct cxl_dport *dport = data;
struct cxl_port *port = dport->port;
+ port->nr_dports--;
xa_erase(&port->dports, (unsigned long) dport->dport_dev);
put_device(dport->dport_dev);
}
@@ -1188,21 +1193,6 @@ __devm_cxl_add_dport(struct cxl_port *port, struct device *dport_dev,
if (rc)
return ERR_PTR(rc);
- /*
- * Setup port register if this is the first dport showed up. Having
- * a dport also means that there is at least 1 active link.
- */
- if (port->nr_dports == 1 &&
- port->component_reg_phys != CXL_RESOURCE_NONE) {
- rc = cxl_port_setup_regs(port, port->component_reg_phys);
- if (rc) {
- xa_erase(&port->dports, (unsigned long)dport->dport_dev);
- return ERR_PTR(rc);
- }
- port->component_reg_phys = CXL_RESOURCE_NONE;
- }
-
- get_device(dport_dev);
rc = devm_add_action_or_reset(host, cxl_dport_remove, dport);
if (rc)
return ERR_PTR(rc);
@@ -1629,7 +1619,16 @@ static struct cxl_dport *cxl_port_add_dport(struct cxl_port *port,
cxl_switch_parse_cdat(new_dport);
- if (ida_is_empty(&port->decoder_ida)) {
+ if (port->nr_dports == 1) {
+ /*
+ * Some host bridges are known to not have component regsisters
+ * available until a root port has trained CXL. Perform that
+ * setup now.
+ */
+ rc = cxl_port_setup_regs(port, port->component_reg_phys);
+ if (rc)
+ return ERR_PTR(rc);
+
rc = devm_cxl_switch_port_decoders_setup(port);
if (rc)
return ERR_PTR(rc);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 527/686] cxl/port: Clear cached dport pointers when a dport is removed
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (525 preceding siblings ...)
2026-11-13 15:50 ` [PATCH 6.18 526/686] cxl/port: Cleanup handling of the nr_dports 0 -> 1 transition Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 528/686] KVM: arm64: Pin the host vCPU before adjusting its PC under pKVM Greg Kroah-Hartman
` (158 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jonathan Cameron, Li Ming,
Gregory Price (Meta), Alison Schofield, Dave Jiang, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Jiang <dave.jiang@intel.com>
[ Upstream commit 019560d23450a320f4060ff235563a5277ea8033 ]
Switch decoders cache dport pointers in cxlsd->target[], and nothing
clears them when a dport is freed. Readers then dereference freed memory.
KASAN caught it under a cxl_test load/unload loop with concurrent sysfs
reads (abbreviated).
Clear the matching slots from cxl_dport_remove(), walking the port's
decoders the way cxl_port_update_decoder_targets() does on the add side.
Scan all nr_targets slots, the target[] allocation size, and clear every
hit.
Fixes: 8330671c57c7 ("cxl: Add helper to delete dport")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Reviewed-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Reviewed-by: Li Ming <ming.li@zohomail.com>
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Alison Schofield <alison.schofield@intel.com>
Link: https://patch.msgid.link/20261001154744.1095902-2-dave.jiang@intel.com
Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/cxl/core/port.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c
index a7d3497f82c05..01655eeb43a8f 100644
--- a/drivers/cxl/core/port.c
+++ b/drivers/cxl/core/port.c
@@ -1105,11 +1105,40 @@ static void cond_cxl_root_unlock(struct cxl_port *port)
device_unlock(&port->dev);
}
+static int clear_decoder_target(struct device *dev, void *data)
+{
+ struct cxl_dport *dport = data;
+ struct cxl_switch_decoder *cxlsd;
+
+ if (!is_switch_decoder(dev))
+ return 0;
+
+ cxlsd = to_cxl_switch_decoder(dev);
+ guard(rwsem_write)(&cxl_rwsem.region);
+
+ /*
+ * A dport can occupy more than one position of an interleave, so
+ * scan the whole target list rather than stopping at the first hit.
+ */
+ for (int i = 0; i < cxlsd->nr_targets; i++) {
+ if (cxlsd->target[i] != dport)
+ continue;
+ cxlsd->target[i] = NULL;
+ dev_dbg(dev, "dport%d removed from target list, index %d\n",
+ dport->port_id, i);
+ }
+
+ return 0;
+}
+
static void cxl_dport_remove(void *data)
{
struct cxl_dport *dport = data;
struct cxl_port *port = dport->port;
+ /* counterpart of cxl_port_update_decoder_targets() */
+ device_for_each_child(&port->dev, dport, clear_decoder_target);
+
port->nr_dports--;
xa_erase(&port->dports, (unsigned long) dport->dport_dev);
put_device(dport->dport_dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 528/686] KVM: arm64: Pin the host vCPU before adjusting its PC under pKVM
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (526 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 527/686] cxl/port: Clear cached dport pointers when a dport is removed Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 529/686] sctp: hold shkey across socket migration Greg Kroah-Hartman
` (157 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Joey Gouly,
Fuad Tabba, Marc Zyngier, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fuad Tabba <fuad.tabba@linux.dev>
[ Upstream commit a2bb5f5c67a95ac97fcd6859dab51be421cf26fe ]
Under pKVM, a page the host shares with EL2 is mapped at EL2 only while
it's pinned, and the host vCPU is pinned at its first KVM_RUN.
KVM_SET_VCPU_EVENTS with ext_dabt_pending reaches __kvm_adjust_pc() at
EL2 before that, and dereferencing the unmapped host vCPU panics the
hypervisor. Any process holding /dev/kvm on a pKVM host can trigger it.
Pin the host vCPU around the adjustment when no hyp vCPU is loaded for
it. A loaded hyp vCPU implies it's pinned. A pin fails only for memory
the host isn't sharing, and the request is then dropped like any other
bad host pointer.
Fixes: efa1368ba9f4b ("KVM: arm64: Commit exceptions from KVM_SET_VCPU_EVENTS immediately")
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Reviewed-by: Joey Gouly <joey.gouly@arm.com>
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
Link: https://patch.msgid.link/20261001135711.1640520-4-fuad.tabba@linux.dev
Signed-off-by: Marc Zyngier <maz@kernel.org>
[ sashal: Replaced the unavailable __get_host_hyp_vcpus() helper with equivalent inline checks in handle___kvm_adjust_pc(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/hyp/nvhe/hyp-main.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 6e7547b7ca432..1363758035bd1 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -385,8 +385,34 @@ static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
{
DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
+ struct pkvm_hyp_vcpu *hyp_vcpu;
+ struct kvm_vcpu *host_vcpu;
+
+ host_vcpu = kern_hyp_va(vcpu);
+ if (unlikely(is_protected_kvm_enabled())) {
+ hyp_vcpu = pkvm_get_loaded_hyp_vcpu();
+
+ if (!hyp_vcpu || hyp_vcpu->host_vcpu != host_vcpu)
+ host_vcpu = NULL;
+ }
+
+ if (host_vcpu) {
+ __kvm_adjust_pc(host_vcpu);
+ return;
+ }
+
+ /*
+ * With no hyp vCPU loaded for it, the host vCPU may be unpinned,
+ * and so unmapped at EL2: its first run pins it. A pin fails only
+ * for memory the host isn't sharing, a bad pointer, so the request
+ * is dropped.
+ */
+ host_vcpu = kern_hyp_va(vcpu);
+ if (hyp_pin_shared_mem(host_vcpu, host_vcpu + 1))
+ return;
- __kvm_adjust_pc(kern_hyp_va(vcpu));
+ __kvm_adjust_pc(host_vcpu);
+ hyp_unpin_shared_mem(host_vcpu, host_vcpu + 1);
}
static void handle___kvm_flush_vm_context(struct kvm_cpu_context *host_ctxt)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 529/686] sctp: hold shkey across socket migration
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (527 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 528/686] KVM: arm64: Pin the host vCPU before adjusting its PC under pKVM Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 530/686] sctp: re-point retained control chunks on association migration Greg Kroah-Hartman
` (156 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, David Lee, Xin Long,
Jakub Kicinski, Sasha Levin
6.18-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 8c9970352952e..285cd8e0a1cfe 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; \
@@ -9669,7 +9679,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] 687+ messages in thread
* [PATCH 6.18 530/686] sctp: re-point retained control chunks on association migration
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (528 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 529/686] sctp: hold shkey across socket migration Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 531/686] bnxt_en: Refactor some basic ring setup and adjustment logic Greg Kroah-Hartman
` (155 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, TencentOS Corvus AI,
Jun Yang, Xin Long, Jakub Kicinski, Sasha Levin
6.18-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 8e4e88b1d0c06..317ce9ee32549 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 285cd8e0a1cfe..5cbc364a53576 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,
@@ -9677,9 +9704,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] 687+ messages in thread
* [PATCH 6.18 531/686] bnxt_en: Refactor some basic ring setup and adjustment logic
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (529 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 530/686] sctp: re-point retained control chunks on association migration Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 532/686] bnxt_en: dont leave an XDP program installed when the open fails Greg Kroah-Hartman
` (154 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kalesh AP, Pavan Chebbi,
Andy Gospodarek, Michael Chan, Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Chan <michael.chan@broadcom.com>
[ Upstream commit ceee35e5674aa84cf9e504c2a9dae4587511556c ]
Refactor out the basic code that trims the default rings, sets up and
adjusts XDP TX rings and CP rings. There is no change in behavior.
This is to prepare for the next bug fix patch.
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20260331065138.948205-2-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 78731b46967e ("bnxt_en: don't leave an XDP program installed when the open fails")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 53 +++++++++++++------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 +
.../net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 5 +-
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 5 +-
4 files changed, 41 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
index 602b97d00e9ae..8ef1d9d2f1355 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -13000,6 +13000,21 @@ static int bnxt_tx_nr_rings_per_tc(struct bnxt *bp)
return bp->num_tc ? bp->tx_nr_rings / bp->num_tc : bp->tx_nr_rings;
}
+static void bnxt_set_xdp_tx_rings(struct bnxt *bp)
+{
+ bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
+ bp->tx_nr_rings += bp->tx_nr_rings_xdp;
+}
+
+static void bnxt_adj_tx_rings(struct bnxt *bp)
+{
+ /* Make adjustments if reserved TX rings are less than requested */
+ bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
+ bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
+ if (bp->tx_nr_rings_xdp)
+ bnxt_set_xdp_tx_rings(bp);
+}
+
static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
{
int rc = 0;
@@ -13017,13 +13032,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init)
if (rc)
return rc;
- /* Make adjustments if reserved TX rings are less than requested */
- bp->tx_nr_rings -= bp->tx_nr_rings_xdp;
- bp->tx_nr_rings_per_tc = bnxt_tx_nr_rings_per_tc(bp);
- if (bp->tx_nr_rings_xdp) {
- bp->tx_nr_rings_xdp = bp->tx_nr_rings_per_tc;
- bp->tx_nr_rings += bp->tx_nr_rings_xdp;
- }
+ bnxt_adj_tx_rings(bp);
rc = bnxt_alloc_mem(bp, irq_re_init);
if (rc) {
netdev_err(bp->dev, "bnxt_alloc_mem err: %x\n", rc);
@@ -15515,11 +15524,19 @@ static int bnxt_change_mtu(struct net_device *dev, int new_mtu)
return 0;
}
+void bnxt_set_cp_rings(struct bnxt *bp, bool sh)
+{
+ int tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
+
+ bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
+ tx_cp + bp->rx_nr_rings;
+}
+
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
{
struct bnxt *bp = netdev_priv(dev);
bool sh = false;
- int rc, tx_cp;
+ int rc;
if (tc > bp->max_tc) {
netdev_err(dev, "Too many traffic classes requested: %d. Max supported is %d.\n",
@@ -15552,9 +15569,7 @@ int bnxt_setup_mq_tc(struct net_device *dev, u8 tc)
bp->num_tc = 0;
}
bp->tx_nr_rings += bp->tx_nr_rings_xdp;
- tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
- bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
- tx_cp + bp->rx_nr_rings;
+ bnxt_set_cp_rings(bp, sh);
if (netif_running(bp->dev))
return bnxt_open_nic(bp, true, false);
@@ -16616,6 +16631,15 @@ static void bnxt_trim_dflt_sh_rings(struct bnxt *bp)
bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
}
+static void bnxt_adj_dflt_rings(struct bnxt *bp, bool sh)
+{
+ if (sh)
+ bnxt_trim_dflt_sh_rings(bp);
+ else
+ bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
+ bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+}
+
static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
{
int dflt_rings, max_rx_rings, max_tx_rings, rc;
@@ -16641,11 +16665,8 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh)
return rc;
bp->rx_nr_rings = min_t(int, dflt_rings, max_rx_rings);
bp->tx_nr_rings_per_tc = min_t(int, dflt_rings, max_tx_rings);
- if (sh)
- bnxt_trim_dflt_sh_rings(bp);
- else
- bp->cp_nr_rings = bp->tx_nr_rings_per_tc + bp->rx_nr_rings;
- bp->tx_nr_rings = bnxt_tx_nr_rings(bp);
+
+ bnxt_adj_dflt_rings(bp, sh);
avail_msix = bnxt_get_max_func_irqs(bp) - bp->cp_nr_rings;
if (avail_msix >= BNXT_MIN_ROCE_CP_RINGS) {
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
index 1d17ffb7415e0..668d929ddb7de 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -2987,6 +2987,7 @@ int bnxt_check_rings(struct bnxt *bp, int tx, int rx, bool sh, int tcs,
int tx_xdp);
int bnxt_fw_init_one(struct bnxt *bp);
bool bnxt_hwrm_reset_permitted(struct bnxt *bp);
+void bnxt_set_cp_rings(struct bnxt *bp, bool sh);
int bnxt_setup_mq_tc(struct net_device *dev, u8 tc);
struct bnxt_ntuple_filter *bnxt_lookup_ntp_filter_from_idx(struct bnxt *bp,
struct bnxt_ntuple_filter *fltr, u32 idx);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
index 7f60d7b9f5570..2dc9708fb63f6 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
@@ -940,7 +940,6 @@ static int bnxt_set_channels(struct net_device *dev,
bool sh = false;
int tx_xdp = 0;
int rc = 0;
- int tx_cp;
if (channel->other_count)
return -EINVAL;
@@ -1008,9 +1007,7 @@ static int bnxt_set_channels(struct net_device *dev,
if (tcs > 1)
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tcs + tx_xdp;
- tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
- bp->cp_nr_rings = sh ? max_t(int, tx_cp, bp->rx_nr_rings) :
- tx_cp + bp->rx_nr_rings;
+ bnxt_set_cp_rings(bp, sh);
/* After changing number of rx channels, update NTUPLE feature. */
netdev_update_features(dev);
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index 85cbeb35681c2..bebe37e139c94 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -384,7 +384,7 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
{
struct net_device *dev = bp->dev;
- int tx_xdp = 0, tx_cp, rc, tc;
+ int tx_xdp = 0, rc, tc;
struct bpf_prog *old;
netdev_assert_locked(dev);
@@ -431,8 +431,7 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
}
bp->tx_nr_rings_xdp = tx_xdp;
bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
- tx_cp = bnxt_num_tx_to_cp(bp, bp->tx_nr_rings);
- bp->cp_nr_rings = max_t(int, tx_cp, bp->rx_nr_rings);
+ bnxt_set_cp_rings(bp, true);
bnxt_set_tpa_flags(bp);
bnxt_set_ring_params(bp);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 532/686] bnxt_en: dont leave an XDP program installed when the open fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (530 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 531/686] bnxt_en: Refactor some basic ring setup and adjustment logic Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 533/686] fs/ntfs3: validate the EA value length in ntfs_read_ea() Greg Kroah-Hartman
` (153 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vaibhav Nagare, Simon Horman,
Paolo Abeni, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vaibhav Nagare <vnagare@redhat.com>
[ Upstream commit 78731b46967e3e7102b5cd5062bef185f3404b5c ]
bnxt_xdp_set() stores the new program and drops the reference on the old
one before reopening the NIC. If bnxt_open_nic() then fails, ndo_bpf()
returns an error with the new program still in bp->xdp_prog. The caller
treats the error as "nothing was installed" and drops its own reference,
so bp->xdp_prog is left pointing at a freed program and the next XDP
update dereferences it:
BUG: unable to handle page fault for address: ff78ecc80ddd1038
RIP: 0010:__bpf_prog_put+0x5/0x80
Call Trace:
bnxt_xdp_set+0xad/0x1b0 [bnxt_en]
dev_xdp_propagate+0x36/0xa0
bond_xdp_set+0xeb/0x2d0 [bonding]
dev_xdp_install+0x1b1/0x350
bpf_xdp_link_update+0xc5/0x1b0
link_update+0x104/0x1e0
__sys_bpf+0x662/0xcf0
Seen on a 6.12 based kernel after bnxt_alloc_mem() failed an order-4
allocation on a fragmented host:
bnxt_en 0000:a0:00.1 ens4f1np1: nic open fail (rc: fffffff4)
bond1: (slave ens4f1np1): Error -12 calling ndo_bpf
Bonding is not required to hit this; a plain XDP attach on a bnxt
interface takes the same path.
Restore the previous program when an attach or a replace fails, and
recompute the page-mode and XDP TX ring configuration from it. The
configuration matters because bnxt_init_one_rx_ring() only assigns
rxr->xdp_prog in page mode, and __bnxt_set_rx_skb_mode() derives
dev->max_mtu from the installed program. Release the old program only
once the change has been committed.
A detach is not undone. dev_xdp_detach_link() clears the core's record
of the program even when the driver returns an error, so putting the
program back would leave the driver running a program the core has
already dropped. If the reopen fails during a detach, bnxt_xdp_set()
therefore returns 0 with the device closed; bnxt_open_nic() has already
logged the failure.
Found in a crash dump; the change was not tested on hardware.
Fixes: c6d30e8391b8 ("bnxt_en: Add basic XDP support.")
Cc: stable@vger.kernel.org
Signed-off-by: Vaibhav Nagare <vnagare@redhat.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20261012072802.2153706-1-vnagare@redhat.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c | 49 +++++++++++++------
1 file changed, 33 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
index bebe37e139c94..2db8cfcf922f3 100644
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_xdp.c
@@ -381,11 +381,31 @@ int bnxt_xdp_xmit(struct net_device *dev, int num_frames,
return nxmit;
}
+static void bnxt_xdp_apply_cfg(struct bnxt *bp, int tx_xdp)
+{
+ struct net_device *dev = bp->dev;
+ int tc = bp->num_tc ? : 1;
+
+ if (bp->xdp_prog) {
+ bnxt_set_rx_skb_mode(bp, true);
+ xdp_features_set_redirect_target_locked(dev, true);
+ } else {
+ xdp_features_clear_redirect_target_locked(dev);
+ bnxt_set_rx_skb_mode(bp, false);
+ }
+ bp->tx_nr_rings_xdp = tx_xdp;
+ bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
+ bnxt_set_cp_rings(bp, true);
+ bnxt_set_tpa_flags(bp);
+ bnxt_set_ring_params(bp);
+}
+
static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
{
struct net_device *dev = bp->dev;
int tx_xdp = 0, rc, tc;
struct bpf_prog *old;
+ int old_tx_xdp;
netdev_assert_locked(dev);
@@ -418,25 +438,22 @@ static int bnxt_xdp_set(struct bnxt *bp, struct bpf_prog *prog)
if (netif_running(dev))
bnxt_close_nic(bp, true, false);
+ old_tx_xdp = bp->tx_nr_rings_xdp;
old = xchg(&bp->xdp_prog, prog);
- if (old)
- bpf_prog_put(old);
-
- if (prog) {
- bnxt_set_rx_skb_mode(bp, true);
- xdp_features_set_redirect_target_locked(dev, true);
- } else {
- xdp_features_clear_redirect_target_locked(dev);
- bnxt_set_rx_skb_mode(bp, false);
+ bnxt_xdp_apply_cfg(bp, tx_xdp);
+
+ if (netif_running(dev)) {
+ rc = bnxt_open_nic(bp, true, false);
+ /* a detach cannot be undone, only an attach */
+ if (rc && prog) {
+ WRITE_ONCE(bp->xdp_prog, old);
+ bnxt_xdp_apply_cfg(bp, old_tx_xdp);
+ return rc;
+ }
}
- bp->tx_nr_rings_xdp = tx_xdp;
- bp->tx_nr_rings = bp->tx_nr_rings_per_tc * tc + tx_xdp;
- bnxt_set_cp_rings(bp, true);
- bnxt_set_tpa_flags(bp);
- bnxt_set_ring_params(bp);
- if (netif_running(dev))
- return bnxt_open_nic(bp, true, false);
+ if (old)
+ bpf_prog_put(old);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 533/686] fs/ntfs3: validate the EA value length in ntfs_read_ea()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (531 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 532/686] bnxt_en: dont leave an XDP program installed when the open fails Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 534/686] mm/hugetlb: unmap the page where the other VMA maps it Greg Kroah-Hartman
` (152 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuejie Shi, Konstantin Komarov,
Sasha Levin
6.18-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 0dbb410d51dfe..03006ff6a296c 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] 687+ messages in thread
* [PATCH 6.18 534/686] mm/hugetlb: unmap the page where the other VMA maps it
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (532 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 533/686] fs/ntfs3: validate the EA value length in ntfs_read_ea() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 535/686] mm/userfaultfd: only allocate anon_vma in CoW mappings Greg Kroah-Hartman
` (151 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, David Hildenbrand (Arm),
Andrew Morton, Chris Mason, Lorenzo Stoakes (ARM), Muchun Song,
Lance Yang, Liam R. Howlett, Vlastimil Babka, Jann Horn,
Pedro Falcato, Oscar Salvador, Miaohe Lin, Naoya Horiguchi,
Adam Litke, Mel Gorman, Rik van Riel, Peter Xu, Kiryl Shutsemau,
Mike Rapoport, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit ae99c503eb362b42cd5d24d80bc6cba669acc4c2 ]
If the owner of a MAP_PRIVATE hugetlb mapping fails to allocate a page
for CoW, unmap_ref_private() unmaps the old page from all other private
VMAs that have no reservation of their own. It finds them by the offset
in the file, but then zaps each of them at the address of the faulting
VMA. Nothing says that another VMA maps the offset at that address: a
child can have moved its copy of the VMA with mremap(), and a second
mapping of the file is wherever mmap() has put it.
So __unmap_hugepage_range() walks the page tables of the other mm at an
address outside of iter_vma, where i_mmap_rwsem of this file protects
nothing and where anything can be mapped, and the page stays mapped where
it really is.
All of the following was seen on v7.3-rc6+ (g6c377d19d4a5) in KVM guests,
as a user without any privilege. It takes a pool of 2 MiB pages with no
free page that is not reserved, so that the allocation fails: the user
can take or reserve what is free itself.
- The child moves its VMA away. The page is never unmapped, the
mapcount stays 2, and the owner goes round retry_avoidcopy in
hugetlb_wp() until the child is gone or a page becomes free. SIGKILL
to the owner does not end it. 5 of 5 runs.
- The owner's mm has a second private mapping of the offset, made with
MAP_NORESERVE. The owner zaps its own entry and reads zeroes where
its data was. 5 of 5 runs.
- The child moves its VMA away and maps a 1 GiB hugetlb page at the old
address, so this one takes a pool with a 1 GiB page as well.
huge_pte_offset() for the 2 MiB size steps through the PUD
leaf, so the "PMD table" is the 1 GiB page itself and its "page table
lock" is folio->private of that page, which holds 2. Kernels with
lock debugging oops in __unmap_hugepage_range(), 7 of 7 runs. Others
spin on that word for ever with preemption disabled, 5 of 5 runs:
watchdog: BUG: soft lockup - CPU#0 stuck for 26s! [u_det3:130]
RIP: 0010:queued_spin_lock_slowpath+0x8a/0x290
RAX: 0000000000000002 RBX: ffffea0001000028
Call Trace:
__unmap_hugepage_range+0x154/0x6d0
unmap_hugepage_range+0xc1/0x140
hugetlb_wp+0x55c/0x700
hugetlb_fault+0x5f3/0x8f0
RCU stalls follow, and killing all tasks of the user changes nothing.
Four such owners, whose children share a single 1 GiB page, took down
the whole guest with its four CPUs, 2 of 2 runs: one reported soft
lockups on all four, the other gave no sign of life any more.
i_mmap_rwsem stays write locked. With a MAP_PRIVATE mapping of a
hugetlbfs file that belongs to another user, and that the attacker
can only read, the next mmap() of that file by its owner sleeps
uninterruptibly in __mmap_region(), 4 of 4 runs.
Compute the address from the offset for each VMA. The tree walk returns
only VMAs that cover pgoff, and vm_start, vm_end and vm_pgoff of a hugetlb
VMA are aligned to the huge page size, as pgoff is, so the whole range
lies inside iter_vma. Its page tables can not go away there, since the
VMA is unlinked from the file under i_mmap_rwsem first.
With the right address the page is unmapped from all VMAs but the
owner's, so the retry in hugetlb_wp() finds a mapcount of 1 and reuses the
page.
A child that has moved its copy of the VMA now loses the page, and gets
SIGBUS when it faults on a missing page of that VMA. That is what the
comment above the function has always promised to those who do not own
the reservation, and what already happens to a child that has left the
VMA in place.
The address has been wrong from the start, and the second case needs
only mmap() and fork(). mremap() of hugetlb VMAs, which the other cases
use, came with commit 550a7d60bd5e ("mm, hugepages: add mremap() support
for hugepage backed vma") in v5.16.
Original fix generated by an LLM and sent in private by Josef.
[david@kernel.org: switch to vma_filebacked_address, add VM_WARN_ON_ONCE, refine comments]
Link: https://lore.kernel.org/20261015-urgent_fixes-v1-4-42796911043b@kernel.org
Fixes: 04f2cbe35699 ("hugetlb: guarantee that COW faults for a process that called mmap(MAP_PRIVATE) on hugetlbfs will succeed")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Chris Mason <mason@kernel.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Acked-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
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: Oscar Salvador <osalvador@suse.de>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Adam Litke <agl@us.ibm.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Rik van Riel <riel@surriel.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: <stable@vger.kernel.org>
[ sashal: Replaced vma_filebacked_address() with the existing vma_address() helper. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index bf1188e9b1c9b..ba7998ad7c7ee 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -6155,6 +6155,8 @@ static void unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
struct address_space *mapping;
pgoff_t pgoff;
+ VM_WARN_ON_ONCE(!folio_test_anon(folio));
+
/*
* vm_pgoff is in PAGE_SIZE units, hence the different calculation
* from page cache lookup which is in HPAGE_SIZE units.
@@ -6190,10 +6192,17 @@ static void unmap_ref_private(struct mm_struct *mm, struct vm_area_struct *vma,
* could insert a zeroed page instead of the data existing
* from the time of fork. This would look like data corruption
*/
- if (!is_vma_resv_set(iter_vma, HPAGE_RESV_OWNER))
- unmap_hugepage_range(iter_vma, address,
- address + huge_page_size(h),
- folio, 0);
+ if (is_vma_resv_set(iter_vma, HPAGE_RESV_OWNER))
+ continue;
+
+ /*
+ * The address in other VMAs can differ. Even though our old
+ * folio is anon, we always operate on the underlying hugetlb
+ * file.
+ */
+ address = vma_address(iter_vma, pgoff, 1);
+ unmap_hugepage_range(iter_vma, address,
+ address + huge_page_size(h), folio, 0);
}
i_mmap_unlock_write(mapping);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 535/686] mm/userfaultfd: only allocate anon_vma in CoW mappings
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (533 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 534/686] mm/hugetlb: unmap the page where the other VMA maps it Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 536/686] ceph: fix longname buffer overflow in ceph_fname_to_usr() Greg Kroah-Hartman
` (150 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 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
6.18-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 newer VMA helpers with is_cow_mapping(vma->vm_flags) and the existing !vma->anon_vma check. ]
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 ba7998ad7c7ee..fccff6d6ca64e 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -5629,10 +5629,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);
}
@@ -5640,6 +5641,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;
@@ -5651,14 +5659,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 579445bddf561..e4a0cb3ad838a 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -48,8 +48,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 (is_cow_mapping(vma->vm_flags) && unlikely(anon_vma_prepare(vma)))
vma = ERR_PTR(-ENOMEM);
return vma;
@@ -77,7 +76,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 (is_cow_mapping(vma->vm_flags) && unlikely(!vma->anon_vma))
vma_end_read(vma);
else
return vma;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 536/686] ceph: fix longname buffer overflow in ceph_fname_to_usr()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (534 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 535/686] mm/userfaultfd: only allocate anon_vma in CoW mappings Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 537/686] mm/page_vma_mapped: continue past nonmatching huge PMDs Greg Kroah-Hartman
` (149 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alex Markuze, Jiangshan Yi,
Ilya Dryomov, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiangshan Yi <yijiangshan@kylinos.cn>
[ Upstream commit 71975d6e0db17646102488cf54480fda9de0f7a7 ]
Snapshot longname reconstruction formats "_<name>_<inode>" via snprintf()
and memcpy()s the result into oname->name. Checking the length against
NAME_MAX only protects the LOOKUPNAME/export callers, whose buffer is
allocated with fscrypt_fname_alloc_buffer(NAME_MAX). The readdir path
points oname->name straight at the altname in the MDS reply, whose
capacity is altname_len; the reconstructed name can exceed that while
still fitting under NAME_MAX, overflowing the in-place destination.
Save the actual oname->len before the decryption overwrites it, and fail
with -ENAMETOOLONG when the reconstructed name would not fit.
Cc: stable@vger.kernel.org
Fixes: dd66df0053ef ("ceph: add support for encrypted snapshot names")
Suggested-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Reviewed-by: Alex Markuze <amarkuze@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
[ sashal: adjusted context to preserve tname->name access because tname is a struct fscrypt_str pointer rather than an unsigned char pointer ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ceph/crypto.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/fs/ceph/crypto.c b/fs/ceph/crypto.c
index f23ba5c148780..eaf12c9c86ee5 100644
--- a/fs/ceph/crypto.c
+++ b/fs/ceph/crypto.c
@@ -370,6 +370,7 @@ int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname,
struct fscrypt_str iname;
char *name = fname->name;
int name_len = fname->name_len;
+ int dst_len;
int ret;
if (WARN_ON_ONCE(tname && is_vmalloc_addr(tname->name)))
@@ -445,6 +446,9 @@ int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname,
iname.len = fname->ctext_len;
}
+ /* oname->len is overwritten by the decryption below */
+ dst_len = oname->len;
+
_oname.name = unlikely(is_vmalloc_addr(oname->name)) ?
tname->name : oname->name;
_oname.len = oname->len;
@@ -462,6 +466,10 @@ int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname,
name_len = snprintf(tmp_buf, sizeof(tmp_buf), "_%.*s_%ld",
oname->len, oname->name, dir->i_ino);
+ if (name_len > dst_len) {
+ ret = -ENAMETOOLONG;
+ goto out;
+ }
memcpy(oname->name, tmp_buf, name_len);
oname->len = name_len;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 537/686] mm/page_vma_mapped: continue past nonmatching huge PMDs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (535 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 536/686] ceph: fix longname buffer overflow in ceph_fname_to_usr() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 538/686] mm/shmem: honour F_SEAL_EXEC when an ACL is set Greg Kroah-Hartman
` (148 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Andrew Morton,
David Hildenbrand (Arm), Lorenzo Stoakes, Rik van Riel,
Liam R. Howlett, Vlastimil Babka, Harry Yoo, Jann Horn,
Lance Yang, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
[ Upstream commit 1a2993227e8a27fc4cdea305bbdae82d290bc885 ]
A PTE-mapped large folio can straddle PMD boundaries after an unaligned
mremap(). If the first part is discarded and replaced with an unrelated
huge PMD, page_vma_mapped_walk() stops instead of looking for the rest of
the folio in subsequent PMDs.
This also affects migration entries. A walk that stops at an unrelated
huge PMD can leave migration PTEs behind when migration or an anonymous
folio split restores the mappings. Those entries do not hold mapping
references and can outlive the source folio.
This issue can lead to memory corruption and I have a reproducer for
it.
Skip the current PMD rather than ending the walk on a flag or PFN
mismatch. Do the same if the PMD became nonpresent before the locked
recheck. Release the PMD lock, clear the per-PMD state and advance with
step_forward(), so the existing range limit controls termination. This
covers present, migration and device-private huge PMDs while preserving
the matching-PMD and split-to-PTE paths.
Link: https://lore.kernel.org/20261016011549.61146-1-kylebot@openai.com
Fixes: ace71a19cec5 ("mm: introduce page_vma_mapped_walk()")
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>
Assisted-by: LLM
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Rik van Riel <riel@surriel.com>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Harry Yoo <harry@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: <stable@vger.kernel.org>
[ sashal: Adapted PMD handling to older migration-entry APIs and inline locking without device-private huge-PMD support. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/page_vma_mapped.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c
index 41cf3192a8f62..dfbbbf5e3f53d 100644
--- a/mm/page_vma_mapped.c
+++ b/mm/page_vma_mapped.c
@@ -260,18 +260,18 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
if (!thp_migration_supported() ||
!(pvmw->flags & PVMW_MIGRATION))
- return not_found(pvmw);
+ goto next_pmd;
entry = pmd_to_swp_entry(pmde);
if (!is_migration_entry(entry) ||
!check_pmd(swp_offset_pfn(entry), pvmw))
- return not_found(pvmw);
+ goto next_pmd;
return true;
}
if (likely(pmd_trans_huge(pmde))) {
if (pvmw->flags & PVMW_MIGRATION)
- return not_found(pvmw);
+ goto next_pmd;
if (!check_pmd(pmd_pfn(pmde), pvmw))
- return not_found(pvmw);
+ goto next_pmd;
return true;
}
/* THP pmd was split under us: handle on pte level */
@@ -291,8 +291,7 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
spin_unlock(ptl);
}
- step_forward(pvmw, PMD_SIZE);
- continue;
+ goto next_pmd;
}
if (!map_pte(pvmw, &pmde, &ptl)) {
if (!pvmw->pte)
@@ -331,6 +330,17 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw)
pvmw->ptl = ptl;
}
goto this_pte;
+next_pmd:
+ /*
+ * A large folio can be PTE-mapped across PMDs, so a
+ * nonmatching PMD does not end the walk.
+ */
+ if (pvmw->ptl) {
+ spin_unlock(pvmw->ptl);
+ pvmw->ptl = NULL;
+ }
+ pvmw->pmd = NULL;
+ step_forward(pvmw, PMD_SIZE);
} while (pvmw->address < end);
return false;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 538/686] mm/shmem: honour F_SEAL_EXEC when an ACL is set
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (536 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 537/686] mm/page_vma_mapped: continue past nonmatching huge PMDs Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 539/686] spi: cadence-xspi: Replace ACPI specifics by agnostic APIs Greg Kroah-Hartman
` (147 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 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
6.18-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 mnt_idmap parameter to match the existing callback and simple_set_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 6f606d9573c38..97b8a94cd0b31 100644
--- a/include/linux/memfd.h
+++ b/include/linux/memfd.h
@@ -2,8 +2,17 @@
#ifndef __LINUX_MEMFD_H
#define __LINUX_MEMFD_H
+#include <linux/fcntl.h>
#include <linux/file.h>
+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 5efde9fcc3057..6f4c85a3f6410 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -76,6 +76,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>
@@ -1321,10 +1322,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)) {
@@ -5295,12 +5297,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] 687+ messages in thread
* [PATCH 6.18 539/686] spi: cadence-xspi: Replace ACPI specifics by agnostic APIs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (537 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 538/686] mm/shmem: honour F_SEAL_EXEC when an ACL is set Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 540/686] spi: cadence-xspi: Use FIELD_MODIFY() Greg Kroah-Hartman
` (146 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andy Shevchenko, Mark Brown,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 6f9e4740e8591176eb90bb1dae95bbbb5c7d789e ]
Replace ACPI specific calls to get device property with the agnostic one.
The code looses the direct dependency to the ACPI APIs and get cleaner.
This doesn't change functionality.
While at it, drop now unneeded acpi.h.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20251129151739.3998668-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: ea9854a169e9 ("spi: cadence-xspi: reject SDMA transfers larger than the requested length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-cadence-xspi.c | 36 +++++++++++-----------------------
1 file changed, 11 insertions(+), 25 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index c3676b21e8167..b6b42daae1bce 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -2,7 +2,6 @@
// Cadence XSPI flash controller driver
// Copyright (C) 2020-21 Cadence
-#include <linux/acpi.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/err.h>
@@ -21,6 +20,7 @@
#include <linux/limits.h>
#include <linux/log2.h>
#include <linux/bitrev.h>
+#include <linux/util_macros.h>
#define CDNS_XSPI_MAGIC_NUM_VALUE 0x6522
#define CDNS_XSPI_MAX_BANKS 8
@@ -775,19 +775,15 @@ static int marvell_xspi_mem_op_execute(struct spi_mem *mem,
return ret;
}
-#ifdef CONFIG_ACPI
static bool cdns_xspi_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
struct spi_device *spi = mem->spi;
- const union acpi_object *obj;
- struct acpi_device *adev;
+ struct device *dev = &spi->dev;
+ u32 value;
- adev = ACPI_COMPANION(&spi->dev);
-
- if (!acpi_dev_get_property(adev, "spi-tx-bus-width", ACPI_TYPE_INTEGER,
- &obj)) {
- switch (obj->integer.value) {
+ if (!device_property_read_u32(dev, "spi-tx-bus-width", &value)) {
+ switch (value) {
case 1:
break;
case 2:
@@ -800,16 +796,13 @@ static bool cdns_xspi_supports_op(struct spi_mem *mem,
spi->mode |= SPI_TX_OCTAL;
break;
default:
- dev_warn(&spi->dev,
- "spi-tx-bus-width %lld not supported\n",
- obj->integer.value);
+ dev_warn(dev, "spi-tx-bus-width %u not supported\n", value);
break;
}
}
- if (!acpi_dev_get_property(adev, "spi-rx-bus-width", ACPI_TYPE_INTEGER,
- &obj)) {
- switch (obj->integer.value) {
+ if (!device_property_read_u32(dev, "spi-rx-bus-width", &value)) {
+ switch (value) {
case 1:
break;
case 2:
@@ -822,9 +815,7 @@ static bool cdns_xspi_supports_op(struct spi_mem *mem,
spi->mode |= SPI_RX_OCTAL;
break;
default:
- dev_warn(&spi->dev,
- "spi-rx-bus-width %lld not supported\n",
- obj->integer.value);
+ dev_warn(dev, "spi-rx-bus-width %u not supported\n", value);
break;
}
}
@@ -834,7 +825,6 @@ static bool cdns_xspi_supports_op(struct spi_mem *mem,
return true;
}
-#endif
static int cdns_xspi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op *op)
{
@@ -847,17 +837,13 @@ static int cdns_xspi_adjust_mem_op_size(struct spi_mem *mem, struct spi_mem_op *
}
static const struct spi_controller_mem_ops cadence_xspi_mem_ops = {
-#ifdef CONFIG_ACPI
- .supports_op = cdns_xspi_supports_op,
-#endif
+ .supports_op = PTR_IF(IS_ENABLED(CONFIG_ACPI), cdns_xspi_supports_op),
.exec_op = cdns_xspi_mem_op_execute,
.adjust_op_size = cdns_xspi_adjust_mem_op_size,
};
static const struct spi_controller_mem_ops marvell_xspi_mem_ops = {
-#ifdef CONFIG_ACPI
- .supports_op = cdns_xspi_supports_op,
-#endif
+ .supports_op = PTR_IF(IS_ENABLED(CONFIG_ACPI), cdns_xspi_supports_op),
.exec_op = marvell_xspi_mem_op_execute,
.adjust_op_size = cdns_xspi_adjust_mem_op_size,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 540/686] spi: cadence-xspi: Use FIELD_MODIFY()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (538 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 539/686] spi: cadence-xspi: Replace ACPI specifics by agnostic APIs Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 541/686] spi: cadence-xspi: group marvell support code together Greg Kroah-Hartman
` (145 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hans Zhang, Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans Zhang <18255117159@163.com>
[ Upstream commit 6fa473f4c5dcc20db9799f90da48b977730e05f1 ]
Use FIELD_MODIFY() to remove open-coded bit manipulation.
No functional change intended.
Signed-off-by: Hans Zhang <18255117159@163.com>
Link: https://patch.msgid.link/20260430155456.36998-4-18255117159@163.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: ea9854a169e9 ("spi: cadence-xspi: reject SDMA transfers larger than the requested length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-cadence-xspi.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index b6b42daae1bce..90c6d9fa4dbb9 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -453,8 +453,7 @@ static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi,
writel(clk_reg,
cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
clk_reg = FIELD_PREP(MRVL_XSPI_CLK_DIV, i);
- clk_reg &= ~MRVL_XSPI_CLK_DIV;
- clk_reg |= FIELD_PREP(MRVL_XSPI_CLK_DIV, i);
+ FIELD_MODIFY(MRVL_XSPI_CLK_DIV, &clk_reg, i);
clk_reg |= MRVL_XSPI_CLK_ENABLE;
clk_reg |= MRVL_XSPI_IRQ_ENABLE;
update_clk = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 541/686] spi: cadence-xspi: group marvell support code together
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (539 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 540/686] spi: cadence-xspi: Use FIELD_MODIFY() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 542/686] spi: cadence-xspi: reject SDMA transfers larger than the requested length Greg Kroah-Hartman
` (144 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jisheng Zhang, Mark Brown,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jisheng Zhang <jszhang@kernel.org>
[ Upstream commit 94d031d26168560e951f8c88cbfb7aa53a57092a ]
We will remove the 64BIT dependency from cadence-xspi for non marvell
platform soon. No functionality change.
Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Link: https://patch.msgid.link/20260803140728.12747-2-jszhang@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: ea9854a169e9 ("spi: cadence-xspi: reject SDMA transfers larger than the requested length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-cadence-xspi.c | 455 ++++++++++++++++-----------------
1 file changed, 227 insertions(+), 228 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index 90c6d9fa4dbb9..c12930ce67472 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -316,39 +316,10 @@ struct cdns_xspi_driver_data {
u32 rfile_phy_dll_slave_ctrl;
};
-static struct cdns_xspi_driver_data marvell_driver_data = {
- .mrvl_hw_overlay = true,
- .dll_phy_ctrl = MARVELL_REGS_DLL_PHY_CTRL,
- .ctb_rfile_phy_ctrl = MARVELL_CTB_RFILE_PHY_CTRL,
- .rfile_phy_tsel = MARVELL_RFILE_PHY_TSEL,
- .rfile_phy_dq_timing = MARVELL_RFILE_PHY_DQ_TIMING,
- .rfile_phy_dqs_timing = MARVELL_RFILE_PHY_DQS_TIMING,
- .rfile_phy_gate_lpbk_ctrl = MARVELL_RFILE_PHY_GATE_LPBK_CTRL,
- .rfile_phy_dll_master_ctrl = MARVELL_RFILE_PHY_DLL_MASTER_CTRL,
- .rfile_phy_dll_slave_ctrl = MARVELL_RFILE_PHY_DLL_SLAVE_CTRL,
-};
-
static struct cdns_xspi_driver_data cdns_driver_data = {
.mrvl_hw_overlay = false,
};
-static const int cdns_mrvl_xspi_clk_div_list[] = {
- 4, //0x0 = Divide by 4. SPI clock is 200 MHz.
- 6, //0x1 = Divide by 6. SPI clock is 133.33 MHz.
- 8, //0x2 = Divide by 8. SPI clock is 100 MHz.
- 10, //0x3 = Divide by 10. SPI clock is 80 MHz.
- 12, //0x4 = Divide by 12. SPI clock is 66.666 MHz.
- 16, //0x5 = Divide by 16. SPI clock is 50 MHz.
- 18, //0x6 = Divide by 18. SPI clock is 44.44 MHz.
- 20, //0x7 = Divide by 20. SPI clock is 40 MHz.
- 24, //0x8 = Divide by 24. SPI clock is 33.33 MHz.
- 32, //0x9 = Divide by 32. SPI clock is 25 MHz.
- 40, //0xA = Divide by 40. SPI clock is 20 MHz.
- 50, //0xB = Divide by 50. SPI clock is 16 MHz.
- 64, //0xC = Divide by 64. SPI clock is 12.5 MHz.
- 128 //0xD = Divide by 128. SPI clock is 6.25 MHz.
-};
-
struct cdns_xspi_dev {
struct platform_device *pdev;
struct device *dev;
@@ -380,92 +351,6 @@ struct cdns_xspi_dev {
int current_xfer_qword;
};
-static void cdns_xspi_reset_dll(struct cdns_xspi_dev *cdns_xspi)
-{
- u32 dll_cntrl = readl(cdns_xspi->iobase +
- CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL);
-
- /* Reset DLL */
- dll_cntrl |= CDNS_XSPI_DLL_RST_N;
- writel(dll_cntrl, cdns_xspi->iobase +
- CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL);
-}
-
-static bool cdns_xspi_is_dll_locked(struct cdns_xspi_dev *cdns_xspi)
-{
- u32 dll_lock;
-
- return !readl_relaxed_poll_timeout(cdns_xspi->iobase +
- CDNS_XSPI_INTR_STATUS_REG,
- dll_lock, ((dll_lock & CDNS_XSPI_DLL_LOCK) == 1), 10, 10000);
-}
-
-/* Static configuration of PHY */
-static bool cdns_xspi_configure_phy(struct cdns_xspi_dev *cdns_xspi)
-{
- writel(cdns_xspi->driver_data->dll_phy_ctrl,
- cdns_xspi->iobase + CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL);
- writel(cdns_xspi->driver_data->ctb_rfile_phy_ctrl,
- cdns_xspi->auxbase + CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL);
- writel(cdns_xspi->driver_data->rfile_phy_tsel,
- cdns_xspi->auxbase + CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL);
- writel(cdns_xspi->driver_data->rfile_phy_dq_timing,
- cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING);
- writel(cdns_xspi->driver_data->rfile_phy_dqs_timing,
- cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING);
- writel(cdns_xspi->driver_data->rfile_phy_gate_lpbk_ctrl,
- cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL);
- writel(cdns_xspi->driver_data->rfile_phy_dll_master_ctrl,
- cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_MASTER_CTRL);
- writel(cdns_xspi->driver_data->rfile_phy_dll_slave_ctrl,
- cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL);
-
- cdns_xspi_reset_dll(cdns_xspi);
-
- return cdns_xspi_is_dll_locked(cdns_xspi);
-}
-
-static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi,
- int requested_clk)
-{
- int i = 0;
- int clk_val;
- u32 clk_reg;
- bool update_clk = false;
-
- while (i < (ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list) - 1)) {
- clk_val = MRVL_XSPI_CLOCK_DIVIDED(
- cdns_mrvl_xspi_clk_div_list[i]);
- if (clk_val <= requested_clk)
- break;
- i++;
- }
-
- dev_dbg(cdns_xspi->dev, "Found clk div: %d, clk val: %d\n",
- cdns_mrvl_xspi_clk_div_list[i],
- MRVL_XSPI_CLOCK_DIVIDED(
- cdns_mrvl_xspi_clk_div_list[i]));
-
- clk_reg = readl(cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
-
- if (FIELD_GET(MRVL_XSPI_CLK_DIV, clk_reg) != i) {
- clk_reg &= ~MRVL_XSPI_CLK_ENABLE;
- writel(clk_reg,
- cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
- clk_reg = FIELD_PREP(MRVL_XSPI_CLK_DIV, i);
- FIELD_MODIFY(MRVL_XSPI_CLK_DIV, &clk_reg, i);
- clk_reg |= MRVL_XSPI_CLK_ENABLE;
- clk_reg |= MRVL_XSPI_IRQ_ENABLE;
- update_clk = true;
- }
-
- if (update_clk)
- writel(clk_reg,
- cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
-
- return update_clk;
-}
-
static int cdns_xspi_wait_for_controller_idle(struct cdns_xspi_dev *cdns_xspi)
{
u32 ctrl_stat;
@@ -538,23 +423,6 @@ static void cdns_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi,
writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
}
-static void marvell_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi,
- bool enabled)
-{
- u32 intr_enable;
- u32 irq_status;
-
- irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
- writel(irq_status, cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
-
- intr_enable = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
- if (enabled)
- intr_enable |= CDNS_XSPI_INTR_MASK;
- else
- intr_enable &= ~CDNS_XSPI_INTR_MASK;
- writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
-}
-
static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)
{
u32 ctrl_ver;
@@ -599,78 +467,6 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
}
}
-static void m_ioreadq(void __iomem *addr, void *buf, int len)
-{
- if (IS_ALIGNED((long)buf, 8) && len >= 8) {
- u64 full_ops = len / 8;
- u64 *buffer = buf;
-
- len -= full_ops * 8;
- buf += full_ops * 8;
-
- do {
- u64 b = readq(addr);
- *buffer++ = b;
- } while (--full_ops);
- }
-
-
- while (len) {
- u64 tmp_buf;
-
- tmp_buf = readq(addr);
- memcpy(buf, &tmp_buf, min(len, 8));
- len = len > 8 ? len - 8 : 0;
- buf += 8;
- }
-}
-
-static void m_iowriteq(void __iomem *addr, const void *buf, int len)
-{
- if (IS_ALIGNED((long)buf, 8) && len >= 8) {
- u64 full_ops = len / 8;
- const u64 *buffer = buf;
-
- len -= full_ops * 8;
- buf += full_ops * 8;
-
- do {
- writeq(*buffer++, addr);
- } while (--full_ops);
- }
-
- while (len) {
- u64 tmp_buf;
-
- memcpy(&tmp_buf, buf, min(len, 8));
- writeq(tmp_buf, addr);
- len = len > 8 ? len - 8 : 0;
- buf += 8;
- }
-}
-
-static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
-{
- u32 sdma_size, sdma_trd_info;
- u8 sdma_dir;
-
- sdma_size = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_SIZE_REG);
- sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG);
- sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info);
-
- switch (sdma_dir) {
- case CDNS_XSPI_SDMA_DIR_READ:
- m_ioreadq(cdns_xspi->sdmabase,
- cdns_xspi->in_buffer, sdma_size);
- break;
-
- case CDNS_XSPI_SDMA_DIR_WRITE:
- m_iowriteq(cdns_xspi->sdmabase,
- cdns_xspi->out_buffer, sdma_size);
- break;
- }
-}
-
static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
const struct spi_mem_op *op,
bool data_phase)
@@ -760,20 +556,6 @@ static int cdns_xspi_mem_op_execute(struct spi_mem *mem,
return ret;
}
-static int marvell_xspi_mem_op_execute(struct spi_mem *mem,
- const struct spi_mem_op *op)
-{
- struct cdns_xspi_dev *cdns_xspi =
- spi_controller_get_devdata(mem->spi->controller);
- int ret = 0;
-
- cdns_mrvl_xspi_setup_clock(cdns_xspi, mem->spi->max_speed_hz);
-
- ret = cdns_xspi_mem_op(cdns_xspi, mem, op);
-
- return ret;
-}
-
static bool cdns_xspi_supports_op(struct spi_mem *mem,
const struct spi_mem_op *op)
{
@@ -841,12 +623,6 @@ static const struct spi_controller_mem_ops cadence_xspi_mem_ops = {
.adjust_op_size = cdns_xspi_adjust_mem_op_size,
};
-static const struct spi_controller_mem_ops marvell_xspi_mem_ops = {
- .supports_op = PTR_IF(IS_ENABLED(CONFIG_ACPI), cdns_xspi_supports_op),
- .exec_op = marvell_xspi_mem_op_execute,
- .adjust_op_size = cdns_xspi_adjust_mem_op_size,
-};
-
static irqreturn_t cdns_xspi_irq_handler(int this_irq, void *dev)
{
struct cdns_xspi_dev *cdns_xspi = dev;
@@ -928,6 +704,230 @@ static void cdns_xspi_print_phy_config(struct cdns_xspi_dev *cdns_xspi)
readl(cdns_xspi->auxbase + CDNS_XSPI_CCP_PHY_DLL_SLAVE_CTRL));
}
+static struct cdns_xspi_driver_data marvell_driver_data = {
+ .mrvl_hw_overlay = true,
+ .dll_phy_ctrl = MARVELL_REGS_DLL_PHY_CTRL,
+ .ctb_rfile_phy_ctrl = MARVELL_CTB_RFILE_PHY_CTRL,
+ .rfile_phy_tsel = MARVELL_RFILE_PHY_TSEL,
+ .rfile_phy_dq_timing = MARVELL_RFILE_PHY_DQ_TIMING,
+ .rfile_phy_dqs_timing = MARVELL_RFILE_PHY_DQS_TIMING,
+ .rfile_phy_gate_lpbk_ctrl = MARVELL_RFILE_PHY_GATE_LPBK_CTRL,
+ .rfile_phy_dll_master_ctrl = MARVELL_RFILE_PHY_DLL_MASTER_CTRL,
+ .rfile_phy_dll_slave_ctrl = MARVELL_RFILE_PHY_DLL_SLAVE_CTRL,
+};
+
+static const int cdns_mrvl_xspi_clk_div_list[] = {
+ 4, //0x0 = Divide by 4. SPI clock is 200 MHz.
+ 6, //0x1 = Divide by 6. SPI clock is 133.33 MHz.
+ 8, //0x2 = Divide by 8. SPI clock is 100 MHz.
+ 10, //0x3 = Divide by 10. SPI clock is 80 MHz.
+ 12, //0x4 = Divide by 12. SPI clock is 66.666 MHz.
+ 16, //0x5 = Divide by 16. SPI clock is 50 MHz.
+ 18, //0x6 = Divide by 18. SPI clock is 44.44 MHz.
+ 20, //0x7 = Divide by 20. SPI clock is 40 MHz.
+ 24, //0x8 = Divide by 24. SPI clock is 33.33 MHz.
+ 32, //0x9 = Divide by 32. SPI clock is 25 MHz.
+ 40, //0xA = Divide by 40. SPI clock is 20 MHz.
+ 50, //0xB = Divide by 50. SPI clock is 16 MHz.
+ 64, //0xC = Divide by 64. SPI clock is 12.5 MHz.
+ 128 //0xD = Divide by 128. SPI clock is 6.25 MHz.
+};
+
+static void cdns_xspi_reset_dll(struct cdns_xspi_dev *cdns_xspi)
+{
+ u32 dll_cntrl = readl(cdns_xspi->iobase +
+ CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL);
+
+ /* Reset DLL */
+ dll_cntrl |= CDNS_XSPI_DLL_RST_N;
+ writel(dll_cntrl, cdns_xspi->iobase +
+ CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL);
+}
+
+static bool cdns_xspi_is_dll_locked(struct cdns_xspi_dev *cdns_xspi)
+{
+ u32 dll_lock;
+
+ return !readl_relaxed_poll_timeout(cdns_xspi->iobase +
+ CDNS_XSPI_INTR_STATUS_REG,
+ dll_lock, ((dll_lock & CDNS_XSPI_DLL_LOCK) == 1), 10, 10000);
+}
+
+/* Static configuration of PHY */
+static bool cdns_xspi_configure_phy(struct cdns_xspi_dev *cdns_xspi)
+{
+ writel(cdns_xspi->driver_data->dll_phy_ctrl,
+ cdns_xspi->iobase + CDNS_XSPI_RF_MINICTRL_REGS_DLL_PHY_CTRL);
+ writel(cdns_xspi->driver_data->ctb_rfile_phy_ctrl,
+ cdns_xspi->auxbase + CDNS_XSPI_PHY_CTB_RFILE_PHY_CTRL);
+ writel(cdns_xspi->driver_data->rfile_phy_tsel,
+ cdns_xspi->auxbase + CDNS_XSPI_PHY_CTB_RFILE_PHY_TSEL);
+ writel(cdns_xspi->driver_data->rfile_phy_dq_timing,
+ cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQ_TIMING);
+ writel(cdns_xspi->driver_data->rfile_phy_dqs_timing,
+ cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DQS_TIMING);
+ writel(cdns_xspi->driver_data->rfile_phy_gate_lpbk_ctrl,
+ cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_GATE_LPBK_CTRL);
+ writel(cdns_xspi->driver_data->rfile_phy_dll_master_ctrl,
+ cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_MASTER_CTRL);
+ writel(cdns_xspi->driver_data->rfile_phy_dll_slave_ctrl,
+ cdns_xspi->auxbase + CDNS_XSPI_PHY_DATASLICE_RFILE_PHY_DLL_SLAVE_CTRL);
+
+ cdns_xspi_reset_dll(cdns_xspi);
+
+ return cdns_xspi_is_dll_locked(cdns_xspi);
+}
+
+static bool cdns_mrvl_xspi_setup_clock(struct cdns_xspi_dev *cdns_xspi,
+ int requested_clk)
+{
+ int i = 0;
+ int clk_val;
+ u32 clk_reg;
+ bool update_clk = false;
+
+ while (i < (ARRAY_SIZE(cdns_mrvl_xspi_clk_div_list) - 1)) {
+ clk_val = MRVL_XSPI_CLOCK_DIVIDED(
+ cdns_mrvl_xspi_clk_div_list[i]);
+ if (clk_val <= requested_clk)
+ break;
+ i++;
+ }
+
+ dev_dbg(cdns_xspi->dev, "Found clk div: %d, clk val: %d\n",
+ cdns_mrvl_xspi_clk_div_list[i],
+ MRVL_XSPI_CLOCK_DIVIDED(
+ cdns_mrvl_xspi_clk_div_list[i]));
+
+ clk_reg = readl(cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
+
+ if (FIELD_GET(MRVL_XSPI_CLK_DIV, clk_reg) != i) {
+ clk_reg &= ~MRVL_XSPI_CLK_ENABLE;
+ writel(clk_reg,
+ cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
+ clk_reg = FIELD_PREP(MRVL_XSPI_CLK_DIV, i);
+ FIELD_MODIFY(MRVL_XSPI_CLK_DIV, &clk_reg, i);
+ clk_reg |= MRVL_XSPI_CLK_ENABLE;
+ clk_reg |= MRVL_XSPI_IRQ_ENABLE;
+ update_clk = true;
+ }
+
+ if (update_clk)
+ writel(clk_reg,
+ cdns_xspi->auxbase + MRVL_XSPI_CLK_CTRL_AUX_REG);
+
+ return update_clk;
+}
+
+static void marvell_xspi_set_interrupts(struct cdns_xspi_dev *cdns_xspi,
+ bool enabled)
+{
+ u32 intr_enable;
+ u32 irq_status;
+
+ irq_status = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
+ writel(irq_status, cdns_xspi->iobase + CDNS_XSPI_INTR_STATUS_REG);
+
+ intr_enable = readl(cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
+ if (enabled)
+ intr_enable |= CDNS_XSPI_INTR_MASK;
+ else
+ intr_enable &= ~CDNS_XSPI_INTR_MASK;
+ writel(intr_enable, cdns_xspi->iobase + CDNS_XSPI_INTR_ENABLE_REG);
+}
+
+static int marvell_xspi_mem_op_execute(struct spi_mem *mem,
+ const struct spi_mem_op *op)
+{
+ struct cdns_xspi_dev *cdns_xspi =
+ spi_controller_get_devdata(mem->spi->controller);
+ int ret = 0;
+
+ cdns_mrvl_xspi_setup_clock(cdns_xspi, mem->spi->max_speed_hz);
+
+ ret = cdns_xspi_mem_op(cdns_xspi, mem, op);
+
+ return ret;
+}
+
+static void m_ioreadq(void __iomem *addr, void *buf, int len)
+{
+ if (IS_ALIGNED((long)buf, 8) && len >= 8) {
+ u64 full_ops = len / 8;
+ u64 *buffer = buf;
+
+ len -= full_ops * 8;
+ buf += full_ops * 8;
+
+ do {
+ u64 b = readq(addr);
+ *buffer++ = b;
+ } while (--full_ops);
+ }
+
+
+ while (len) {
+ u64 tmp_buf;
+
+ tmp_buf = readq(addr);
+ memcpy(buf, &tmp_buf, min(len, 8));
+ len = len > 8 ? len - 8 : 0;
+ buf += 8;
+ }
+}
+
+static void m_iowriteq(void __iomem *addr, const void *buf, int len)
+{
+ if (IS_ALIGNED((long)buf, 8) && len >= 8) {
+ u64 full_ops = len / 8;
+ const u64 *buffer = buf;
+
+ len -= full_ops * 8;
+ buf += full_ops * 8;
+
+ do {
+ writeq(*buffer++, addr);
+ } while (--full_ops);
+ }
+
+ while (len) {
+ u64 tmp_buf;
+
+ memcpy(&tmp_buf, buf, min(len, 8));
+ writeq(tmp_buf, addr);
+ len = len > 8 ? len - 8 : 0;
+ buf += 8;
+ }
+}
+
+static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
+{
+ u32 sdma_size, sdma_trd_info;
+ u8 sdma_dir;
+
+ sdma_size = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_SIZE_REG);
+ sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG);
+ sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info);
+
+ switch (sdma_dir) {
+ case CDNS_XSPI_SDMA_DIR_READ:
+ m_ioreadq(cdns_xspi->sdmabase,
+ cdns_xspi->in_buffer, sdma_size);
+ break;
+
+ case CDNS_XSPI_SDMA_DIR_WRITE:
+ m_iowriteq(cdns_xspi->sdmabase,
+ cdns_xspi->out_buffer, sdma_size);
+ break;
+ }
+}
+
+static const struct spi_controller_mem_ops marvell_xspi_mem_ops = {
+ .supports_op = PTR_IF(IS_ENABLED(CONFIG_ACPI), cdns_xspi_supports_op),
+ .exec_op = marvell_xspi_mem_op_execute,
+ .adjust_op_size = cdns_xspi_adjust_mem_op_size,
+};
+
static int cdns_xspi_prepare_generic(int cs, const void *dout, int len, int glue, u32 *cmd_regs)
{
u8 *data = (u8 *)dout;
@@ -1155,15 +1155,14 @@ static int cdns_xspi_probe(struct platform_device *pdev)
return -ENODEV;
}
+ host->mem_ops = &cadence_xspi_mem_ops;
+ cdns_xspi->sdma_handler = &cdns_xspi_sdma_handle;
+ cdns_xspi->set_interrupts_handler = &cdns_xspi_set_interrupts;
if (cdns_xspi->driver_data->mrvl_hw_overlay) {
host->mem_ops = &marvell_xspi_mem_ops;
host->transfer_one_message = cdns_xspi_transfer_one_message_b0;
cdns_xspi->sdma_handler = &marvell_xspi_sdma_handle;
cdns_xspi->set_interrupts_handler = &marvell_xspi_set_interrupts;
- } else {
- host->mem_ops = &cadence_xspi_mem_ops;
- cdns_xspi->sdma_handler = &cdns_xspi_sdma_handle;
- cdns_xspi->set_interrupts_handler = &cdns_xspi_set_interrupts;
}
host->dev.of_node = pdev->dev.of_node;
host->bus_num = -1;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 542/686] spi: cadence-xspi: reject SDMA transfers larger than the requested length
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (540 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 541/686] spi: cadence-xspi: group marvell support code together Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 543/686] mm: memory: fix truncation removing mapped folios Greg Kroah-Hartman
` (143 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Weibin Liu, Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weibin Liu <liuwb@xiaopeng.com>
[ Upstream commit ea9854a169e9c1437df8829bea21c2f2e80b137c ]
The XSPI controller reports the size of the slave-DMA transaction
through SDMA_SIZE_REG. Both SDMA handlers take this register at face
value and copy the reported number of bytes between the SDMA FIFO and
the transfer buffers, without checking it against the length of the
transfer that was actually requested.
While cdns_xspi_adjust_mem_op_size() clamps the size of the operations
issued by the SPI core, the device can still report a bigger SDMA size
than what was programmed, which makes the handlers read from or write
to memory beyond the end of the transfer buffers.
Track the number of bytes requested for the current data phase in a new
sdma_xfer_len field, set by cdns_xspi_send_stig_command() and by the
Marvell b0 transfer path, and reject any SDMA size that exceeds it.
Fixes: a16cc8077627 ("spi: cadence: add support for Cadence XSPI controller")
Cc: stable@vger.kernel.org # 5.16+
Signed-off-by: Weibin Liu <liuwb@xiaopeng.com>
Link: https://patch.msgid.link/20260929081146.41041-2-liuwb@xiaopeng.com
Signed-off-by: Mark Brown <broonie@kernel.org>
[ sashal: Adjusted context to retain ioread8_rep() and iowrite8_rep() because the wider-I/O helpers are absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/spi-cadence-xspi.c | 36 +++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index c12930ce67472..ca6af39e977a4 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -332,6 +332,7 @@ struct cdns_xspi_dev {
int irq;
int cur_cs;
unsigned int sdmasize;
+ unsigned int sdma_xfer_len;
struct completion cmd_complete;
struct completion auto_cmd_complete;
@@ -344,7 +345,7 @@ struct cdns_xspi_dev {
u8 hw_num_banks;
const struct cdns_xspi_driver_data *driver_data;
- void (*sdma_handler)(struct cdns_xspi_dev *cdns_xspi);
+ int (*sdma_handler)(struct cdns_xspi_dev *cdns_xspi);
void (*set_interrupts_handler)(struct cdns_xspi_dev *cdns_xspi, bool enabled);
bool xfer_in_progress;
@@ -445,7 +446,7 @@ static int cdns_xspi_controller_init(struct cdns_xspi_dev *cdns_xspi)
return 0;
}
-static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
+static int cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
{
u32 sdma_size, sdma_trd_info;
u8 sdma_dir;
@@ -454,6 +455,13 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG);
sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info);
+ if (sdma_size > cdns_xspi->sdma_xfer_len) {
+ dev_err(cdns_xspi->dev,
+ "SDMA size %u exceeds the requested length %u\n",
+ sdma_size, cdns_xspi->sdma_xfer_len);
+ return -EINVAL;
+ }
+
switch (sdma_dir) {
case CDNS_XSPI_SDMA_DIR_READ:
ioread8_rep(cdns_xspi->sdmabase,
@@ -465,6 +473,8 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
cdns_xspi->out_buffer, sdma_size);
break;
}
+
+ return 0;
}
static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
@@ -510,6 +520,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
cdns_xspi->in_buffer = op->data.buf.in;
cdns_xspi->out_buffer = op->data.buf.out;
+ cdns_xspi->sdma_xfer_len = op->data.nbytes;
cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
@@ -518,7 +529,11 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi,
cdns_xspi->set_interrupts_handler(cdns_xspi, false);
return -EIO;
}
- cdns_xspi->sdma_handler(cdns_xspi);
+ ret = cdns_xspi->sdma_handler(cdns_xspi);
+ if (ret) {
+ cdns_xspi->set_interrupts_handler(cdns_xspi, false);
+ return ret;
+ }
}
wait_for_completion(&cdns_xspi->cmd_complete);
@@ -900,7 +915,7 @@ static void m_iowriteq(void __iomem *addr, const void *buf, int len)
}
}
-static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
+static int marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
{
u32 sdma_size, sdma_trd_info;
u8 sdma_dir;
@@ -909,6 +924,13 @@ static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG);
sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info);
+ if (sdma_size > cdns_xspi->sdma_xfer_len) {
+ dev_err(cdns_xspi->dev,
+ "SDMA size %u exceeds the requested length %u\n",
+ sdma_size, cdns_xspi->sdma_xfer_len);
+ return -EINVAL;
+ }
+
switch (sdma_dir) {
case CDNS_XSPI_SDMA_DIR_READ:
m_ioreadq(cdns_xspi->sdmabase,
@@ -920,6 +942,8 @@ static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi)
cdns_xspi->out_buffer, sdma_size);
break;
}
+
+ return 0;
}
static const struct spi_controller_mem_ops marvell_xspi_mem_ops = {
@@ -1084,9 +1108,11 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller,
cdns_xspi_prepare_transfer(cs, 1, current_transfer_len - 1,
cmd_regs);
cdns_xspi_trigger_command(cdns_xspi, cmd_regs);
+ cdns_xspi->sdma_xfer_len = current_transfer_len - 1;
if (!cdns_xspi_is_sdma_ready(cdns_xspi, true))
return -EIO;
- cdns_xspi->sdma_handler(cdns_xspi);
+ if (cdns_xspi->sdma_handler(cdns_xspi))
+ return -EIO;
if (!cdns_xspi_is_stig_ready(cdns_xspi, true))
return -EIO;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 543/686] mm: memory: fix truncation removing mapped folios
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (541 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 542/686] spi: cadence-xspi: reject SDMA transfers larger than the requested length Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 544/686] ipmr: prevent info-leak in pmr_cache_report() Greg Kroah-Hartman
` (142 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 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
6.18-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>
[ sashal: adapted to try_get_and_clear_pmd() and arch_leave_lazy_mmu_mode() with inline PMD locking in place of sync_with_folio_pmd_zap() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memory.c | 52 +++++++++++++++++++++++++++++++---------------------
1 file changed, 31 insertions(+), 21 deletions(-)
diff --git a/mm/memory.c b/mm/memory.c
index 3049e4dc2651f..e37ae367c8c19 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1877,6 +1877,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);
+ arch_leave_lazy_mmu_mode();
+
+ /* 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.
*
@@ -1884,18 +1893,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 = try_get_and_clear_pmd(mm, pmd, &pmdval);
-
- add_mm_rss_vec(mm, rss);
- arch_leave_lazy_mmu_mode();
-
- /* 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);
/*
@@ -1942,19 +1945,26 @@ 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)) {
- spinlock_t *ptl = pmd_lock(tlb->mm, pmd);
- /*
- * Take and drop THP pmd lock so that we cannot return
- * prematurely, while zap_huge_pmd() has cleared *pmd,
- * but not yet decremented compound_mapcount().
- */
- spin_unlock(ptl);
- }
- if (pmd_none(*pmd)) {
+ } else if (pmd_none(*pmd)) {
+ if (details && details->single_folio) {
+ spinlock_t *ptl = pmd_lock(tlb->mm, pmd);
+
+ /*
+ * zap_huge_pmd() may have cleared the PMD but not
+ * yet updated the folio mapcount, and
+ * try_get_and_clear_pmd() clears the PMD only after
+ * the rmaps for the table have been removed, but
+ * nothing orders the pmd_none() read against later
+ * mapcount reads without this synchronization.
+ */
+ spin_unlock(ptl);
+ }
addr = next;
continue;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 544/686] ipmr: prevent info-leak in pmr_cache_report()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (542 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 543/686] mm: memory: fix truncation removing mapped folios Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 545/686] ipmr: only copy pktinfo to cache reports Greg Kroah-Hartman
` (141 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yiming Qian, Eric Dumazet,
Ido Schimmel, Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 4f34002e2e37639133693c13a2a9977fab86880d ]
Yiming Qian reported:
<quote>
ipmr_cache_report()` allocates a report skb with `alloc_skb(128,
GFP_ATOMIC)` and appends a `struct igmphdr` using `skb_put()`. In the
non-`IGMPMSG_WHOLEPKT` path it initializes only:
- `igmp->type`
- `igmp->code`
but does not initialize:
- `igmp->csum`
- `igmp->group`
Later, `igmpmsg_netlink_event()` copies the bytes after `sizeof(struct
igmpmsg)` into the `IPMRA_CREPORT_PKT` netlink attribute and emits
`RTM_NEWCACHEREPORT` on `RTNLGRP_IPV4_MROUTE_R`.
As a result, 6 bytes of stale heap data from the skb head are
disclosed to userspace.
</quote>
Let's use skb_put_zero() instead of skb_put() to fix this bug.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Yiming Qian <yimingqian591@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260430070611.4004529-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 94a6736bb5ab ("ipmr: only copy pktinfo to cache reports")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ipmr.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index dd9ed871a1b4f..cd587d84f388e 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1112,11 +1112,12 @@ static int ipmr_cache_report(const struct mr_table *mrt,
msg->im_vif_hi = vifi >> 8;
ipv4_pktinfo_prepare(mroute_sk, pkt, false);
memcpy(skb->cb, pkt->cb, sizeof(skb->cb));
- /* Add our header */
- igmp = skb_put(skb, sizeof(struct igmphdr));
+ /* Add our header.
+ * Note that code, csum and group fields are cleared.
+ */
+ igmp = skb_put_zero(skb, sizeof(struct igmphdr));
igmp->type = assert;
msg->im_msgtype = assert;
- igmp->code = 0;
ip_hdr(skb)->tot_len = htons(skb->len); /* Fix the length */
skb->transport_header = skb->network_header;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 545/686] ipmr: only copy pktinfo to cache reports
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (543 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 544/686] ipmr: prevent info-leak in pmr_cache_report() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 546/686] nvme-tcp: skip TLS control records while waiting for the ICResp Greg Kroah-Hartman
` (140 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Ido Schimmel, Eric Dumazet,
Zhiling Zou, Eric Dumazet, Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
[ Upstream commit 94a6736bb5abe6b2ef38490d0cab19c1c6a7c71f ]
ipmr_cache_report() prepares IP_PKTINFO on the original skb. The
ipv4_pktinfo_prepare() helper updates skb->cb and clears the pktinfo fields
when packet info is disabled. Since the skb can continue through the data
path, preserve and restore its original control block around the helper.
The original implementation copies the entire control block to the report
skb. For synthetic RTM_GETROUTE packets, NETLINK_CB data is interpreted as
IPCB by the raw IPv4 receive path. With IP_RECVOPTS or IP_RETOPTS enabled,
corrupted option offsets cause out-of-bounds reads or a stack buffer
overflow. WHOLEPKT and WRVIFWHOLE reports also inherit stale IP option
offsets when their header is prepended.
Clear the report skb control block. Only prepare and copy pktinfo when the
input skb has an IPv4 header. Synthetic route-query skbs use NETLINK_CB,
not IPCB, so leave their report control block zeroed. Restore pkt->cb after
preparing pktinfo for regular IPv4 packets.
Fixes: bb7403655b3c ("ipmr: support IP_PKTINFO on cache report IGMP msg")
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Link: https://lore.kernel.org/netdev/20260903113055.GA90787@shredder/
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Eric Dumazet <edumazet@kernel.org>
Link: https://patch.msgid.link/0545f0c83f5ee2f6696210f87268e811ef655715.1792476357.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ipmr.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index cd587d84f388e..5133fd14029e2 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1055,6 +1055,7 @@ static void ipmr_cache_resolve(struct net *net, struct mr_table *mrt,
static int ipmr_cache_report(const struct mr_table *mrt,
struct sk_buff *pkt, vifi_t vifi, int assert)
{
+ unsigned char pkt_cb[sizeof(pkt->cb)];
const int ihl = ip_hdrlen(pkt);
struct sock *mroute_sk;
struct igmphdr *igmp;
@@ -1110,8 +1111,6 @@ static int ipmr_cache_report(const struct mr_table *mrt,
msg = (struct igmpmsg *)skb_network_header(skb);
msg->im_vif = vifi;
msg->im_vif_hi = vifi >> 8;
- ipv4_pktinfo_prepare(mroute_sk, pkt, false);
- memcpy(skb->cb, pkt->cb, sizeof(skb->cb));
/* Add our header.
* Note that code, csum and group fields are cleared.
*/
@@ -1122,6 +1121,15 @@ static int ipmr_cache_report(const struct mr_table *mrt,
skb->transport_header = skb->network_header;
}
+ memset(skb->cb, 0, sizeof(skb->cb));
+ /* Route queries from ipmr_get_route() carry NETLINK_CB, not IPCB. */
+ if (ip_hdr(pkt)->version) {
+ memcpy(pkt_cb, pkt->cb, sizeof(pkt_cb));
+ ipv4_pktinfo_prepare(mroute_sk, pkt, false);
+ *PKTINFO_SKB_CB(skb) = *PKTINFO_SKB_CB(pkt);
+ memcpy(pkt->cb, pkt_cb, sizeof(pkt_cb));
+ }
+
igmpmsg_netlink_event(mrt, skb);
/* Deliver to mrouted */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 546/686] nvme-tcp: skip TLS control records while waiting for the ICResp
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (544 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 545/686] ipmr: only copy pktinfo to cache reports Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 547/686] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery Greg Kroah-Hartman
` (139 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Christoph Hellwig,
Martin Belanger, Keith Busch, Sasha Levin
6.18-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 94495b0228714..190eac661e7da 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -53,6 +53,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];
#ifdef CONFIG_DEBUG_LOCK_ALLOC
@@ -1535,12 +1541,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;
@@ -1578,16 +1715,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) {
@@ -1595,16 +1723,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] 687+ messages in thread
* [PATCH 6.18 547/686] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (545 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 546/686] nvme-tcp: skip TLS control records while waiting for the ICResp Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 548/686] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue Greg Kroah-Hartman
` (138 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mehmet Fide, Ping-Ke Shih,
Sasha Levin
6.18-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 c7f723c084338..355c607202381 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] 687+ messages in thread
* [PATCH 6.18 548/686] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (546 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 547/686] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 549/686] wifi: rtw88: usb: only let the frames a dozing station needs use " Greg Kroah-Hartman
` (137 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mehmet Fide, Ping-Ke Shih,
Sasha Levin
6.18-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 355c607202381..c60413fd5c6d7 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);
@@ -1025,6 +1056,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] 687+ messages in thread
* [PATCH 6.18 549/686] wifi: rtw88: usb: only let the frames a dozing station needs use the after-DTIM queue
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (547 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 548/686] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 550/686] wifi: rtw88: widen the ATIM window while an AP interface is up Greg Kroah-Hartman
` (136 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mehmet Fide, Ping-Ke Shih,
Sasha Levin
6.18-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 c60413fd5c6d7..caba2e2cedad1 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] 687+ messages in thread
* [PATCH 6.18 550/686] wifi: rtw88: widen the ATIM window while an AP interface is up
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (548 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 549/686] wifi: rtw88: usb: only let the frames a dozing station needs use " Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 551/686] ovl: fail the mount if the casefold flag has changed Greg Kroah-Hartman
` (135 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ping-Ke Shih, Mehmet Fide,
Sasha Levin
6.18-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 3b6302f14de03..a832720f441bf 100644
--- a/drivers/net/wireless/realtek/rtw88/mac80211.c
+++ b/drivers/net/wireless/realtek/rtw88/mac80211.c
@@ -468,6 +468,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);
@@ -484,6 +485,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] 687+ messages in thread
* [PATCH 6.18 551/686] ovl: fail the mount if the casefold flag has changed
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (549 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 550/686] wifi: rtw88: widen the ATIM window while an AP interface is up Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 552/686] udf: validate the device specification EA before using it Greg Kroah-Hartman
` (134 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris Mason, Hungyu Lin,
Amir Goldstein, Sasha Levin
6.18-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>
[backport: In 6.18, ovl_fill_super() handles credential restoration and
filesystem cleanup. Drop the unpublished root dentry and go to out_err,
skipping out_free_oe because the root inode already owns oe.]
Signed-off-by: Hungyu Lin <dennylin0707@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 8d4ef5b2f1780..52d6f32a5a7c3 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1370,7 +1370,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);
@@ -1576,6 +1575,17 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
if (!root_dentry)
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(root_dentry)) != ofs->casefold) {
+ pr_err("casefold flag of the root directory has changed\n");
+ dput(root_dentry);
+ err = -EINVAL;
+ goto out_err;
+ }
+
sb->s_root = root_dentry;
ovl_revert_creds(old_cred);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 552/686] udf: validate the device specification EA before using it
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (550 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 551/686] ovl: fail the mount if the casefold flag has changed Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 553/686] hwmon: (tmp108) Fix jiffies wraparound in conversion-ready check Greg Kroah-Hartman
` (133 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yunpeng Tian, Gongming Wang,
Mingda Zhang, Qinrun Dai, Jan Kara, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yunpeng Tian <shionthanatos@gmail.com>
[ Upstream commit 9a2390959685ac35a58c80c8016120849a2babf6 ]
udf_get_extendedattr() bounds an extended attribute only against
struct genericFormat, which is 12 bytes. A type-12 device
specification is struct deviceSpec, which is 24 bytes plus a flexible
impUse array. Thus a corrupted filesystem can contain extended attribute
that is accepted by udf_get_extendedattr() but udf_write_inode() or
udf_read_inode() may access beyond the end of provided buffer.
Provide a udf_device_spec_valid() check to validate correctness of
extended attribute that is a deviceSpec. While here, check the result of
udf_add_extendedattr() before dereferencing it as it can return NULL in
case of error.
[JK: Removed duplicated validity checks]
Reported-by: Yunpeng Tian <shionthanatos@gmail.com>
Reported-by: Gongming Wang <gmwgg05@gmail.com>
Reported-by: Mingda Zhang <npczmd@qq.com>
Reported-by: Qinrun Dai <jupmouse@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Yunpeng Tian <shionthanatos@gmail.com>
Signed-off-by: Jan Kara <jack@suse.cz>
[ sashal: adapted udf_write_inode() changes to udf_update_inode() while preserving its existing err variable and synchronous writeback error handling ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/udf/inode.c | 42 +++++++++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index d00b78523a967..a9538a0f9734b 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1346,6 +1346,26 @@ int udf_setsize(struct inode *inode, loff_t newsize)
return err;
}
+/*
+ * Verify validity of struct deviceSpec on disk. udf_get_extendedattr() has
+ * already verified the generic header and made sure attribute fits in the
+ * inode so we just have to make sure attribute space is large enough for
+ * deviceSpec struct and required impUse information.
+ */
+static bool udf_device_spec_valid(struct deviceSpec *dsea)
+{
+ u32 attr_length, imp_use_length;
+
+ attr_length = le32_to_cpu(dsea->attrLength);
+ imp_use_length = le32_to_cpu(dsea->impUseLength);
+ if (attr_length < sizeof(struct deviceSpec) ||
+ imp_use_length < sizeof(struct regid) ||
+ imp_use_length > attr_length - sizeof(struct deviceSpec))
+ return false;
+
+ return true;
+}
+
/*
* Maximum length of linked list formed by ICB hierarchy. The chosen number is
* arbitrary - just that we hopefully don't limit any real use of rewritten
@@ -1664,13 +1684,12 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
struct deviceSpec *dsea =
(struct deviceSpec *)udf_get_extendedattr(inode, 12, 1);
- if (dsea) {
- init_special_inode(inode, inode->i_mode,
+
+ if (!dsea || !udf_device_spec_valid(dsea))
+ goto out;
+ init_special_inode(inode, inode->i_mode,
MKDEV(le32_to_cpu(dsea->majorDeviceIdent),
le32_to_cpu(dsea->minorDeviceIdent)));
- /* Developer ID ??? */
- } else
- goto out;
}
ret = 0;
out:
@@ -1818,6 +1837,10 @@ static int udf_update_inode(struct inode *inode, int do_sync)
udf_add_extendedattr(inode,
sizeof(struct deviceSpec) +
sizeof(struct regid), 12, 0x3);
+ if (!dsea) {
+ err = -ENOSPC;
+ goto out_unlock;
+ }
dsea->attrType = cpu_to_le32(12);
dsea->attrSubtype = 1;
dsea->attrLength = cpu_to_le32(
@@ -1825,6 +1848,10 @@ static int udf_update_inode(struct inode *inode, int do_sync)
sizeof(struct regid));
dsea->impUseLength = cpu_to_le32(sizeof(struct regid));
}
+ if (!udf_device_spec_valid(dsea)) {
+ err = -EFSCORRUPTED;
+ goto out_unlock;
+ }
eid = (struct regid *)dsea->impUse;
memset(eid, 0, sizeof(*eid));
strcpy(eid->ident, UDF_ID_DEVELOPER);
@@ -1966,6 +1993,11 @@ static int udf_update_inode(struct inode *inode, int do_sync)
brelse(bh);
return err;
+
+out_unlock:
+ unlock_buffer(bh);
+ brelse(bh);
+ return err;
}
struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 553/686] hwmon: (tmp108) Fix jiffies wraparound in conversion-ready check
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (551 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 552/686] udf: validate the device specification EA before using it Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 554/686] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree Greg Kroah-Hartman
` (132 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tom Verdonck, Guenter Roeck,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tom Verdonck <tom.verdonck@inspiral.be>
[ Upstream commit 6b8b1d1d7bc7e579b53fc7c3293b787d68de702a ]
tmp108 records a one-shot deadline in ->ready_time at probe (and resume)
and, on every temperature read, refuses the read with -EAGAIN while
time_before(jiffies, ready_time) is true, in order to skip the initial
conversion.
->ready_time is an unsigned long compared with time_before(), whose
signed difference is only meaningful while the two values are within
LONG_MAX jiffies of each other. Because ->ready_time is set once and
never refreshed, jiffies keeps advancing away from it, and after 2^31
jiffies the difference flips sign. On a 32-bit HZ=100 kernel that
happens ~248.5 days after boot: time_before() then permanently reports
"not ready" and the driver returns -EAGAIN on every read, without ever
touching the sensor, until the next reboot. The continuous-mode path,
which sets ->ready_time to jiffies with no added conversion delay, wraps
the same way.
Store the deadline as a 64-bit jiffies value and compare it with
get_jiffies_64()/time_before64(), which does not wrap in any practical
uptime.
Fixes: 66e1c9171339 ("hwmon: Add Texas Instruments TMP108 temperature sensor driver.")
Cc: stable@vger.kernel.org
Signed-off-by: Tom Verdonck <tom.verdonck@inspiral.be>
Link: https://patch.msgid.link/525fa49d8c50922344fa53e22be5e6133c9bbb62.1790358356.git.tom.verdonck@inspiral.be
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
[ sashal: Adjusted struct tmp108 context to account for the missing params field. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/tmp108.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/tmp108.c b/drivers/hwmon/tmp108.c
index a971ff628435b..b298fae9296c6 100644
--- a/drivers/hwmon/tmp108.c
+++ b/drivers/hwmon/tmp108.c
@@ -74,7 +74,7 @@
struct tmp108 {
struct regmap *regmap;
u16 orig_config;
- unsigned long ready_time;
+ u64 ready_time;
};
/* convert 12-bit TMP108 register value to milliCelsius */
@@ -125,7 +125,7 @@ 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_before(jiffies, tmp108->ready_time)) {
+ if (time_before64(get_jiffies_64(), tmp108->ready_time)) {
dev_dbg(dev, "%s: Conversion not ready yet..\n",
__func__);
return -EAGAIN;
@@ -362,7 +362,7 @@ static int tmp108_common_probe(struct device *dev, struct regmap *regmap, char *
return err;
}
- tmp108->ready_time = jiffies;
+ tmp108->ready_time = get_jiffies_64();
if ((tmp108->orig_config & TMP108_CONF_MODE_MASK) ==
TMP108_MODE_SHUTDOWN)
tmp108->ready_time +=
@@ -413,7 +413,7 @@ 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 = jiffies +
+ tmp108->ready_time = get_jiffies_64() +
msecs_to_jiffies(TMP108_CONVERSION_TIME_MS);
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 554/686] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (552 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 553/686] hwmon: (tmp108) Fix jiffies wraparound in conversion-ready check Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 555/686] dmaengine: qcom: bam_dma: free interrupt before the clock in error path Greg Kroah-Hartman
` (131 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Deepak Kumar Singh, Vishnu Santhosh,
Frank Li, Vinod Koul, Sasha Levin
6.18-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 781cea16196f5..c8cd6112f9003 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -1323,7 +1323,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] 687+ messages in thread
* [PATCH 6.18 555/686] dmaengine: qcom: bam_dma: free interrupt before the clock in error path
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (553 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 554/686] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 556/686] ASoC: stm: stm32_i2s: Drop redundant error messages Greg Kroah-Hartman
` (130 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Manivannan Sadhasivam,
Bartosz Golaszewski, Vinod Koul, Sasha Levin
6.18-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 c8cd6112f9003..9f514f9201bcc 100644
--- a/drivers/dma/qcom/bam_dma.c
+++ b/drivers/dma/qcom/bam_dma.c
@@ -1322,8 +1322,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;
@@ -1356,7 +1356,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,
@@ -1375,6 +1375,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);
@@ -1400,7 +1402,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] 687+ messages in thread
* [PATCH 6.18 556/686] ASoC: stm: stm32_i2s: Drop redundant error messages
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (554 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 555/686] dmaengine: qcom: bam_dma: free interrupt before the clock in error path Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 557/686] ASoC: stm: stm32_i2s: request IRQ after regmap initialization Greg Kroah-Hartman
` (129 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, bui duc phuc, Mark Brown,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: bui duc phuc <phucduc.bui@gmail.com>
[ Upstream commit a6cdfb6230944082e7be64f9166eed64656b1162 ]
Both devm_request_irq() and snd_dmaengine_pcm_register() already log
failures internally. Drop the redundant error messages and return the
original errors directly.
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
Link: https://patch.msgid.link/20260720074044.87528-3-phucduc.bui@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 1b207c85551f ("ASoC: stm: stm32_i2s: request IRQ after regmap initialization")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/stm/stm32_i2s.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index 6ca21780f21d4..100a50a88d6d6 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -1245,10 +1245,8 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, 0,
dev_name(&pdev->dev), i2s);
- if (ret) {
- dev_err(&pdev->dev, "irq request returned %d\n", ret);
+ if (ret)
return ret;
- }
/* Reset */
rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
@@ -1302,7 +1300,7 @@ static int stm32_i2s_probe(struct platform_device *pdev)
ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0);
if (ret)
- return dev_err_probe(&pdev->dev, ret, "PCM DMA register error\n");
+ return ret;
ret = snd_soc_register_component(&pdev->dev, &stm32_i2s_component,
i2s->dai_drv, 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 557/686] ASoC: stm: stm32_i2s: request IRQ after regmap initialization
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (555 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 556/686] ASoC: stm: stm32_i2s: Drop redundant error messages Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 558/686] iio: dac: mcp4821: reject devices without match data Greg Kroah-Hartman
` (128 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Mark Brown,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit 1b207c85551fd74854d632116849295b2305245f ]
The ISR accesses the managed regmap, but probe requests the IRQ before
creating it. An early interrupt can reach an uninitialized regmap.
Reverse-order cleanup can free the regmap while the IRQ remains active.
Request the IRQ after regmap initialization so probe unwind and
removal free and synchronize it before releasing the regmap.
The teardown ordering issue was found by static analysis.
Fixes: e4e6ec7b127c ("ASoC: stm32: Add I2S driver")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20261004043451.1138613-1-mhun512@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/stm/stm32_i2s.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/sound/soc/stm/stm32_i2s.c b/sound/soc/stm/stm32_i2s.c
index 100a50a88d6d6..ab06d13a59b9f 100644
--- a/sound/soc/stm/stm32_i2s.c
+++ b/sound/soc/stm/stm32_i2s.c
@@ -1192,7 +1192,7 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
struct device_node *np = pdev->dev.of_node;
struct reset_control *rst;
struct resource *res;
- int irq, ret;
+ int ret;
if (!np)
return -ENODEV;
@@ -1238,16 +1238,6 @@ static int stm32_i2s_parse_dt(struct platform_device *pdev,
return ret;
}
- /* Get irqs */
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- return irq;
-
- ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, 0,
- dev_name(&pdev->dev), i2s);
- if (ret)
- return ret;
-
/* Reset */
rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
if (IS_ERR(rst))
@@ -1272,7 +1262,7 @@ static int stm32_i2s_probe(struct platform_device *pdev)
{
struct stm32_i2s_data *i2s;
u32 val;
- int ret;
+ int irq, ret;
i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
if (!i2s)
@@ -1298,6 +1288,15 @@ static int stm32_i2s_probe(struct platform_device *pdev)
return dev_err_probe(&pdev->dev, PTR_ERR(i2s->regmap),
"Regmap init error\n");
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ ret = devm_request_irq(&pdev->dev, irq, stm32_i2s_isr, 0,
+ dev_name(&pdev->dev), i2s);
+ if (ret)
+ return ret;
+
ret = snd_dmaengine_pcm_register(&pdev->dev, &stm32_i2s_pcm_config, 0);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 558/686] iio: dac: mcp4821: reject devices without match data
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (556 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 557/686] ASoC: stm: stm32_i2s: request IRQ after regmap initialization Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 559/686] ALSA: hda/realtek: Add codec SSID quirk for Lenovo Yoga Pro 9 16IMH9 Greg Kroah-Hartman
` (127 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiale Yao, Jonathan Cameron,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiale Yao <yaojiale02@163.com>
[ Upstream commit 6ac1faf4de61dcf27ffe8f2c25d96fe5f4b2886d ]
A device bound through driver_override need not match an entry in the
driver tables. In that case spi_get_device_match_data() returns NULL,
but mcp4821_probe() dereferences the result while configuring the IIO
device.
Reject devices without match data before using the chip information.
Fixes: cdf3ecb0d8d0 ("iio: dac: driver for MCP4821")
Signed-off-by: Jiale Yao <yaojiale02@163.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
[ sashal: adjusted context due to missing configurable-gain initialization ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/dac/mcp4821.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/dac/mcp4821.c b/drivers/iio/dac/mcp4821.c
index 748bdca9a964d..daaebf175fedb 100644
--- a/drivers/iio/dac/mcp4821.c
+++ b/drivers/iio/dac/mcp4821.c
@@ -172,9 +172,13 @@ static const struct iio_info mcp4821_info = {
static int mcp4821_probe(struct spi_device *spi)
{
+ const struct mcp4821_chip_info *info;
struct iio_dev *indio_dev;
struct mcp4821_state *state;
- const struct mcp4821_chip_info *info;
+
+ info = spi_get_device_match_data(spi);
+ if (!info)
+ return -ENODATA;
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*state));
if (indio_dev == NULL)
@@ -183,7 +187,6 @@ static int mcp4821_probe(struct spi_device *spi)
state = iio_priv(indio_dev);
state->spi = spi;
- info = spi_get_device_match_data(spi);
indio_dev->name = info->name;
indio_dev->info = &mcp4821_info;
indio_dev->modes = INDIO_DIRECT_MODE;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 559/686] ALSA: hda/realtek: Add codec SSID quirk for Lenovo Yoga Pro 9 16IMH9
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (557 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 558/686] iio: dac: mcp4821: reject devices without match data Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 560/686] ALSA: hda/realtek: Fix Legion 7 16ITHG6 speaker amp binding Greg Kroah-Hartman
` (126 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rámon van Raaij, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rámon van Raaij <ramon@vanraaij.eu>
[ Upstream commit 56722cfbb78d7eb41756cd78dc5192d08bd14f3d ]
The Yoga Pro 9 16IMH9 (codec SSID 17aa:38d6) shares PCI audio device
subsystem ID 17aa:3811 with the Legion S7 15IMH05. The existing
SND_PCI_QUIRK entry for the Legion routes both machines to
ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS, which does not bind the TAS2781
smart amplifiers, resulting in near-silent built-in speakers.
Add an HDA_CODEC_QUIRK entry immediately before the conflicting PCI quirk
that matches the Yoga Pro 9's unique codec SSID and routes it to
ALC287_FIXUP_TAS2781_I2C. Codec quirks are evaluated after PCI quirks and
take precedence, leaving the Legion S7 15IMH05 entry unaffected.
This follows the same pattern used to disambiguate PCI SSID 17aa:3847
(shared between Yoga Pro 7 14IMH9 and Legion 7 16ACHG6), where a
HDA_CODEC_QUIRK for codec SSID 17aa:38cf resolves the conflict.
Signed-off-by: Rámon van Raaij <ramon@vanraaij.eu>
Link: https://patch.msgid.link/20260430191224.patch1-ramon@vanraaij.eu
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 1c36207da794 ("ALSA: hda/realtek: Fix silent speakers on Lenovo Legion S7 15IMH05")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 99d3fda16f3a2..5bf382eb4646e 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -7544,6 +7544,10 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
HDA_CODEC_QUIRK(0x17aa, 0x3802, "DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga Pro 9 14IRP8", ALC287_FIXUP_TAS2781_I2C),
+ /* Yoga Pro 9 16IMH9 shares PCI SSID 17aa:3811 with Legion S7 15IMH05;
+ * use codec SSID to distinguish them
+ */
+ HDA_CODEC_QUIRK(0x17aa, 0x38d6, "Lenovo Yoga Pro 9 16IMH9", ALC287_FIXUP_TAS2781_I2C),
SND_PCI_QUIRK(0x17aa, 0x3811, "Legion S7 15IMH05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 560/686] ALSA: hda/realtek: Fix Legion 7 16ITHG6 speaker amp binding
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (558 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 559/686] ALSA: hda/realtek: Add codec SSID quirk for Lenovo Yoga Pro 9 16IMH9 Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 561/686] ALSA: hda/realtek: Fix silent speakers on Lenovo Legion S7 15IMH05 Greg Kroah-Hartman
` (125 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Bonello, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Bonello <hadobedo@gmail.com>
[ Upstream commit dd074f04e04648d89d9d10ae9846cd057c97b385 ]
The Lenovo Legion 7 16ITHG6 uses codec SSID 17aa:3855, but its PCI
SSID is 17aa:3811. The latter is now also used by the Legion S7 15IMH05
quirk, which is matched before codec SSID fallback and incorrectly
routes Legion 7 16ITHG6 machines to ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS.
That fixup does not bind the CLSA0101 CS35L41 companion amplifiers,
making the built-in speakers silent even though playback appears to be
active.
Add a codec SSID quirk for 17aa:3855 before the conflicting PCI SSID
quirk so that the Legion 7 16ITHG6 uses ALC287_FIXUP_LEGION_16ITHG6.
This restores CS35L41 firmware loading and binds both speaker
amplifiers.
Fixes: 67f4c61a73e9 ("ALSA: hda/realtek: Add quirk for Legion S7 15IMH")
Cc: stable@vger.kernel.org
Tested-by: Nicholas Bonello <hadobedo@gmail.com>
Assisted-by: Codex:GPT-5
Signed-off-by: Nicholas Bonello <hadobedo@gmail.com>
Link: https://patch.msgid.link/20260508225507.47667-1-hadobedo@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: 1c36207da794 ("ALSA: hda/realtek: Fix silent speakers on Lenovo Legion S7 15IMH05")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 5bf382eb4646e..ed76281856b1c 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -7544,10 +7544,11 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3801, "Lenovo Yoga9 14IAP7", ALC287_FIXUP_YOGA9_14IAP7_BASS_SPK_PIN),
HDA_CODEC_QUIRK(0x17aa, 0x3802, "DuetITL 2021", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo Yoga Pro 9 14IRP8", ALC287_FIXUP_TAS2781_I2C),
- /* Yoga Pro 9 16IMH9 shares PCI SSID 17aa:3811 with Legion S7 15IMH05;
- * use codec SSID to distinguish them
+ /* Yoga Pro 9 16IMH9 and Legion 7 16ITHG6 share PCI SSID 17aa:3811
+ * with Legion S7 15IMH05; use codec SSID to distinguish them
*/
HDA_CODEC_QUIRK(0x17aa, 0x38d6, "Lenovo Yoga Pro 9 16IMH9", ALC287_FIXUP_TAS2781_I2C),
+ HDA_CODEC_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
SND_PCI_QUIRK(0x17aa, 0x3811, "Legion S7 15IMH05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 561/686] ALSA: hda/realtek: Fix silent speakers on Lenovo Legion S7 15IMH05
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (559 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 560/686] ALSA: hda/realtek: Fix Legion 7 16ITHG6 speaker amp binding Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 562/686] spi: atmel-quadspi: add controller init callback Greg Kroah-Hartman
` (124 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Matej Sochan, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matej Sochan <matej.sochan@gmail.com>
[ Upstream commit 1c36207da79455402d981125fa09716991364e66 ]
The speakers on the Legion S7 15IMH05 (PCI SSID 17aa:3811, ALC287) stay
silent after a cold boot with the current quirk, which applies
ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS. They only start working after a
suspend/resume cycle.
The amplifier setup is sent through COEF 0x24/0x26 on NID 0x20. On this
machine the first pass of that sequence appears to only wake the
amplifiers. Sending the identical sequence a second time makes both
speakers work, provided the second write comes a few milliseconds after
the first: back-to-back writes leave the speakers silent, a 7 ms gap
makes only the right speaker work, and 8 ms or more is reliable. A dump
of all COEF registers of NID 0x20 taken before and after the second
write shows no difference.
Add a dedicated fixup that writes the sequence, waits 20 ms to keep a
margin over the measured minimum, and writes it again on every codec
init. It chains to the same AUTOMUTE fixup as before. To share the
sequence, move the verbs of ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS into a
named array; this has no functional change for the other users of that
fixup.
Fixes: 67f4c61a73e9 ("ALSA: hda/realtek: Add quirk for Legion S7 15IMH")
Cc: stable@vger.kernel.org
Link: https://github.com/CachyOS/linux-cachyos/issues/792
Signed-off-by: Matej Sochan <matej.sochan@gmail.com>
Link: https://patch.msgid.link/20261007-legion-s7-v1-1-8ea7fb7ee766@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 92 +++++++++++++++++++------------
1 file changed, 56 insertions(+), 36 deletions(-)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index ed76281856b1c..68b5648d51119 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -3937,6 +3937,7 @@ enum {
ALC236_FIXUP_HP_LIMIT_INT_MIC_BOOST,
ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS,
ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
+ ALC287_FIXUP_LEGION_S7_15IMH05_AMP,
ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
ALC298_FIXUP_LENOVO_C940_DUET7,
ALC287_FIXUP_LENOVO_YOGA_BOOK_9I,
@@ -4058,6 +4059,53 @@ static void alc700_fixup_intel_hades_canyon(struct hda_codec *codec,
alc_update_coef_idx(codec, 0x1b, 0x0400, 0x0400);
}
+static const struct hda_verb legion_amp_verbs[] = {
+ /* left speaker */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x41 },
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0xc },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x1a },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+
+ /* right speaker */
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x42 },
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0xc },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x2a },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+ { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
+ { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
+ {}
+};
+
+static void alc287_fixup_legion_s7_amp(struct hda_codec *codec,
+ const struct hda_fixup *fix, int action)
+{
+ if (action != HDA_FIXUP_ACT_INIT)
+ return;
+
+ snd_hda_sequence_write(codec, legion_amp_verbs);
+ /*
+ * The amplifiers accept the setup only a few ms after the first
+ * write (8 ms is the measured minimum on the test machine), so
+ * keep a margin.
+ */
+ msleep(20);
+ snd_hda_sequence_write(codec, legion_amp_verbs);
+}
+
static const struct hda_fixup alc269_fixups[] = {
[ALC233_FIXUP_WUJIE_SPEAKERS] = {
.type = HDA_FIXUP_PINS,
@@ -6054,41 +6102,13 @@ static const struct hda_fixup alc269_fixups[] = {
},
[ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS] = {
.type = HDA_FIXUP_VERBS,
- //.v.verbs = legion_15imhg05_coefs,
- .v.verbs = (const struct hda_verb[]) {
- // set left speaker Legion 7i.
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x41 },
-
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0xc },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x1a },
- { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
-
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
-
- // set right speaker Legion 7i.
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x24 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x42 },
-
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0xc },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x2a },
- { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
-
- { 0x20, AC_VERB_SET_COEF_INDEX, 0x26 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x2 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0x0 },
- { 0x20, AC_VERB_SET_PROC_COEF, 0xb020 },
- {}
- },
+ .v.verbs = legion_amp_verbs,
+ .chained = true,
+ .chain_id = ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
+ },
+ [ALC287_FIXUP_LEGION_S7_15IMH05_AMP] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc287_fixup_legion_s7_amp,
.chained = true,
.chain_id = ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
},
@@ -7549,7 +7569,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
*/
HDA_CODEC_QUIRK(0x17aa, 0x38d6, "Lenovo Yoga Pro 9 16IMH9", ALC287_FIXUP_TAS2781_I2C),
HDA_CODEC_QUIRK(0x17aa, 0x3855, "Legion 7 16ITHG6", ALC287_FIXUP_LEGION_16ITHG6),
- SND_PCI_QUIRK(0x17aa, 0x3811, "Legion S7 15IMH05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
+ SND_PCI_QUIRK(0x17aa, 0x3811, "Legion S7 15IMH05", ALC287_FIXUP_LEGION_S7_15IMH05_AMP),
SND_PCI_QUIRK(0x17aa, 0x3813, "Legion 7i 15IMHG05", ALC287_FIXUP_LEGION_15IMHG05_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x3818, "Lenovo C940 / Yoga Duet 7", ALC298_FIXUP_LENOVO_C940_DUET7),
SND_PCI_QUIRK(0x17aa, 0x3819, "Lenovo 13s Gen2 ITL", ALC287_FIXUP_13S_GEN2_SPEAKERS),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 562/686] spi: atmel-quadspi: add controller init callback
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (560 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 561/686] ALSA: hda/realtek: Fix silent speakers on Lenovo Legion S7 15IMH05 Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 563/686] spi: atmel-quadspi: use init callback for gclk variants Greg Kroah-Hartman
` (123 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Robert Marko, Mark Brown,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Marko <robert.marko@sartura.hr>
[ Upstream commit cbbd5a945e85e7835ac5792d855d85c20e40d1e3 ]
Allow controller variants to provide a custom initialization callback
through their capability data.
This prepares the driver for variants which require a different hardware
initialization sequence without adding SoC checks to the common path.
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
Link: https://patch.msgid.link/20260709112006.390742-3-robert.marko@sartura.hr
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 717e45f97246 ("spi: atmel-quadspi: balance runtime PM and pclk across system sleep")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/atmel-quadspi.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index d7a3d85d00c2f..6c2d3c00409bb 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -256,8 +256,11 @@ static const struct atmel_qspi_pcal pcal[ATMEL_QSPI_PCAL_ARRAY_SIZE] = {
{200000000, 7},
};
+struct atmel_qspi;
+
struct atmel_qspi_caps {
u32 max_speed_hz;
+ int (*init)(struct atmel_qspi *aq);
bool has_qspick;
bool has_gclk;
bool has_ricr;
@@ -1156,6 +1159,9 @@ static int atmel_qspi_sama7g5_setup(struct spi_device *spi)
/* The controller can communicate with a single peripheral device (target). */
aq->target_max_speed_hz = spi->max_speed_hz;
+ if (aq->caps->init)
+ return aq->caps->init(aq);
+
return atmel_qspi_sama7g5_init(aq);
}
@@ -1571,6 +1577,9 @@ static int __maybe_unused atmel_qspi_resume(struct device *dev)
return ret;
}
+ if (aq->caps->init)
+ return aq->caps->init(aq);
+
if (aq->caps->has_gclk)
return atmel_qspi_sama7g5_init(aq);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 563/686] spi: atmel-quadspi: use init callback for gclk variants
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (561 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 562/686] spi: atmel-quadspi: add controller init callback Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 564/686] spi: atmel-quadspi: balance runtime PM and pclk across system sleep Greg Kroah-Hartman
` (122 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Robert Marko, Mark Brown,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Marko <robert.marko@sartura.hr>
[ Upstream commit b881f1d8d1dfbc4480776d3b16f80261a5a68cbc ]
Assign the existing SAMA7G5 initialization routine to every generic
clock variant and dispatch initialization exclusively through the
capability callback.
This keeps hardware capabilities separate from initialization selection
and lets variants override the sequence explicitly.
Signed-off-by: Robert Marko <robert.marko@sartura.hr>
Link: https://patch.msgid.link/20260709112006.390742-4-robert.marko@sartura.hr
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 717e45f97246 ("spi: atmel-quadspi: balance runtime PM and pclk across system sleep")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/atmel-quadspi.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index 6c2d3c00409bb..a917530f81741 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -1159,10 +1159,7 @@ static int atmel_qspi_sama7g5_setup(struct spi_device *spi)
/* The controller can communicate with a single peripheral device (target). */
aq->target_max_speed_hz = spi->max_speed_hz;
- if (aq->caps->init)
- return aq->caps->init(aq);
-
- return atmel_qspi_sama7g5_init(aq);
+ return aq->caps->init(aq);
}
static int atmel_qspi_setup(struct spi_device *spi)
@@ -1577,11 +1574,8 @@ static int __maybe_unused atmel_qspi_resume(struct device *dev)
return ret;
}
- if (aq->caps->init)
- return aq->caps->init(aq);
-
if (aq->caps->has_gclk)
- return atmel_qspi_sama7g5_init(aq);
+ return aq->caps->init(aq);
ret = pm_runtime_force_resume(dev);
if (ret < 0)
@@ -1639,6 +1633,7 @@ static const struct atmel_qspi_caps atmel_sam9x60_qspi_caps = {
static const struct atmel_qspi_caps atmel_sam9x7_ospi_caps = {
.max_speed_hz = SAM9X7_QSPI_MAX_SPEED_HZ,
+ .init = atmel_qspi_sama7g5_init,
.has_gclk = true,
.octal = true,
.has_dma = true,
@@ -1649,6 +1644,7 @@ static const struct atmel_qspi_caps atmel_sam9x7_ospi_caps = {
static const struct atmel_qspi_caps atmel_sama7d65_ospi_caps = {
.max_speed_hz = SAMA7G5_QSPI0_MAX_SPEED_HZ,
+ .init = atmel_qspi_sama7g5_init,
.has_gclk = true,
.octal = true,
.has_dma = true,
@@ -1659,6 +1655,7 @@ static const struct atmel_qspi_caps atmel_sama7d65_ospi_caps = {
static const struct atmel_qspi_caps atmel_sama7d65_qspi_caps = {
.max_speed_hz = SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ,
+ .init = atmel_qspi_sama7g5_init,
.has_gclk = true,
.has_dma = true,
.has_2xgclk = true,
@@ -1667,6 +1664,7 @@ static const struct atmel_qspi_caps atmel_sama7d65_qspi_caps = {
static const struct atmel_qspi_caps atmel_sama7g5_ospi_caps = {
.max_speed_hz = SAMA7G5_QSPI0_MAX_SPEED_HZ,
+ .init = atmel_qspi_sama7g5_init,
.has_gclk = true,
.octal = true,
.has_dma = true,
@@ -1676,6 +1674,7 @@ static const struct atmel_qspi_caps atmel_sama7g5_ospi_caps = {
static const struct atmel_qspi_caps atmel_sama7g5_qspi_caps = {
.max_speed_hz = SAMA7G5_QSPI1_SDR_MAX_SPEED_HZ,
+ .init = atmel_qspi_sama7g5_init,
.has_gclk = true,
.has_dma = true,
.has_dllon = true,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 564/686] spi: atmel-quadspi: balance runtime PM and pclk across system sleep
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (562 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 563/686] spi: atmel-quadspi: use init callback for gclk variants Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 565/686] vfio/pci: Restore 8-byte ioeventfd support Greg Kroah-Hartman
` (121 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Karl Mehltretter,
Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 717e45f97246d1070cdf86ccd7a0fb872b45933a ]
On the controllers with a generic clock (SAMA7G5, SAMA7D65, SAM9X7 and
LAN969x), atmel_qspi_suspend() takes a runtime PM reference and returns
without dropping it or suspending the device. It disables the peripheral
clock directly. atmel_qspi_resume() only prepares the peripheral clock
and then reinitializes the controller with that clock still off.
On a SAM9X75 Curiosity board, the tested standby and mem resumes
failed:
atmel_qspi f0014000.spi: PM: failed to resume: error -110
spi-nor spi0.0: resume() failed
Reading the flash afterwards returned no data. The runtime usage count
grew by one with each cycle, and the second suspend disabled the
peripheral clock again:
WARNING: drivers/clk/clk.c:1257 at clk_core_disable+0x6c/0xcc
qspi_clk already disabled
Use the same runtime PM sequence as the other variants. Suspend disables
the controller and forces a runtime suspend. Resume forces a runtime
resume, which enables the peripheral clock, before it runs the init
callback, and drops the reference afterwards. With this change the
tested resumes succeed on the board in both modes, the controller
returns to runtime suspend, and the flash reads back.
Fixes: 5af42209a4d2 ("spi: atmel-quadspi: Add support for sama7g5 QSPI")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260709112006.390742-1-robert.marko%40sartura.hr?part=3
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Link: https://patch.msgid.link/20260923012950.15651-1-kmehltretter@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/spi/atmel-quadspi.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c
index a917530f81741..d3c14e2ec8c86 100644
--- a/drivers/spi/atmel-quadspi.c
+++ b/drivers/spi/atmel-quadspi.c
@@ -1543,12 +1543,14 @@ static int __maybe_unused atmel_qspi_suspend(struct device *dev)
if (aq->caps->has_gclk) {
ret = atmel_qspi_sama7g5_suspend(aq);
- clk_disable_unprepare(aq->pclk);
- return ret;
+ if (ret) {
+ pm_runtime_put_autosuspend(dev);
+ return ret;
+ }
+ } else {
+ atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
}
- atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
-
pm_runtime_mark_last_busy(dev);
pm_runtime_force_suspend(dev);
@@ -1574,20 +1576,20 @@ static int __maybe_unused atmel_qspi_resume(struct device *dev)
return ret;
}
- if (aq->caps->has_gclk)
- return aq->caps->init(aq);
-
ret = pm_runtime_force_resume(dev);
if (ret < 0)
return ret;
- atmel_qspi_init(aq);
-
- atmel_qspi_write(aq->scr, aq, QSPI_SCR);
+ if (aq->caps->has_gclk) {
+ ret = aq->caps->init(aq);
+ } else {
+ atmel_qspi_init(aq);
+ atmel_qspi_write(aq->scr, aq, QSPI_SCR);
+ }
pm_runtime_put_autosuspend(dev);
- return 0;
+ return ret;
}
static int __maybe_unused atmel_qspi_runtime_suspend(struct device *dev)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 565/686] vfio/pci: Restore 8-byte ioeventfd support
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (563 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 564/686] spi: atmel-quadspi: balance runtime PM and pclk across system sleep Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 566/686] ata: libata: Add an argument to ata_eh_reset() Greg Kroah-Hartman
` (120 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Li RongQing, Alex Williamson,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li RongQing <lirongqing@baidu.com>
[ Upstream commit b30b52c2fb82e6d38ee2845a4d85e8254b44f3d8 ]
Commit b44a06bd28f2 ("vfio/pci: Remove #ifdef iowrite64 and #ifdef
ioread64") inadvertently converted a conditional 8-byte rejection
into an unconditional one.
Originally, 'count == 8' was rejected only if iowrite64 was undefined
(#ifndef iowrite64). When iowrite64 became globally available via generic
fallbacks, this rejection became dead code, allowing 8-byte ioeventfds.
However, b44a06bd28f2 removed the #ifndef wrappers but left the nested
'if (count == 8) return -EINVAL;' intact, breaking all 8-byte
registrations.
Drop the unconditional check to restore 8-byte ioeventfd support,
matching the original intent.
Fixes: b44a06bd28f2 ("vfio/pci: Remove #ifdef iowrite64 and #ifdef ioread64")
Cc: stable@vger.kernel.org
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Link: https://lore.kernel.org/r/20260922040013.2188-1-lirongqing@baidu.com
Signed-off-by: Alex Williamson <alex@shazbot.org>
[ sashal: Adjusted context to retain vfio_pci_core_setup_barmap() instead of vfio_pci_core_get_iomap(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vfio/pci/vfio_pci_rdwr.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/drivers/vfio/pci/vfio_pci_rdwr.c b/drivers/vfio/pci/vfio_pci_rdwr.c
index 25380b7dfe18a..8338708b99c1e 100644
--- a/drivers/vfio/pci/vfio_pci_rdwr.c
+++ b/drivers/vfio/pci/vfio_pci_rdwr.c
@@ -449,9 +449,6 @@ int vfio_pci_ioeventfd(struct vfio_pci_core_device *vdev, loff_t offset,
pos >= vdev->msix_offset + vdev->msix_size))
return -EINVAL;
- if (count == 8)
- return -EINVAL;
-
ret = vfio_pci_core_setup_barmap(vdev, bar);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 566/686] ata: libata: Add an argument to ata_eh_reset()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (564 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 565/686] vfio/pci: Restore 8-byte ioeventfd support Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 567/686] ata: sata_inic162x: remove dangerous broken driver Greg Kroah-Hartman
` (119 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bart Van Assche, Niklas Cassel,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <bvanassche@acm.org>
[ Upstream commit 4b3c2ca268b0a66093793466e02d8566d642f19c ]
Pass the ATA port pointer as first argument to ata_eh_reset(). No
functionality has been changed. This patch prepares for enabling lock
context analysis. Without this patch, lockdep_assert_held() statements
would have to be added before each ata_eh_reset() call because the
compiler doesn't know that ap->link.p == ap. See also ata_link_init().
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Stable-dep-of: 96fdeb7e3fd8 ("ata: sata_inic162x: remove dangerous broken driver")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ata/libata-eh.c | 6 +++---
drivers/ata/libata-pmp.c | 2 +-
drivers/ata/libata.h | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index f21efb0f6419f..9d35b4f8d3929 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -2812,10 +2812,9 @@ static bool ata_eh_followup_srst_needed(struct ata_link *link, int rc)
return false;
}
-int ata_eh_reset(struct ata_link *link, int classify,
+int ata_eh_reset(struct ata_port *ap, struct ata_link *link, int classify,
struct ata_reset_operations *reset_ops)
{
- struct ata_port *ap = link->ap;
struct ata_link *slave = ap->slave_link;
struct ata_eh_context *ehc = &link->eh_context;
struct ata_eh_context *sehc = slave ? &slave->eh_context : NULL;
@@ -3863,7 +3862,8 @@ int ata_eh_recover(struct ata_port *ap, struct ata_reset_operations *reset_ops,
if (!(ehc->i.action & ATA_EH_RESET))
continue;
- rc = ata_eh_reset(link, ata_link_nr_vacant(link), reset_ops);
+ rc = ata_eh_reset(ap, link, ata_link_nr_vacant(link),
+ reset_ops);
if (rc) {
ata_link_err(link, "reset failed, giving up\n");
goto out;
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index 99c67dbfb7536..c3b3af28d17c9 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -796,7 +796,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
struct ata_link *tlink;
/* reset */
- rc = ata_eh_reset(link, 0, reset_ops);
+ rc = ata_eh_reset(ap, link, 0, reset_ops);
if (rc) {
ata_link_err(link, "failed to reset PMP, giving up\n");
goto fail;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 9f96ca2acfd90..506a649b73d58 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -192,8 +192,8 @@ extern void ata_eh_done(struct ata_link *link, struct ata_device *dev,
extern void ata_eh_autopsy(struct ata_port *ap);
const char *ata_get_cmd_name(u8 command);
extern void ata_eh_report(struct ata_port *ap);
-extern int ata_eh_reset(struct ata_link *link, int classify,
- struct ata_reset_operations *reset_ops);
+extern int ata_eh_reset(struct ata_port *ap, struct ata_link *link,
+ int classify, struct ata_reset_operations *reset_ops);
extern int ata_eh_recover(struct ata_port *ap,
struct ata_reset_operations *reset_ops,
struct ata_link **r_failed_disk);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 567/686] ata: sata_inic162x: remove dangerous broken driver
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (565 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 566/686] ata: libata: Add an argument to ata_eh_reset() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 568/686] f2fs: zone: fix to avoid bio split on sequential zone Greg Kroah-Hartman
` (118 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ethan Nelson-Moore, Damien Le Moal,
Niklas Cassel, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Nelson-Moore <enelsonmoore@gmail.com>
[ Upstream commit 96fdeb7e3fd8d937f8351ed90824c9d904e590a1 ]
The sata_inic162x driver was labeled as "very experimental" in
commit bb9696192826 ("libata: make it clear that sata_inic162x is
experimental") due to data corruption issues, but not marked as broken.
Since then, no changes have been made to it that could fix these
issues. Since the driver was not marked as broken, and the message
about potential data corruption is only visible in the code and dmesg,
it is possible that someone could enable the driver without realizing
its potential for data corruption. Remove the driver to protect users'
data.
Fixes: 1fd7a697a37b ("sata_inic162x: finally, driver for initio 162x SATA controllers, take #2")
Cc: stable@vger.kernel.org
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Link: https://lore.kernel.org/r/20260915014714.41274-1-enelsonmoore@gmail.com
Signed-off-by: Niklas Cassel <cassel@kernel.org>
[ sashal: adapted whole-file deletion to account for the missing __must_hold() annotation on inic_error_handler() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ata/Kconfig | 7 -
drivers/ata/Makefile | 1 -
drivers/ata/sata_inic162x.c | 902 ------------------------------------
3 files changed, 910 deletions(-)
delete mode 100644 drivers/ata/sata_inic162x.c
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 120a2b7067fc7..ff81f707d0b23 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -329,13 +329,6 @@ config SATA_AHCI_SEATTLE
If unsure, say N
-config SATA_INIC162X
- tristate "Initio 162x SATA support (Very Experimental)"
- depends on PCI
- select SATA_HOST
- help
- This option enables support for Initio 162x Serial ATA.
-
config SATA_ACARD_AHCI
tristate "ACard AHCI variant (ATP 8620)"
depends on PCI
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 20e6645ab7371..81e04e96b807e 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -9,7 +9,6 @@ obj-$(CONFIG_SATA_AHCI_SEATTLE) += ahci_seattle.o libahci.o libahci_platform.o
obj-$(CONFIG_SATA_AHCI_PLATFORM) += ahci_platform.o libahci.o libahci_platform.o
obj-$(CONFIG_SATA_FSL) += sata_fsl.o
obj-$(CONFIG_SATA_GEMINI) += sata_gemini.o
-obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o
obj-$(CONFIG_SATA_HIGHBANK) += sata_highbank.o libahci.o
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
deleted file mode 100644
index 46a8c20daf180..0000000000000
--- a/drivers/ata/sata_inic162x.c
+++ /dev/null
@@ -1,902 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * sata_inic162x.c - Driver for Initio 162x SATA controllers
- *
- * Copyright 2006 SUSE Linux Products GmbH
- * Copyright 2006 Tejun Heo <teheo@novell.com>
- *
- * **** WARNING ****
- *
- * This driver never worked properly and unfortunately data corruption is
- * relatively common. There isn't anyone working on the driver and there's
- * no support from the vendor. Do not use this driver in any production
- * environment.
- *
- * http://thread.gmane.org/gmane.linux.debian.devel.bugs.rc/378525/focus=54491
- * https://bugzilla.kernel.org/show_bug.cgi?id=60565
- *
- * *****************
- *
- * This controller is eccentric and easily locks up if something isn't
- * right. Documentation is available at initio's website but it only
- * documents registers (not programming model).
- *
- * This driver has interesting history. The first version was written
- * from the documentation and a 2.4 IDE driver posted on a Taiwan
- * company, which didn't use any IDMA features and couldn't handle
- * LBA48. The resulting driver couldn't handle LBA48 devices either
- * making it pretty useless.
- *
- * After a while, initio picked the driver up, renamed it to
- * sata_initio162x, updated it to use IDMA for ATA DMA commands and
- * posted it on their website. It only used ATA_PROT_DMA for IDMA and
- * attaching both devices and issuing IDMA and !IDMA commands
- * simultaneously broke it due to PIRQ masking interaction but it did
- * show how to use the IDMA (ADMA + some initio specific twists)
- * engine.
- *
- * Then, I picked up their changes again and here's the usable driver
- * which uses IDMA for everything. Everything works now including
- * LBA48, CD/DVD burning, suspend/resume and hotplug. There are some
- * issues tho. Result Tf is not resported properly, NCQ isn't
- * supported yet and CD/DVD writing works with DMA assisted PIO
- * protocol (which, for native SATA devices, shouldn't cause any
- * noticeable difference).
- *
- * Anyways, so, here's finally a working driver for inic162x. Enjoy!
- *
- * initio: If you guys wanna improve the driver regarding result TF
- * access and other stuff, please feel free to contact me. I'll be
- * happy to assist.
- */
-
-#include <linux/gfp.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/pci.h>
-#include <scsi/scsi_host.h>
-#include <linux/libata.h>
-#include <linux/blkdev.h>
-#include <scsi/scsi_device.h>
-
-#define DRV_NAME "sata_inic162x"
-#define DRV_VERSION "0.4"
-
-enum {
- MMIO_BAR_PCI = 5,
- MMIO_BAR_CARDBUS = 1,
-
- NR_PORTS = 2,
-
- IDMA_CPB_TBL_SIZE = 4 * 32,
-
- INIC_DMA_BOUNDARY = 0xffffff,
-
- HOST_ACTRL = 0x08,
- HOST_CTL = 0x7c,
- HOST_STAT = 0x7e,
- HOST_IRQ_STAT = 0xbc,
- HOST_IRQ_MASK = 0xbe,
-
- PORT_SIZE = 0x40,
-
- /* registers for ATA TF operation */
- PORT_TF_DATA = 0x00,
- PORT_TF_FEATURE = 0x01,
- PORT_TF_NSECT = 0x02,
- PORT_TF_LBAL = 0x03,
- PORT_TF_LBAM = 0x04,
- PORT_TF_LBAH = 0x05,
- PORT_TF_DEVICE = 0x06,
- PORT_TF_COMMAND = 0x07,
- PORT_TF_ALT_STAT = 0x08,
- PORT_IRQ_STAT = 0x09,
- PORT_IRQ_MASK = 0x0a,
- PORT_PRD_CTL = 0x0b,
- PORT_PRD_ADDR = 0x0c,
- PORT_PRD_XFERLEN = 0x10,
- PORT_CPB_CPBLAR = 0x18,
- PORT_CPB_PTQFIFO = 0x1c,
-
- /* IDMA register */
- PORT_IDMA_CTL = 0x14,
- PORT_IDMA_STAT = 0x16,
-
- PORT_RPQ_FIFO = 0x1e,
- PORT_RPQ_CNT = 0x1f,
-
- PORT_SCR = 0x20,
-
- /* HOST_CTL bits */
- HCTL_LEDEN = (1 << 3), /* enable LED operation */
- HCTL_IRQOFF = (1 << 8), /* global IRQ off */
- HCTL_FTHD0 = (1 << 10), /* fifo threshold 0 */
- HCTL_FTHD1 = (1 << 11), /* fifo threshold 1*/
- HCTL_PWRDWN = (1 << 12), /* power down PHYs */
- HCTL_SOFTRST = (1 << 13), /* global reset (no phy reset) */
- HCTL_RPGSEL = (1 << 15), /* register page select */
-
- HCTL_KNOWN_BITS = HCTL_IRQOFF | HCTL_PWRDWN | HCTL_SOFTRST |
- HCTL_RPGSEL,
-
- /* HOST_IRQ_(STAT|MASK) bits */
- HIRQ_PORT0 = (1 << 0),
- HIRQ_PORT1 = (1 << 1),
- HIRQ_SOFT = (1 << 14),
- HIRQ_GLOBAL = (1 << 15), /* STAT only */
-
- /* PORT_IRQ_(STAT|MASK) bits */
- PIRQ_OFFLINE = (1 << 0), /* device unplugged */
- PIRQ_ONLINE = (1 << 1), /* device plugged */
- PIRQ_COMPLETE = (1 << 2), /* completion interrupt */
- PIRQ_FATAL = (1 << 3), /* fatal error */
- PIRQ_ATA = (1 << 4), /* ATA interrupt */
- PIRQ_REPLY = (1 << 5), /* reply FIFO not empty */
- PIRQ_PENDING = (1 << 7), /* port IRQ pending (STAT only) */
-
- PIRQ_ERR = PIRQ_OFFLINE | PIRQ_ONLINE | PIRQ_FATAL,
- PIRQ_MASK_DEFAULT = PIRQ_REPLY | PIRQ_ATA,
- PIRQ_MASK_FREEZE = 0xff,
-
- /* PORT_PRD_CTL bits */
- PRD_CTL_START = (1 << 0),
- PRD_CTL_WR = (1 << 3),
- PRD_CTL_DMAEN = (1 << 7), /* DMA enable */
-
- /* PORT_IDMA_CTL bits */
- IDMA_CTL_RST_ATA = (1 << 2), /* hardreset ATA bus */
- IDMA_CTL_RST_IDMA = (1 << 5), /* reset IDMA machinery */
- IDMA_CTL_GO = (1 << 7), /* IDMA mode go */
- IDMA_CTL_ATA_NIEN = (1 << 8), /* ATA IRQ disable */
-
- /* PORT_IDMA_STAT bits */
- IDMA_STAT_PERR = (1 << 0), /* PCI ERROR MODE */
- IDMA_STAT_CPBERR = (1 << 1), /* ADMA CPB error */
- IDMA_STAT_LGCY = (1 << 3), /* ADMA legacy */
- IDMA_STAT_UIRQ = (1 << 4), /* ADMA unsolicited irq */
- IDMA_STAT_STPD = (1 << 5), /* ADMA stopped */
- IDMA_STAT_PSD = (1 << 6), /* ADMA pause */
- IDMA_STAT_DONE = (1 << 7), /* ADMA done */
-
- IDMA_STAT_ERR = IDMA_STAT_PERR | IDMA_STAT_CPBERR,
-
- /* CPB Control Flags*/
- CPB_CTL_VALID = (1 << 0), /* CPB valid */
- CPB_CTL_QUEUED = (1 << 1), /* queued command */
- CPB_CTL_DATA = (1 << 2), /* data, rsvd in datasheet */
- CPB_CTL_IEN = (1 << 3), /* PCI interrupt enable */
- CPB_CTL_DEVDIR = (1 << 4), /* device direction control */
-
- /* CPB Response Flags */
- CPB_RESP_DONE = (1 << 0), /* ATA command complete */
- CPB_RESP_REL = (1 << 1), /* ATA release */
- CPB_RESP_IGNORED = (1 << 2), /* CPB ignored */
- CPB_RESP_ATA_ERR = (1 << 3), /* ATA command error */
- CPB_RESP_SPURIOUS = (1 << 4), /* ATA spurious interrupt error */
- CPB_RESP_UNDERFLOW = (1 << 5), /* APRD deficiency length error */
- CPB_RESP_OVERFLOW = (1 << 6), /* APRD exccess length error */
- CPB_RESP_CPB_ERR = (1 << 7), /* CPB error flag */
-
- /* PRD Control Flags */
- PRD_DRAIN = (1 << 1), /* ignore data excess */
- PRD_CDB = (1 << 2), /* atapi packet command pointer */
- PRD_DIRECT_INTR = (1 << 3), /* direct interrupt */
- PRD_DMA = (1 << 4), /* data transfer method */
- PRD_WRITE = (1 << 5), /* data dir, rsvd in datasheet */
- PRD_IOM = (1 << 6), /* io/memory transfer */
- PRD_END = (1 << 7), /* APRD chain end */
-};
-
-/* Comman Parameter Block */
-struct inic_cpb {
- u8 resp_flags; /* Response Flags */
- u8 error; /* ATA Error */
- u8 status; /* ATA Status */
- u8 ctl_flags; /* Control Flags */
- __le32 len; /* Total Transfer Length */
- __le32 prd; /* First PRD pointer */
- u8 rsvd[4];
- /* 16 bytes */
- u8 feature; /* ATA Feature */
- u8 hob_feature; /* ATA Ex. Feature */
- u8 device; /* ATA Device/Head */
- u8 mirctl; /* Mirror Control */
- u8 nsect; /* ATA Sector Count */
- u8 hob_nsect; /* ATA Ex. Sector Count */
- u8 lbal; /* ATA Sector Number */
- u8 hob_lbal; /* ATA Ex. Sector Number */
- u8 lbam; /* ATA Cylinder Low */
- u8 hob_lbam; /* ATA Ex. Cylinder Low */
- u8 lbah; /* ATA Cylinder High */
- u8 hob_lbah; /* ATA Ex. Cylinder High */
- u8 command; /* ATA Command */
- u8 ctl; /* ATA Control */
- u8 slave_error; /* Slave ATA Error */
- u8 slave_status; /* Slave ATA Status */
- /* 32 bytes */
-} __packed;
-
-/* Physical Region Descriptor */
-struct inic_prd {
- __le32 mad; /* Physical Memory Address */
- __le16 len; /* Transfer Length */
- u8 rsvd;
- u8 flags; /* Control Flags */
-} __packed;
-
-struct inic_pkt {
- struct inic_cpb cpb;
- struct inic_prd prd[LIBATA_MAX_PRD + 1]; /* + 1 for cdb */
- u8 cdb[ATAPI_CDB_LEN];
-} __packed;
-
-struct inic_host_priv {
- void __iomem *mmio_base;
- u16 cached_hctl;
-};
-
-struct inic_port_priv {
- struct inic_pkt *pkt;
- dma_addr_t pkt_dma;
- u32 *cpb_tbl;
- dma_addr_t cpb_tbl_dma;
-};
-
-static const struct scsi_host_template inic_sht = {
- ATA_BASE_SHT(DRV_NAME),
- .sg_tablesize = LIBATA_MAX_PRD, /* maybe it can be larger? */
-
- /*
- * This controller is braindamaged. dma_boundary is 0xffff like others
- * but it will lock up the whole machine HARD if 65536 byte PRD entry
- * is fed. Reduce maximum segment size.
- */
- .dma_boundary = INIC_DMA_BOUNDARY,
- .max_segment_size = 65536 - 512,
-};
-
-static const int scr_map[] = {
- [SCR_STATUS] = 0,
- [SCR_ERROR] = 1,
- [SCR_CONTROL] = 2,
-};
-
-static void __iomem *inic_port_base(struct ata_port *ap)
-{
- struct inic_host_priv *hpriv = ap->host->private_data;
-
- return hpriv->mmio_base + ap->port_no * PORT_SIZE;
-}
-
-static void inic_reset_port(void __iomem *port_base)
-{
- void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
-
- /* stop IDMA engine */
- readw(idma_ctl); /* flush */
- msleep(1);
-
- /* mask IRQ and assert reset */
- writew(IDMA_CTL_RST_IDMA, idma_ctl);
- readw(idma_ctl); /* flush */
- msleep(1);
-
- /* release reset */
- writew(0, idma_ctl);
-
- /* clear irq */
- writeb(0xff, port_base + PORT_IRQ_STAT);
-}
-
-static int inic_scr_read(struct ata_link *link, unsigned sc_reg, u32 *val)
-{
- void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;
-
- if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
- return -EINVAL;
-
- *val = readl(scr_addr + scr_map[sc_reg] * 4);
-
- /* this controller has stuck DIAG.N, ignore it */
- if (sc_reg == SCR_ERROR)
- *val &= ~SERR_PHYRDY_CHG;
- return 0;
-}
-
-static int inic_scr_write(struct ata_link *link, unsigned sc_reg, u32 val)
-{
- void __iomem *scr_addr = inic_port_base(link->ap) + PORT_SCR;
-
- if (unlikely(sc_reg >= ARRAY_SIZE(scr_map)))
- return -EINVAL;
-
- writel(val, scr_addr + scr_map[sc_reg] * 4);
- return 0;
-}
-
-static void inic_stop_idma(struct ata_port *ap)
-{
- void __iomem *port_base = inic_port_base(ap);
-
- readb(port_base + PORT_RPQ_FIFO);
- readb(port_base + PORT_RPQ_CNT);
- writew(0, port_base + PORT_IDMA_CTL);
-}
-
-static void inic_host_err_intr(struct ata_port *ap, u8 irq_stat, u16 idma_stat)
-{
- struct ata_eh_info *ehi = &ap->link.eh_info;
- struct inic_port_priv *pp = ap->private_data;
- struct inic_cpb *cpb = &pp->pkt->cpb;
- bool freeze = false;
-
- ata_ehi_clear_desc(ehi);
- ata_ehi_push_desc(ehi, "irq_stat=0x%x idma_stat=0x%x",
- irq_stat, idma_stat);
-
- inic_stop_idma(ap);
-
- if (irq_stat & (PIRQ_OFFLINE | PIRQ_ONLINE)) {
- ata_ehi_push_desc(ehi, "hotplug");
- ata_ehi_hotplugged(ehi);
- freeze = true;
- }
-
- if (idma_stat & IDMA_STAT_PERR) {
- ata_ehi_push_desc(ehi, "PCI error");
- freeze = true;
- }
-
- if (idma_stat & IDMA_STAT_CPBERR) {
- ata_ehi_push_desc(ehi, "CPB error");
-
- if (cpb->resp_flags & CPB_RESP_IGNORED) {
- __ata_ehi_push_desc(ehi, " ignored");
- ehi->err_mask |= AC_ERR_INVALID;
- freeze = true;
- }
-
- if (cpb->resp_flags & CPB_RESP_ATA_ERR)
- ehi->err_mask |= AC_ERR_DEV;
-
- if (cpb->resp_flags & CPB_RESP_SPURIOUS) {
- __ata_ehi_push_desc(ehi, " spurious-intr");
- ehi->err_mask |= AC_ERR_HSM;
- freeze = true;
- }
-
- if (cpb->resp_flags &
- (CPB_RESP_UNDERFLOW | CPB_RESP_OVERFLOW)) {
- __ata_ehi_push_desc(ehi, " data-over/underflow");
- ehi->err_mask |= AC_ERR_HSM;
- freeze = true;
- }
- }
-
- if (freeze)
- ata_port_freeze(ap);
- else
- ata_port_abort(ap);
-}
-
-static void inic_host_intr(struct ata_port *ap)
-{
- void __iomem *port_base = inic_port_base(ap);
- struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
- u8 irq_stat;
- u16 idma_stat;
-
- /* read and clear IRQ status */
- irq_stat = readb(port_base + PORT_IRQ_STAT);
- writeb(irq_stat, port_base + PORT_IRQ_STAT);
- idma_stat = readw(port_base + PORT_IDMA_STAT);
-
- if (unlikely((irq_stat & PIRQ_ERR) || (idma_stat & IDMA_STAT_ERR)))
- inic_host_err_intr(ap, irq_stat, idma_stat);
-
- if (unlikely(!qc))
- goto spurious;
-
- if (likely(idma_stat & IDMA_STAT_DONE)) {
- inic_stop_idma(ap);
-
- /* Depending on circumstances, device error
- * isn't reported by IDMA, check it explicitly.
- */
- if (unlikely(readb(port_base + PORT_TF_COMMAND) &
- (ATA_DF | ATA_ERR)))
- qc->err_mask |= AC_ERR_DEV;
-
- ata_qc_complete(qc);
- return;
- }
-
- spurious:
- ata_port_warn(ap, "unhandled interrupt: cmd=0x%x irq_stat=0x%x idma_stat=0x%x\n",
- qc ? qc->tf.command : 0xff, irq_stat, idma_stat);
-}
-
-static irqreturn_t inic_interrupt(int irq, void *dev_instance)
-{
- struct ata_host *host = dev_instance;
- struct inic_host_priv *hpriv = host->private_data;
- u16 host_irq_stat;
- int i, handled = 0;
-
- host_irq_stat = readw(hpriv->mmio_base + HOST_IRQ_STAT);
-
- if (unlikely(!(host_irq_stat & HIRQ_GLOBAL)))
- goto out;
-
- spin_lock(&host->lock);
-
- for (i = 0; i < NR_PORTS; i++)
- if (host_irq_stat & (HIRQ_PORT0 << i)) {
- inic_host_intr(host->ports[i]);
- handled++;
- }
-
- spin_unlock(&host->lock);
-
- out:
- return IRQ_RETVAL(handled);
-}
-
-static int inic_check_atapi_dma(struct ata_queued_cmd *qc)
-{
- /* For some reason ATAPI_PROT_DMA doesn't work for some
- * commands including writes and other misc ops. Use PIO
- * protocol instead, which BTW is driven by the DMA engine
- * anyway, so it shouldn't make much difference for native
- * SATA devices.
- */
- if (atapi_cmd_type(qc->cdb[0]) == READ)
- return 0;
- return 1;
-}
-
-static void inic_fill_sg(struct inic_prd *prd, struct ata_queued_cmd *qc)
-{
- struct scatterlist *sg;
- unsigned int si;
- u8 flags = 0;
-
- if (qc->tf.flags & ATA_TFLAG_WRITE)
- flags |= PRD_WRITE;
-
- if (ata_is_dma(qc->tf.protocol))
- flags |= PRD_DMA;
-
- for_each_sg(qc->sg, sg, qc->n_elem, si) {
- prd->mad = cpu_to_le32(sg_dma_address(sg));
- prd->len = cpu_to_le16(sg_dma_len(sg));
- prd->flags = flags;
- prd++;
- }
-
- WARN_ON(!si);
- prd[-1].flags |= PRD_END;
-}
-
-static enum ata_completion_errors inic_qc_prep(struct ata_queued_cmd *qc)
-{
- struct inic_port_priv *pp = qc->ap->private_data;
- struct inic_pkt *pkt = pp->pkt;
- struct inic_cpb *cpb = &pkt->cpb;
- struct inic_prd *prd = pkt->prd;
- bool is_atapi = ata_is_atapi(qc->tf.protocol);
- bool is_data = ata_is_data(qc->tf.protocol);
- unsigned int cdb_len = 0;
-
- if (is_atapi)
- cdb_len = qc->dev->cdb_len;
-
- /* prepare packet, based on initio driver */
- memset(pkt, 0, sizeof(struct inic_pkt));
-
- cpb->ctl_flags = CPB_CTL_VALID | CPB_CTL_IEN;
- if (is_atapi || is_data)
- cpb->ctl_flags |= CPB_CTL_DATA;
-
- cpb->len = cpu_to_le32(qc->nbytes + cdb_len);
- cpb->prd = cpu_to_le32(pp->pkt_dma + offsetof(struct inic_pkt, prd));
-
- cpb->device = qc->tf.device;
- cpb->feature = qc->tf.feature;
- cpb->nsect = qc->tf.nsect;
- cpb->lbal = qc->tf.lbal;
- cpb->lbam = qc->tf.lbam;
- cpb->lbah = qc->tf.lbah;
-
- if (qc->tf.flags & ATA_TFLAG_LBA48) {
- cpb->hob_feature = qc->tf.hob_feature;
- cpb->hob_nsect = qc->tf.hob_nsect;
- cpb->hob_lbal = qc->tf.hob_lbal;
- cpb->hob_lbam = qc->tf.hob_lbam;
- cpb->hob_lbah = qc->tf.hob_lbah;
- }
-
- cpb->command = qc->tf.command;
- /* don't load ctl - dunno why. it's like that in the initio driver */
-
- /* setup PRD for CDB */
- if (is_atapi) {
- memcpy(pkt->cdb, qc->cdb, ATAPI_CDB_LEN);
- prd->mad = cpu_to_le32(pp->pkt_dma +
- offsetof(struct inic_pkt, cdb));
- prd->len = cpu_to_le16(cdb_len);
- prd->flags = PRD_CDB | PRD_WRITE;
- if (!is_data)
- prd->flags |= PRD_END;
- prd++;
- }
-
- /* setup sg table */
- if (is_data)
- inic_fill_sg(prd, qc);
-
- pp->cpb_tbl[0] = pp->pkt_dma;
-
- return AC_ERR_OK;
-}
-
-static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- void __iomem *port_base = inic_port_base(ap);
-
- /* fire up the ADMA engine */
- writew(HCTL_FTHD0 | HCTL_LEDEN, port_base + HOST_CTL);
- writew(IDMA_CTL_GO, port_base + PORT_IDMA_CTL);
- writeb(0, port_base + PORT_CPB_PTQFIFO);
-
- return 0;
-}
-
-static void inic_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- void __iomem *port_base = inic_port_base(ap);
-
- tf->error = readb(port_base + PORT_TF_FEATURE);
- tf->nsect = readb(port_base + PORT_TF_NSECT);
- tf->lbal = readb(port_base + PORT_TF_LBAL);
- tf->lbam = readb(port_base + PORT_TF_LBAM);
- tf->lbah = readb(port_base + PORT_TF_LBAH);
- tf->device = readb(port_base + PORT_TF_DEVICE);
- tf->status = readb(port_base + PORT_TF_COMMAND);
-}
-
-static void inic_qc_fill_rtf(struct ata_queued_cmd *qc)
-{
- struct ata_taskfile *rtf = &qc->result_tf;
- struct ata_taskfile tf;
-
- /* FIXME: Except for status and error, result TF access
- * doesn't work. I tried reading from BAR0/2, CPB and BAR5.
- * None works regardless of which command interface is used.
- * For now return true iff status indicates device error.
- * This means that we're reporting bogus sector for RW
- * failures. Eeekk....
- */
- inic_tf_read(qc->ap, &tf);
-
- if (tf.status & ATA_ERR) {
- rtf->status = tf.status;
- rtf->error = tf.error;
- }
-}
-
-static void inic_freeze(struct ata_port *ap)
-{
- void __iomem *port_base = inic_port_base(ap);
-
- writeb(PIRQ_MASK_FREEZE, port_base + PORT_IRQ_MASK);
- writeb(0xff, port_base + PORT_IRQ_STAT);
-}
-
-static void inic_thaw(struct ata_port *ap)
-{
- void __iomem *port_base = inic_port_base(ap);
-
- writeb(0xff, port_base + PORT_IRQ_STAT);
- writeb(PIRQ_MASK_DEFAULT, port_base + PORT_IRQ_MASK);
-}
-
-static int inic_check_ready(struct ata_link *link)
-{
- void __iomem *port_base = inic_port_base(link->ap);
-
- return ata_check_ready(readb(port_base + PORT_TF_COMMAND));
-}
-
-/*
- * SRST and SControl hardreset don't give valid signature on this
- * controller. Only controller specific hardreset mechanism works.
- */
-static int inic_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- struct ata_port *ap = link->ap;
- void __iomem *port_base = inic_port_base(ap);
- void __iomem *idma_ctl = port_base + PORT_IDMA_CTL;
- const unsigned int *timing = sata_ehc_deb_timing(&link->eh_context);
- int rc;
-
- /* hammer it into sane state */
- inic_reset_port(port_base);
-
- writew(IDMA_CTL_RST_ATA, idma_ctl);
- readw(idma_ctl); /* flush */
- ata_msleep(ap, 1);
- writew(0, idma_ctl);
-
- rc = sata_link_resume(link, timing, deadline);
- if (rc) {
- ata_link_warn(link,
- "failed to resume link after reset (errno=%d)\n",
- rc);
- return rc;
- }
-
- *class = ATA_DEV_NONE;
- if (ata_link_online(link)) {
- struct ata_taskfile tf;
-
- /* wait for link to become ready */
- rc = ata_wait_after_reset(link, deadline, inic_check_ready);
- /* link occupied, -ENODEV too is an error */
- if (rc) {
- ata_link_warn(link,
- "device not ready after hardreset (errno=%d)\n",
- rc);
- return rc;
- }
-
- inic_tf_read(ap, &tf);
- *class = ata_port_classify(ap, &tf);
- }
-
- return 0;
-}
-
-static void inic_error_handler(struct ata_port *ap)
-{
- void __iomem *port_base = inic_port_base(ap);
-
- inic_reset_port(port_base);
- ata_std_error_handler(ap);
-}
-
-static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
-{
- /* make DMA engine forget about the failed command */
- if (qc->flags & ATA_QCFLAG_EH)
- inic_reset_port(inic_port_base(qc->ap));
-}
-
-static void init_port(struct ata_port *ap)
-{
- void __iomem *port_base = inic_port_base(ap);
- struct inic_port_priv *pp = ap->private_data;
-
- /* clear packet and CPB table */
- memset(pp->pkt, 0, sizeof(struct inic_pkt));
- memset(pp->cpb_tbl, 0, IDMA_CPB_TBL_SIZE);
-
- /* setup CPB lookup table addresses */
- writel(pp->cpb_tbl_dma, port_base + PORT_CPB_CPBLAR);
-}
-
-static int inic_port_resume(struct ata_port *ap)
-{
- init_port(ap);
- return 0;
-}
-
-static int inic_port_start(struct ata_port *ap)
-{
- struct device *dev = ap->host->dev;
- struct inic_port_priv *pp;
-
- /* alloc and initialize private data */
- pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
- if (!pp)
- return -ENOMEM;
- ap->private_data = pp;
-
- /* Alloc resources */
- pp->pkt = dmam_alloc_coherent(dev, sizeof(struct inic_pkt),
- &pp->pkt_dma, GFP_KERNEL);
- if (!pp->pkt)
- return -ENOMEM;
-
- pp->cpb_tbl = dmam_alloc_coherent(dev, IDMA_CPB_TBL_SIZE,
- &pp->cpb_tbl_dma, GFP_KERNEL);
- if (!pp->cpb_tbl)
- return -ENOMEM;
-
- init_port(ap);
-
- return 0;
-}
-
-static struct ata_port_operations inic_port_ops = {
- .inherits = &sata_port_ops,
-
- .check_atapi_dma = inic_check_atapi_dma,
- .qc_prep = inic_qc_prep,
- .qc_issue = inic_qc_issue,
- .qc_fill_rtf = inic_qc_fill_rtf,
-
- .freeze = inic_freeze,
- .thaw = inic_thaw,
- .reset.hardreset = inic_hardreset,
- .error_handler = inic_error_handler,
- .post_internal_cmd = inic_post_internal_cmd,
-
- .scr_read = inic_scr_read,
- .scr_write = inic_scr_write,
-
- .port_resume = inic_port_resume,
- .port_start = inic_port_start,
-};
-
-static const struct ata_port_info inic_port_info = {
- .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
- .pio_mask = ATA_PIO4,
- .mwdma_mask = ATA_MWDMA2,
- .udma_mask = ATA_UDMA6,
- .port_ops = &inic_port_ops
-};
-
-static int init_controller(void __iomem *mmio_base, u16 hctl)
-{
- int i;
- u16 val;
-
- hctl &= ~HCTL_KNOWN_BITS;
-
- /* Soft reset whole controller. Spec says reset duration is 3
- * PCI clocks, be generous and give it 10ms.
- */
- writew(hctl | HCTL_SOFTRST, mmio_base + HOST_CTL);
- readw(mmio_base + HOST_CTL); /* flush */
-
- for (i = 0; i < 10; i++) {
- msleep(1);
- val = readw(mmio_base + HOST_CTL);
- if (!(val & HCTL_SOFTRST))
- break;
- }
-
- if (val & HCTL_SOFTRST)
- return -EIO;
-
- /* mask all interrupts and reset ports */
- for (i = 0; i < NR_PORTS; i++) {
- void __iomem *port_base = mmio_base + i * PORT_SIZE;
-
- writeb(0xff, port_base + PORT_IRQ_MASK);
- inic_reset_port(port_base);
- }
-
- /* port IRQ is masked now, unmask global IRQ */
- writew(hctl & ~HCTL_IRQOFF, mmio_base + HOST_CTL);
- val = readw(mmio_base + HOST_IRQ_MASK);
- val &= ~(HIRQ_PORT0 | HIRQ_PORT1);
- writew(val, mmio_base + HOST_IRQ_MASK);
-
- return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int inic_pci_device_resume(struct pci_dev *pdev)
-{
- struct ata_host *host = pci_get_drvdata(pdev);
- struct inic_host_priv *hpriv = host->private_data;
- int rc;
-
- rc = ata_pci_device_do_resume(pdev);
- if (rc)
- return rc;
-
- if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
- rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
- if (rc)
- return rc;
- }
-
- ata_host_resume(host);
-
- return 0;
-}
-#endif
-
-static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
-{
- const struct ata_port_info *ppi[] = { &inic_port_info, NULL };
- struct ata_host *host;
- struct inic_host_priv *hpriv;
- void __iomem * const *iomap;
- int mmio_bar;
- int i, rc;
-
- ata_print_version_once(&pdev->dev, DRV_VERSION);
-
- dev_alert(&pdev->dev, "inic162x support is broken with common data corruption issues and will be disabled by default, contact linux-ide@vger.kernel.org if in production use\n");
-
- /* alloc host */
- host = ata_host_alloc_pinfo(&pdev->dev, ppi, NR_PORTS);
- hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL);
- if (!host || !hpriv)
- return -ENOMEM;
-
- host->private_data = hpriv;
-
- /* Acquire resources and fill host. Note that PCI and cardbus
- * use different BARs.
- */
- rc = pcim_enable_device(pdev);
- if (rc)
- return rc;
-
- if (pci_resource_flags(pdev, MMIO_BAR_PCI) & IORESOURCE_MEM)
- mmio_bar = MMIO_BAR_PCI;
- else
- mmio_bar = MMIO_BAR_CARDBUS;
-
- rc = pcim_iomap_regions(pdev, 1 << mmio_bar, DRV_NAME);
- if (rc)
- return rc;
- host->iomap = iomap = pcim_iomap_table(pdev);
- hpriv->mmio_base = iomap[mmio_bar];
- hpriv->cached_hctl = readw(hpriv->mmio_base + HOST_CTL);
-
- for (i = 0; i < NR_PORTS; i++) {
- struct ata_port *ap = host->ports[i];
-
- ata_port_pbar_desc(ap, mmio_bar, -1, "mmio");
- ata_port_pbar_desc(ap, mmio_bar, i * PORT_SIZE, "port");
- }
-
- /* Set dma_mask. This devices doesn't support 64bit addressing. */
- rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
- if (rc) {
- dev_err(&pdev->dev, "32-bit DMA enable failed\n");
- return rc;
- }
-
- rc = init_controller(hpriv->mmio_base, hpriv->cached_hctl);
- if (rc) {
- dev_err(&pdev->dev, "failed to initialize controller\n");
- return rc;
- }
-
- pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, inic_interrupt, IRQF_SHARED,
- &inic_sht);
-}
-
-static const struct pci_device_id inic_pci_tbl[] = {
- { PCI_VDEVICE(INIT, 0x1622), },
- { },
-};
-
-static struct pci_driver inic_pci_driver = {
- .name = DRV_NAME,
- .id_table = inic_pci_tbl,
-#ifdef CONFIG_PM_SLEEP
- .suspend = ata_pci_device_suspend,
- .resume = inic_pci_device_resume,
-#endif
- .probe = inic_init_one,
- .remove = ata_pci_remove_one,
-};
-
-module_pci_driver(inic_pci_driver);
-
-MODULE_AUTHOR("Tejun Heo");
-MODULE_DESCRIPTION("low-level driver for Initio 162x SATA");
-MODULE_LICENSE("GPL v2");
-MODULE_DEVICE_TABLE(pci, inic_pci_tbl);
-MODULE_VERSION(DRV_VERSION);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 568/686] f2fs: zone: fix to avoid bio split on sequential zone
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (566 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 567/686] ata: sata_inic162x: remove dangerous broken driver Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 569/686] cgroup: Expose some cgroup helpers Greg Kroah-Hartman
` (117 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chao Yu, Jaegeuk Kim, Sasha Levin
6.18-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: Replaced F2FS_BLKSIZE(sbi) with the F2FS_BLKSIZE constant. ]
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 a9a829315c305..ab58d3d2235bb 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -475,6 +475,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);
@@ -744,7 +748,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] 687+ messages in thread
* [PATCH 6.18 569/686] cgroup: Expose some cgroup helpers
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (567 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 568/686] f2fs: zone: fix to avoid bio split on sequential zone Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 570/686] mm/mglru: fix ineffective memory protection for non-kswapd reclaim Greg Kroah-Hartman
` (116 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tejun Heo, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <tj@kernel.org>
[ Upstream commit 5b30afc20b3fea29b9beb83c6415c4ff06f774aa ]
Expose the following through cgroup.h:
- cgroup_on_dfl()
- cgroup_is_dead()
- cgroup_for_each_live_child()
- cgroup_for_each_live_descendant_pre()
- cgroup_for_each_live_descendant_post()
Until now, these didn't need to be exposed because controllers only cared
about the css hierarchy. The planned sched_ext hierarchical scheduler
support will be based on the default cgroup hierarchy, which is in line
with the existing BPF cgroup support, and thus needs these exposed.
Signed-off-by: Tejun Heo <tj@kernel.org>
Stable-dep-of: 15da1e4978dd ("mm/mglru: fix ineffective memory protection for non-kswapd reclaim")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/cgroup.h | 65 ++++++++++++++++++++++++++++++++-
kernel/cgroup/cgroup-internal.h | 6 ---
kernel/cgroup/cgroup.c | 55 ----------------------------
3 files changed, 63 insertions(+), 63 deletions(-)
diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
index 7b2807009155a..e53524027b737 100644
--- a/include/linux/cgroup.h
+++ b/include/linux/cgroup.h
@@ -42,6 +42,14 @@ struct kernel_clone_args;
#ifdef CONFIG_CGROUPS
+/*
+ * To avoid confusing the compiler (and generating warnings) with code
+ * that attempts to access what would be a 0-element array (i.e. sized
+ * to a potentially empty array when CGROUP_SUBSYS_COUNT == 0), this
+ * constant expression can be added.
+ */
+#define CGROUP_HAS_SUBSYS_CONFIG (CGROUP_SUBSYS_COUNT > 0)
+
enum css_task_iter_flags {
CSS_TASK_ITER_PROCS = (1U << 0), /* walk only threadgroup leaders */
CSS_TASK_ITER_THREADED = (1U << 1), /* walk all threaded css_sets in the domain */
@@ -76,6 +84,7 @@ enum cgroup_lifetime_events {
extern struct file_system_type cgroup_fs_type;
extern struct cgroup_root cgrp_dfl_root;
extern struct css_set init_css_set;
+extern struct mutex cgroup_mutex;
extern spinlock_t css_set_lock;
extern struct blocking_notifier_head cgroup_lifetime_notifier;
@@ -103,6 +112,8 @@ extern struct blocking_notifier_head cgroup_lifetime_notifier;
#define cgroup_subsys_on_dfl(ss) \
static_branch_likely(&ss ## _on_dfl_key)
+bool cgroup_on_dfl(const struct cgroup *cgrp);
+
bool css_has_online_children(struct cgroup_subsys_state *css);
struct cgroup_subsys_state *css_from_id(int id, struct cgroup_subsys *ss);
struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgroup,
@@ -273,6 +284,32 @@ void css_task_iter_end(struct css_task_iter *it);
for ((pos) = css_next_descendant_post(NULL, (css)); (pos); \
(pos) = css_next_descendant_post((pos), (css)))
+/* iterate over child cgrps, lock should be held throughout iteration */
+#define cgroup_for_each_live_child(child, cgrp) \
+ list_for_each_entry((child), &(cgrp)->self.children, self.sibling) \
+ if (({ lockdep_assert_held(&cgroup_mutex); \
+ cgroup_is_dead(child); })) \
+ ; \
+ else
+
+/* walk live descendants in pre order */
+#define cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp) \
+ css_for_each_descendant_pre((d_css), cgroup_css((cgrp), NULL)) \
+ if (({ lockdep_assert_held(&cgroup_mutex); \
+ (dsct) = (d_css)->cgroup; \
+ cgroup_is_dead(dsct); })) \
+ ; \
+ else
+
+/* walk live descendants in postorder */
+#define cgroup_for_each_live_descendant_post(dsct, d_css, cgrp) \
+ css_for_each_descendant_post((d_css), cgroup_css((cgrp), NULL)) \
+ if (({ lockdep_assert_held(&cgroup_mutex); \
+ (dsct) = (d_css)->cgroup; \
+ cgroup_is_dead(dsct); })) \
+ ; \
+ else
+
/**
* cgroup_taskset_for_each - iterate cgroup_taskset
* @task: the loop cursor
@@ -335,6 +372,27 @@ static inline u64 cgroup_id(const struct cgroup *cgrp)
return cgrp->kn->id;
}
+/**
+ * cgroup_css - obtain a cgroup's css for the specified subsystem
+ * @cgrp: the cgroup of interest
+ * @ss: the subsystem of interest (%NULL returns @cgrp->self)
+ *
+ * Return @cgrp's css (cgroup_subsys_state) associated with @ss. This
+ * function must be called either under cgroup_mutex or rcu_read_lock() and
+ * the caller is responsible for pinning the returned css if it wants to
+ * keep accessing it outside the said locks. This function may return
+ * %NULL if @cgrp doesn't have @subsys_id enabled.
+ */
+static inline struct cgroup_subsys_state *cgroup_css(struct cgroup *cgrp,
+ struct cgroup_subsys *ss)
+{
+ if (CGROUP_HAS_SUBSYS_CONFIG && ss)
+ return rcu_dereference_check(cgrp->subsys[ss->id],
+ lockdep_is_held(&cgroup_mutex));
+ else
+ return &cgrp->self;
+}
+
/**
* css_is_dying - test whether the specified css is dying
* @css: target css
@@ -371,6 +429,11 @@ static inline bool css_is_self(struct cgroup_subsys_state *css)
return false;
}
+static inline bool cgroup_is_dead(const struct cgroup *cgrp)
+{
+ return !(cgrp->self.flags & CSS_ONLINE);
+}
+
static inline void cgroup_get(struct cgroup *cgrp)
{
css_get(&cgrp->self);
@@ -386,8 +449,6 @@ static inline void cgroup_put(struct cgroup *cgrp)
css_put(&cgrp->self);
}
-extern struct mutex cgroup_mutex;
-
static inline void cgroup_lock(void)
{
mutex_lock(&cgroup_mutex);
diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
index 22051b4f1ccbc..e4a872e2e08c2 100644
--- a/kernel/cgroup/cgroup-internal.h
+++ b/kernel/cgroup/cgroup-internal.h
@@ -184,11 +184,6 @@ extern bool cgrp_dfl_visible;
for ((ssid) = 0; (ssid) < CGROUP_SUBSYS_COUNT && \
(((ss) = cgroup_subsys[ssid]) || true); (ssid)++)
-static inline bool cgroup_is_dead(const struct cgroup *cgrp)
-{
- return !(cgrp->self.flags & CSS_ONLINE);
-}
-
static inline bool notify_on_release(const struct cgroup *cgrp)
{
return test_bit(CGRP_NOTIFY_ON_RELEASE, &cgrp->flags);
@@ -222,7 +217,6 @@ static inline void get_css_set(struct css_set *cset)
}
bool cgroup_ssid_enabled(int ssid);
-bool cgroup_on_dfl(const struct cgroup *cgrp);
struct cgroup_root *cgroup_root_from_kf(struct kernfs_root *kf_root);
struct cgroup *task_cgroup_from_root(struct task_struct *task,
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index aa629b7d76e53..ac7b2103df68a 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -70,14 +70,6 @@
/* let's not notify more than 100 times per second */
#define CGROUP_FILE_NOTIFY_MIN_INTV DIV_ROUND_UP(HZ, 100)
-/*
- * To avoid confusing the compiler (and generating warnings) with code
- * that attempts to access what would be a 0-element array (i.e. sized
- * to a potentially empty array when CGROUP_SUBSYS_COUNT == 0), this
- * constant expression can be added.
- */
-#define CGROUP_HAS_SUBSYS_CONFIG (CGROUP_SUBSYS_COUNT > 0)
-
/*
* cgroup_mutex is the master lock. Any modification to cgroup or its
* hierarchy must be performed while holding it.
@@ -513,27 +505,6 @@ static u16 cgroup_ss_mask(struct cgroup *cgrp)
return cgrp->root->subsys_mask;
}
-/**
- * cgroup_css - obtain a cgroup's css for the specified subsystem
- * @cgrp: the cgroup of interest
- * @ss: the subsystem of interest (%NULL returns @cgrp->self)
- *
- * Return @cgrp's css (cgroup_subsys_state) associated with @ss. This
- * function must be called either under cgroup_mutex or rcu_read_lock() and
- * the caller is responsible for pinning the returned css if it wants to
- * keep accessing it outside the said locks. This function may return
- * %NULL if @cgrp doesn't have @subsys_id enabled.
- */
-static struct cgroup_subsys_state *cgroup_css(struct cgroup *cgrp,
- struct cgroup_subsys *ss)
-{
- if (CGROUP_HAS_SUBSYS_CONFIG && ss)
- return rcu_dereference_check(cgrp->subsys[ss->id],
- lockdep_is_held(&cgroup_mutex));
- else
- return &cgrp->self;
-}
-
/**
* cgroup_e_css_by_mask - obtain a cgroup's effective css for the specified ss
* @cgrp: the cgroup of interest
@@ -745,32 +716,6 @@ EXPORT_SYMBOL_GPL(of_css);
} \
} while (false)
-/* iterate over child cgrps, lock should be held throughout iteration */
-#define cgroup_for_each_live_child(child, cgrp) \
- list_for_each_entry((child), &(cgrp)->self.children, self.sibling) \
- if (({ lockdep_assert_held(&cgroup_mutex); \
- cgroup_is_dead(child); })) \
- ; \
- else
-
-/* walk live descendants in pre order */
-#define cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp) \
- css_for_each_descendant_pre((d_css), cgroup_css((cgrp), NULL)) \
- if (({ lockdep_assert_held(&cgroup_mutex); \
- (dsct) = (d_css)->cgroup; \
- cgroup_is_dead(dsct); })) \
- ; \
- else
-
-/* walk live descendants in postorder */
-#define cgroup_for_each_live_descendant_post(dsct, d_css, cgrp) \
- css_for_each_descendant_post((d_css), cgroup_css((cgrp), NULL)) \
- if (({ lockdep_assert_held(&cgroup_mutex); \
- (dsct) = (d_css)->cgroup; \
- cgroup_is_dead(dsct); })) \
- ; \
- else
-
/*
* The default css_set - used by init and its children prior to any
* hierarchies being mounted. It contains a pointer to the root state
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 570/686] mm/mglru: fix ineffective memory protection for non-kswapd reclaim
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (568 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 569/686] cgroup: Expose some cgroup helpers Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 571/686] f2fs: return -EIO for a lost inode block after cp_error Greg Kroah-Hartman
` (115 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ridong Chen, Andrew Morton,
Barry Song, Johannes Weiner, Axel Rasmussen, Chris Down,
David Hildenbrand, Kairui Song, Lorenzo Stoakes, Michal Hocko,
Muchun Song, Roman Gushchin, Shakeel Butt, Tejun Heo, Wei Xu,
Yuanchu Xie, Yu Zhao, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ridong Chen <chenridong@xiaomi.com>
[ Upstream commit 15da1e4978dd4ea8f5faa6e15ee967ba4ad9a30a ]
For MGLRU, memory.min/low is not honored during global proactive reclaim
(writing to the root memory.reclaim) and global direct reclaim, because
these paths shrink memcgs using stale protection (emin/elow). It can be
reproduced as follows:
# echo 7 > /sys/kernel/mm/lru_gen/enabled
# cd /sys/fs/cgroup
# mkdir -p a/b
# echo 100M > a/memory.min
# echo +memory > a/cgroup.subtree_control
# echo 100M > a/b/memory.min
# echo $$ > a/b/cgroup.procs
# dd if=/dev/zero of=/tmp/testfile bs=1M count=200
# cat a/b/memory.current
222650368
# echo 500M > memory.reclaim
-bash: echo: write error: Resource temporarily unavailable
# cat a/b/memory.current
6070272
memory.min is 100M, yet reclaim drops a/b down to 6M, breaking the
protection. The traditional LRU path is not affected because
shrink_node() calls mem_cgroup_calculate_protection() for each memcg it
visits during a top-down tree walk.
Commit 30d77b7eef01 ("mm/mglru: fix ineffective protection calculation")
moved the protection computation into lru_gen_age_node(), which only runs
for kswapd. Non-kswapd global reclaim reaches shrink_one() through
lru_gen_shrink_node() -> shrink_many() without any protection computation,
so emin/elow are whatever a previous kswapd run left behind - or zero if
kswapd never ran on this node. Relying on a prior kswapd pass is not
correct either: a memcg's emin/elow are derived from its ancestors'
memory.min/low settings and from children_min_usage, both of which change
over time, so emin/elow go stale even after kswapd has run and must be
recomputed at the point of reclaim.
Introduce mem_cgroup_calculate_protection_path() which computes emin/elow
along the root-to-target path only, by iterating through the cgroup
ancestors array top-down. This avoids the full tree traversal that would
be needed with mem_cgroup_calculate_protection(), limiting the cost to
O(depth) per memcg - typically 3-5 levels.
Call it from shrink_one() for the non-kswapd path so that each memcg about
to be shrunk has correct protection values.
Link: https://lore.kernel.org/20260907025445.1836238-3-ridong.chen@linux.dev
Fixes: e4dde56cd208 ("mm: multi-gen LRU: per-node lru_gen_folio lists")
Signed-off-by: Ridong Chen <chenridong@xiaomi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Barry Song <baohua@kernel.org>
Reviewed-by: Johannes Weiner <hannes@cmpxchg.org>
Assisted-by: Claude:claude-opus-4-8
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Chris Down <chris@chrisdown.name>
Cc: David Hildenbrand <david@kernel.org>
Cc: Kairui Song <kasong@tencent.com>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Tejun Heo <tj@kernel.org>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Yu Zhao <yuzhao@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/memcontrol.h | 10 +++++++++
mm/memcontrol.c | 45 ++++++++++++++++++++++++++++++++++++++
mm/vmscan.c | 8 ++++++-
3 files changed, 62 insertions(+), 1 deletion(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 706ddda4a60b1..b14bfce896d20 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -1869,6 +1869,16 @@ static inline void mem_cgroup_node_filter_allowed(struct mem_cgroup *memcg,
}
#endif /* CONFIG_MEMCG */
+#if defined(CONFIG_MEMCG) && defined(CONFIG_LRU_GEN)
+void mem_cgroup_calculate_protection_path(struct mem_cgroup *root,
+ struct mem_cgroup *memcg);
+#else
+static inline void mem_cgroup_calculate_protection_path(struct mem_cgroup *root,
+ struct mem_cgroup *memcg)
+{
+}
+#endif
+
#if defined(CONFIG_MEMCG) && defined(CONFIG_ZSWAP)
bool obj_cgroup_may_zswap(struct obj_cgroup *objcg);
void obj_cgroup_charge_zswap(struct obj_cgroup *objcg, size_t size);
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 97ed5ad4053f0..db12e61ee9852 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4737,6 +4737,51 @@ void mem_cgroup_calculate_protection(struct mem_cgroup *root,
page_counter_calculate_protection(&root->memory, &memcg->memory, recursive_protection);
}
+#ifdef CONFIG_LRU_GEN
+/**
+ * mem_cgroup_calculate_protection_path - compute protection along a path
+ * @root: the top ancestor of the sub-tree being checked (NULL for root_mem_cgroup)
+ * @memcg: the target memory cgroup
+ *
+ * Walk the ancestor path from @root down to @memcg and compute the effective
+ * protection at each level. This is safe for isolated queries because it
+ * ensures parents are computed before children.
+ */
+void mem_cgroup_calculate_protection_path(struct mem_cgroup *root,
+ struct mem_cgroup *memcg)
+{
+ bool recursive_protection =
+ cgrp_dfl_root.flags & CGRP_ROOT_MEMORY_RECURSIVE_PROT;
+ struct cgroup *cg;
+ int root_level, i;
+
+ if (mem_cgroup_disabled())
+ return;
+
+ if (!root)
+ root = root_mem_cgroup;
+
+ if (memcg == root)
+ return;
+
+ root_level = root->css.cgroup->level;
+ cg = memcg->css.cgroup;
+
+ rcu_read_lock();
+ for (i = root_level + 1; i <= cg->level; i++) {
+ struct mem_cgroup *cur;
+
+ cur = mem_cgroup_from_css(cgroup_css(cg->ancestors[i],
+ &memory_cgrp_subsys));
+ if (cur)
+ page_counter_calculate_protection(&root->memory,
+ &cur->memory,
+ recursive_protection);
+ }
+ rcu_read_unlock();
+}
+#endif /* CONFIG_LRU_GEN */
+
static int charge_memcg(struct folio *folio, struct mem_cgroup *memcg,
gfp_t gfp)
{
diff --git a/mm/vmscan.c b/mm/vmscan.c
index ed75f1bce9f0a..8556318ff721d 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -4927,7 +4927,13 @@ static int shrink_one(struct lruvec *lruvec, struct scan_control *sc)
struct mem_cgroup *memcg = lruvec_memcg(lruvec);
struct pglist_data *pgdat = lruvec_pgdat(lruvec);
- /* lru_gen_age_node() called mem_cgroup_calculate_protection() */
+ /*
+ * For kswapd, mem_cgroup_calculate_protection() has already
+ * been called during the top-down cgroup traversal.
+ */
+ if (!current_is_kswapd())
+ mem_cgroup_calculate_protection_path(NULL, memcg);
+
if (mem_cgroup_below_min(NULL, memcg))
return MEMCG_LRU_YOUNG;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 571/686] f2fs: return -EIO for a lost inode block after cp_error
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (569 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 570/686] mm/mglru: fix ineffective memory protection for non-kswapd reclaim Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 572/686] drm/amd/pm:restate all customized OD features on every table upload for smu 13.0.0/smu 14.0.2 Greg Kroah-Hartman
` (114 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Daeho Jeong, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.18-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 inode cache access to folio-based access using f2fs_get_inode_folio() ]
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 1b67184df3dd6..010f94963ea7d 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -811,8 +811,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] 687+ messages in thread
* [PATCH 6.18 572/686] drm/amd/pm:restate all customized OD features on every table upload for smu 13.0.0/smu 14.0.2
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (570 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 571/686] f2fs: return -EIO for a lost inode block after cp_error Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 573/686] mfd: twl-core: Use i2c_check_functionality as boolean value Greg Kroah-Hartman
` (113 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kenneth Feng, Kevin Wang,
Alex Deucher, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kenneth Feng <kenneth.feng@amd.com>
[ Upstream commit 44d0d3031e47973ed65fd327669d5e2eaaf6c565 ]
PMFW interprets OverDriveTable.FeatureCtrlMask as the complete set of
overdrive features that are currently overridden, not as a delta
describing the operation at hand. On import it resets every feature
whose bit is clear back to its default value - for the VF curve that
means zeroing VoltageOffsetPerZoneBoundary[] outright.
The driver assumed the opposite. smu_v14_0_2_od_edit_dpm_table() clears
the mask after a successful commit, so a subsequent above-default
power1_cap write goes through smu_v14_0_2_set_ppt_limit() and uploads a
table carrying only PP_OD_FEATURE_PPT_BIT. PMFW then drops the user's
voltage offset and reverts to the stock V/F curve, while the driver's
cached user table still reports the offset through pp_od_clk_voltage.
Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5935
Signed-off-by: Kenneth Feng <kenneth.feng@amd.com>
Reviewed-by: Kevin Wang <kevin.wang@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 1b63bb397db208a8f84778a9d9cafc93da9373eb)
Cc: stable@vger.kernel.org
[ sashal: adjusted smu_table_context context for existing gpu_metrics_table_size and gpu_metrics_table fields instead of driver_tables ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h | 2 +
.../drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 35 +++++++----------
.../drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 32 +++++++---------
.../drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c | 38 +++++++++++--------
4 files changed, 52 insertions(+), 55 deletions(-)
diff --git a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
index e00beb901d906..0557fbf9649c8 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
+++ b/drivers/gpu/drm/amd/pm/swsmu/inc/amdgpu_smu.h
@@ -370,6 +370,8 @@ struct smu_table_context {
void *boot_overdrive_table;
void *user_overdrive_table;
+ uint32_t user_od_feature_mask;
+
uint32_t gpu_metrics_table_size;
void *gpu_metrics_table;
};
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
index e463a39efab22..9d2d630bba240 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -1643,7 +1643,6 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
struct amdgpu_device *adev = smu->adev;
uint32_t offset_of_voltageoffset;
int32_t minimum, maximum;
- uint32_t feature_ctrlmask;
int i, ret = 0;
switch (type) {
@@ -1965,21 +1964,16 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
if (ret)
return ret;
} else {
- feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask;
memcpy(od_table,
table_context->boot_overdrive_table,
sizeof(OverDriveTableExternal_t));
- od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask;
+ od_table->OverDriveTable.FeatureCtrlMask = 0;
+ table_context->user_od_feature_mask = 0;
}
fallthrough;
case PP_OD_COMMIT_DPM_TABLE:
- /*
- * The member below instructs PMFW the settings focused in
- * this single operation.
- * `uint32_t FeatureCtrlMask;`
- * It does not contain actual informations about user's custom
- * settings. Thus we do not cache it.
- */
+ table_context->user_od_feature_mask =
+ od_table->OverDriveTable.FeatureCtrlMask;
offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary);
if (memcmp((u8 *)od_table + offset_of_voltageoffset,
table_context->user_overdrive_table + offset_of_voltageoffset,
@@ -1992,7 +1986,6 @@ static int smu_v13_0_0_od_edit_dpm_table(struct smu_context *smu,
return ret;
}
- od_table->OverDriveTable.FeatureCtrlMask = 0;
memcpy(table_context->user_overdrive_table + offset_of_voltageoffset,
(u8 *)od_table + offset_of_voltageoffset,
sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset);
@@ -2271,6 +2264,7 @@ static int smu_v13_0_0_set_default_od_settings(struct smu_context *smu)
boot_od_table,
sizeof(OverDriveTableExternal_t));
smu->user_dpm_profile.user_od = false;
+ smu->smu_table.user_od_feature_mask = 0;
} else if (smu->user_dpm_profile.user_od) {
memcpy(&user_od_table_bak,
user_od_table,
@@ -2320,12 +2314,8 @@ static int smu_v13_0_0_restore_user_od_settings(struct smu_context *smu)
OverDriveTableExternal_t *od_table = table_context->overdrive_table;
OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table;
int res;
-
- user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) |
- BIT(PP_OD_FEATURE_UCLK_BIT) |
- BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) |
- BIT(PP_OD_FEATURE_FAN_CURVE_BIT) |
- BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ user_od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
res = smu_v13_0_0_upload_overdrive_table(smu, user_od_table);
user_od_table->OverDriveTable.FeatureCtrlMask = 0;
if (res == 0)
@@ -3130,8 +3120,10 @@ static int smu_v13_0_0_set_power_limit(struct smu_context *smu,
if (limit <= msg_limit) {
if (smu->current_power_limit > msg_limit) {
od_table->OverDriveTable.Ppt = 0;
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
-
+ table_context->user_od_feature_mask &=
+ ~(1U << PP_OD_FEATURE_PPT_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
if (ret) {
dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
@@ -3145,8 +3137,9 @@ static int smu_v13_0_0_set_power_limit(struct smu_context *smu,
return ret;
od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100;
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
-
+ table_context->user_od_feature_mask |= 1U << PP_OD_FEATURE_PPT_BIT;
+ od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
ret = smu_v13_0_0_upload_overdrive_table(smu, od_table);
if (ret) {
dev_err(smu->adev->dev, "Failed to upload overdrive table!\n");
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 0af98b5bf0ac2..9947b3f6bb5fb 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
@@ -1631,7 +1631,6 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
struct amdgpu_device *adev = smu->adev;
uint32_t offset_of_voltageoffset;
int32_t minimum, maximum;
- uint32_t feature_ctrlmask;
int i, ret = 0;
switch (type) {
@@ -1953,22 +1952,17 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
if (ret)
return ret;
} else {
- feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask;
memcpy(od_table,
table_context->boot_overdrive_table,
sizeof(OverDriveTableExternal_t));
- od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask;
+ od_table->OverDriveTable.FeatureCtrlMask = 0;
+ table_context->user_od_feature_mask = 0;
}
fallthrough;
case PP_OD_COMMIT_DPM_TABLE:
- /*
- * The member below instructs PMFW the settings focused in
- * this single operation.
- * `uint32_t FeatureCtrlMask;`
- * It does not contain actual informations about user's custom
- * settings. Thus we do not cache it.
- */
+ table_context->user_od_feature_mask =
+ od_table->OverDriveTable.FeatureCtrlMask;
offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary);
if (memcmp((u8 *)od_table + offset_of_voltageoffset,
table_context->user_overdrive_table + offset_of_voltageoffset,
@@ -1981,7 +1975,6 @@ static int smu_v13_0_7_od_edit_dpm_table(struct smu_context *smu,
return ret;
}
- od_table->OverDriveTable.FeatureCtrlMask = 0;
memcpy(table_context->user_overdrive_table + offset_of_voltageoffset,
(u8 *)od_table + offset_of_voltageoffset,
sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset);
@@ -2254,6 +2247,7 @@ static int smu_v13_0_7_set_default_od_settings(struct smu_context *smu)
boot_od_table,
sizeof(OverDriveTableExternal_t));
smu->user_dpm_profile.user_od = false;
+ smu->smu_table.user_od_feature_mask = 0;
} else if (smu->user_dpm_profile.user_od) {
memcpy(&user_od_table_bak,
user_od_table,
@@ -2304,11 +2298,8 @@ static int smu_v13_0_7_restore_user_od_settings(struct smu_context *smu)
OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table;
int res;
- user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) |
- BIT(PP_OD_FEATURE_UCLK_BIT) |
- BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) |
- BIT(PP_OD_FEATURE_FAN_CURVE_BIT) |
- BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ user_od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
res = smu_v13_0_7_upload_overdrive_table(smu, user_od_table);
user_od_table->OverDriveTable.FeatureCtrlMask = 0;
if (res == 0)
@@ -2726,7 +2717,10 @@ static int smu_v13_0_7_set_power_limit(struct smu_context *smu,
if (limit <= msg_limit) {
if (smu->current_power_limit > msg_limit) {
od_table->OverDriveTable.Ppt = 0;
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+ table_context->user_od_feature_mask &=
+ ~(1U << PP_OD_FEATURE_PPT_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
ret = smu_v13_0_7_upload_overdrive_table(smu, od_table);
if (ret) {
@@ -2741,7 +2735,9 @@ static int smu_v13_0_7_set_power_limit(struct smu_context *smu,
return ret;
od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100;
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+ table_context->user_od_feature_mask |= 1U << PP_OD_FEATURE_PPT_BIT;
+ od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
ret = smu_v13_0_7_upload_overdrive_table(smu, od_table);
if (ret) {
diff --git a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
index f8761a64a6e12..88bbc30b5ec96 100644
--- a/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0_2_ppt.c
@@ -2391,6 +2391,7 @@ static int smu_v14_0_2_set_default_od_settings(struct smu_context *smu)
boot_od_table,
sizeof(OverDriveTableExternal_t));
smu->user_dpm_profile.user_od = false;
+ smu->smu_table.user_od_feature_mask = 0;
} else if (smu->user_dpm_profile.user_od) {
memcpy(&user_od_table_bak,
user_od_table,
@@ -2439,11 +2440,8 @@ static int smu_v14_0_2_restore_user_od_settings(struct smu_context *smu)
OverDriveTableExternal_t *user_od_table = table_context->user_overdrive_table;
int res;
- user_od_table->OverDriveTable.FeatureCtrlMask = BIT(PP_OD_FEATURE_GFXCLK_BIT) |
- BIT(PP_OD_FEATURE_UCLK_BIT) |
- BIT(PP_OD_FEATURE_GFX_VF_CURVE_BIT) |
- BIT(PP_OD_FEATURE_FAN_CURVE_BIT) |
- BIT(PP_OD_FEATURE_ZERO_FAN_BIT);
+ user_od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
res = smu_v14_0_2_upload_overdrive_table(smu, user_od_table);
user_od_table->OverDriveTable.FeatureCtrlMask = 0;
if (res == 0)
@@ -2528,7 +2526,6 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
struct amdgpu_device *adev = smu->adev;
uint32_t offset_of_voltageoffset;
int32_t minimum, maximum;
- uint32_t feature_ctrlmask;
int i, ret = 0;
switch (type) {
@@ -2817,21 +2814,26 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
if (ret)
return ret;
} else {
- feature_ctrlmask = od_table->OverDriveTable.FeatureCtrlMask;
memcpy(od_table,
table_context->boot_overdrive_table,
sizeof(OverDriveTableExternal_t));
- od_table->OverDriveTable.FeatureCtrlMask = feature_ctrlmask;
+ od_table->OverDriveTable.FeatureCtrlMask = 0;
+ table_context->user_od_feature_mask = 0;
}
fallthrough;
case PP_OD_COMMIT_DPM_TABLE:
/*
- * The member below instructs PMFW the settings focused in
- * this single operation.
- * `uint32_t FeatureCtrlMask;`
- * It does not contain actual informations about user's custom
- * settings. Thus we do not cache it.
+ * PMFW interprets FeatureCtrlMask as the complete set of OD
+ * features that are currently overridden, not as a delta
+ * describing this single operation. Any feature whose bit is
+ * clear gets reset to its default on import. od_table's mask
+ * has accumulated every feature the user touched since the
+ * last full restore, so record it and keep restating it on
+ * subsequent uploads.
*/
+ table_context->user_od_feature_mask =
+ od_table->OverDriveTable.FeatureCtrlMask;
+
offset_of_voltageoffset = offsetof(OverDriveTable_t, VoltageOffsetPerZoneBoundary);
if (memcmp((u8 *)od_table + offset_of_voltageoffset,
table_context->user_overdrive_table + offset_of_voltageoffset,
@@ -2844,7 +2846,6 @@ static int smu_v14_0_2_od_edit_dpm_table(struct smu_context *smu,
return ret;
}
- od_table->OverDriveTable.FeatureCtrlMask = 0;
memcpy(table_context->user_overdrive_table + offset_of_voltageoffset,
(u8 *)od_table + offset_of_voltageoffset,
sizeof(OverDriveTableExternal_t) - offset_of_voltageoffset);
@@ -2882,7 +2883,10 @@ static int smu_v14_0_2_set_power_limit(struct smu_context *smu,
if (limit <= msg_limit) {
if (smu->current_power_limit > msg_limit) {
od_table->OverDriveTable.Ppt = 0;
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+ table_context->user_od_feature_mask &=
+ ~(1U << PP_OD_FEATURE_PPT_BIT);
+ od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
ret = smu_v14_0_2_upload_overdrive_table(smu, od_table);
if (ret) {
@@ -2897,7 +2901,9 @@ static int smu_v14_0_2_set_power_limit(struct smu_context *smu,
return ret;
od_table->OverDriveTable.Ppt = (limit * 100) / msg_limit - 100;
- od_table->OverDriveTable.FeatureCtrlMask |= 1U << PP_OD_FEATURE_PPT_BIT;
+ table_context->user_od_feature_mask |= 1U << PP_OD_FEATURE_PPT_BIT;
+ od_table->OverDriveTable.FeatureCtrlMask =
+ table_context->user_od_feature_mask;
ret = smu_v14_0_2_upload_overdrive_table(smu, od_table);
if (ret) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 573/686] mfd: twl-core: Use i2c_check_functionality as boolean value
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (571 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 572/686] drm/amd/pm:restate all customized OD features on every table upload for smu 13.0.0/smu 14.0.2 Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 574/686] mfd: twl-core: Unregister the auxiliary platform device on unbind Greg Kroah-Hartman
` (112 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Lee Jones,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <thorsten.blum@linux.dev>
[ Upstream commit 7ee4fa2674e51a0d100b9240cd8a50355141362f ]
i2c_check_functionality() returns a boolean status rather than an error
code - directly use it as a boolean value.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Link: https://patch.msgid.link/20260505114543.159381-2-thorsten.blum@linux.dev
Signed-off-by: Lee Jones <lee@kernel.org>
Stable-dep-of: 3c5c55d979dd ("mfd: twl-core: Unregister the auxiliary platform device on unbind")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mfd/twl-core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index f89eda4a17fe4..c024a28b057e3 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -754,7 +754,7 @@ twl_probe(struct i2c_client *client)
return status;
}
- if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_dbg(&client->dev, "can't talk I2C?\n");
status = -EIO;
goto free;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 574/686] mfd: twl-core: Unregister the auxiliary platform device on unbind
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (572 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 573/686] mfd: twl-core: Use i2c_check_functionality as boolean value Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 575/686] ALSA: hda: cs35l41: Use auto-cleanup for put_device() Greg Kroah-Hartman
` (111 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak, Lee Jones,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit 3c5c55d979ddcb0765ce531bc7ba173c87c8712a ]
twl_probe() registers a standalone platform device named "twl", but keeps
its pointer only in a local variable. Probe errors unregister the device,
while successful probe leaves no way for twl_remove() to release it. The
platform device therefore remains registered after the I2C driver unbinds.
Register a managed action on the I2C device immediately after adding the
platform device. This unregisters it on probe failure and driver unbind,
and also handles failure to register the action itself. Remove the manual
error-path unregister to avoid releasing the device twice.
This issue was identified during our ongoing static-analysis research while
reviewing kernel code.
Fixes: defa6be1c821 ("mfd: Fix compile for twl-core.c by removing cpu_is_omap usage")
Cc: stable@vger.kernel.org
Assisted-by: OpenAI:GPT-5.6
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Link: https://patch.msgid.link/20260913205013.54777-1-mhun512@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/mfd/twl-core.c | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index c024a28b057e3..128cd3f6c60c4 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -719,6 +719,11 @@ static const struct mfd_cell twl6032_cells[] = {
{ .name = "twl6032-clk" },
};
+static void twl_unregister_device(void *data)
+{
+ platform_device_unregister(data);
+}
+
/* NOTE: This driver only handles a single twl4030/tps659x0 chip */
static int
twl_probe(struct i2c_client *client)
@@ -754,17 +759,22 @@ twl_probe(struct i2c_client *client)
return status;
}
+ status = devm_add_action_or_reset(&client->dev, twl_unregister_device,
+ pdev);
+ if (status)
+ return status;
+
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_dbg(&client->dev, "can't talk I2C?\n");
status = -EIO;
- goto free;
+ goto out;
}
twl_priv = devm_kzalloc(&client->dev, sizeof(struct twl_private),
GFP_KERNEL);
if (!twl_priv) {
status = -ENOMEM;
- goto free;
+ goto out;
}
if ((id->driver_data) & TWL6030_CLASS) {
@@ -784,7 +794,7 @@ twl_probe(struct i2c_client *client)
GFP_KERNEL);
if (!twl_priv->twl_modules) {
status = -ENOMEM;
- goto free;
+ goto out;
}
for (i = 0; i < num_slaves; i++) {
@@ -880,7 +890,7 @@ twl_probe(struct i2c_client *client)
status = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_NONE,
cells, num_cells, NULL, 0, NULL);
if (status < 0)
- goto free;
+ goto out;
if (of_device_is_system_power_controller(node)) {
if (!pm_power_off)
@@ -896,10 +906,7 @@ twl_probe(struct i2c_client *client)
fail:
if (status < 0)
twl_remove(client);
-free:
- if (status < 0)
- platform_device_unregister(pdev);
-
+out:
return status;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 575/686] ALSA: hda: cs35l41: Use auto-cleanup for put_device()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (573 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 574/686] mfd: twl-core: Unregister the auxiliary platform device on unbind Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 576/686] ALSA: hda: cs35l41: Fix ACPI device reference leak on probe failure Greg Kroah-Hartman
` (110 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, patches, Takashi Iwai, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit c437a83cc69645edab8e0bfc450a3b706abe759e ]
A temporary refcount management of a struct device can be done
gracefully with __clean(put_device) for avoiding potential leaks.
No functional change but just a code cleanup.
Cc: patches@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20260803140100.919071-3-tiwai@suse.de
Stable-dep-of: 8d70e364e866 ("ALSA: hda: cs35l41: Fix ACPI device reference leak on probe failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/side-codecs/cs35l41_hda.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/sound/hda/codecs/side-codecs/cs35l41_hda.c b/sound/hda/codecs/side-codecs/cs35l41_hda.c
index de2fd6471f059..a7fc4ba35e3a1 100644
--- a/sound/hda/codecs/side-codecs/cs35l41_hda.c
+++ b/sound/hda/codecs/side-codecs/cs35l41_hda.c
@@ -1929,7 +1929,6 @@ int cs35l41_hda_parse_acpi(struct cs35l41_hda *cs35l41, struct device *physdev,
static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
{
struct acpi_device *adev;
- struct device *physdev;
struct spi_device *spi;
const char *sub;
int ret;
@@ -1941,7 +1940,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
}
cs35l41->dacpi = adev;
- physdev = get_device(acpi_get_first_physical_node(adev));
+ struct device *physdev __free(put_device) =
+ get_device(acpi_get_first_physical_node(adev));
if (!physdev) {
acpi_dev_put(adev);
return -ENODEV;
@@ -1959,13 +1959,9 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
}
ret = cs35l41_hda_parse_acpi(cs35l41, physdev, id);
- if (ret) {
- put_device(physdev);
+ if (ret)
return ret;
- }
out:
- put_device(physdev);
-
cs35l41->bypass_fw = false;
if (cs35l41->control_bus == SPI) {
spi = to_spi_device(cs35l41->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 576/686] ALSA: hda: cs35l41: Fix ACPI device reference leak on probe failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (574 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 575/686] ALSA: hda: cs35l41: Use auto-cleanup for put_device() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 577/686] platform/x86: asus-wmi: Serialize WMI method evaluations with a mutex Greg Kroah-Hartman
` (109 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ma Ke, Takashi Iwai, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ma Ke <make_ruc2021@163.com>
[ Upstream commit 8d70e364e866bdfca81eee24d0688fac9472cfb9 ]
cs35l41_hda_probe() takes an acpi_device through
cs35l41_hda_read_acpi() and stores it in cs35l41->dacpi. Only the
failures that happen later reach the err: label, which is where that
reference and cs35l41->acpi_subsystem_id are released, so the early
return taken when cs35l41_hda_read_acpi() fails leaves both behind.
Keep the ownership in the caller instead of dropping the reference
inside cs35l41_hda_read_acpi(). That removes the need to work out
whether a given failure path has already released it, and with it the
double put that cs35l41_hda_parse_acpi() would otherwise cause when it
fails after having released the device itself.
cs35l41_hda_parse_acpi() and the !physdev path no longer put the
reference, and the early failure enters the existing err: cleanup tail
through a new err_acpi label.
The label sits between the reset of the codec and the gpio cleanup, so
an early failure also releases the reset and chip-select descriptors
that cs35l41_hda_parse_acpi() may already have taken, while still
skipping cs35l41_safe_reset() on a codec that was never brought up.
cs35l41->dacpi comes from devm_kzalloc() and is only assigned once the
ACPI device has been found, so the put is a no-op when the lookup
itself failed.
Found by code review.
Fixes: 447106e92a0c ("ALSA: hda: cs35l41: Support mute notifications for CS35L41 HDA")
Cc: stable@vger.kernel.org
Signed-off-by: Ma Ke <make_ruc2021@163.com>
Link: https://patch.msgid.link/20261012084152.3740340-1-make_ruc2021@163.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/side-codecs/cs35l41_hda.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/sound/hda/codecs/side-codecs/cs35l41_hda.c b/sound/hda/codecs/side-codecs/cs35l41_hda.c
index a7fc4ba35e3a1..d9f687967be51 100644
--- a/sound/hda/codecs/side-codecs/cs35l41_hda.c
+++ b/sound/hda/codecs/side-codecs/cs35l41_hda.c
@@ -1921,7 +1921,6 @@ int cs35l41_hda_parse_acpi(struct cs35l41_hda *cs35l41, struct device *physdev,
hw_cfg->valid = false;
hw_cfg->gpio1.valid = false;
hw_cfg->gpio2.valid = false;
- acpi_dev_put(cs35l41->dacpi);
return ret;
}
@@ -1942,10 +1941,8 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
cs35l41->dacpi = adev;
struct device *physdev __free(put_device) =
get_device(acpi_get_first_physical_node(adev));
- if (!physdev) {
- acpi_dev_put(adev);
+ if (!physdev)
return -ENODEV;
- }
sub = acpi_get_subsystem_id(ACPI_HANDLE(physdev));
if (IS_ERR(sub))
@@ -2000,8 +1997,10 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
dev_set_drvdata(dev, cs35l41);
ret = cs35l41_hda_read_acpi(cs35l41, device_name, id);
- if (ret)
- return dev_err_probe(cs35l41->dev, ret, "Platform not supported\n");
+ if (ret) {
+ dev_err_probe(cs35l41->dev, ret, "Platform not supported\n");
+ goto err_acpi;
+ }
if (IS_ERR(cs35l41->reset_gpio)) {
ret = PTR_ERR(cs35l41->reset_gpio);
@@ -2088,6 +2087,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
err:
if (cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type))
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
+err_acpi:
gpiod_put(cs35l41->reset_gpio);
gpiod_put(cs35l41->cs_gpio);
acpi_dev_put(cs35l41->dacpi);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 577/686] platform/x86: asus-wmi: Serialize WMI method evaluations with a mutex
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (575 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 576/686] ALSA: hda: cs35l41: Fix ACPI device reference leak on probe failure Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 578/686] KVM: arm64: nv: Move L2->L1 switch on interrupt early Greg Kroah-Hartman
` (108 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Marco Scardovi, Denis Benato,
Armin Wolf, Ilpo Järvinen, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marco Scardovi <scardracs@disroot.org>
[ Upstream commit b9428edaf4109e86a97254228d831767d0acc1f8 ]
Concurrent evaluations of ASUS WMI management methods (from ACPI notify,
HID, userspace daemons, and debugfs) enter the BIOS ACPI/SMM interface
simultaneously, triggering re-entrant SMIs or EC mailbox buffer corruption.
Fix this at the root by introducing a centralized evaluation helper
(asus_wmi_evaluate_method_locked()) protected by a global mutex
(asus_wmi_eval_lock) using guard(mutex). Route all evaluations of
ASUS_WMI_MGMT_GUID (method3, method5, method_buf, and show_call) through
this helper.
A static mutex is required because asus_wmi_evaluate_method() is an
exported symbol used by external modules (such as hid-asus and
asus-armoury) that lack access to struct asus_wmi drvdata, and the
underlying ASUS ACPI/EC management method is a single physical platform
resource.
The mutex is non-recursive: nested ACPI/WMI notify handlers must not call
back into evaluate on the same task (defer via workqueue, as
asus_rfkill_notify already does).
The sysfs-versus-notify race predates the later export of
asus_wmi_evaluate_method(), so Fixes points at the original shared
evaluate helper rather than that export.
Link: https://github.com/OpenGamingCollective/asusctl/issues/328
Fixes: d33da3b68669 ("asus-wmi: factorise wmi_evaluate_method call")
Cc: stable@vger.kernel.org
Signed-off-by: Marco Scardovi <scardracs@disroot.org>
Reviewed-by: Denis Benato <denis.benato@linux.dev>
Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/b6a1981777e63f0c28bd719d8203ebbda57d6957.1789722252.git.scardracs@disroot.org
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
[ sashal: Adjusted include-block context because the bits.h header was absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/asus-wmi.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
index c8cc47df9294e..75316c268a74e 100644
--- a/drivers/platform/x86/asus-wmi.c
+++ b/drivers/platform/x86/asus-wmi.c
@@ -15,6 +15,7 @@
#include <linux/acpi.h>
#include <linux/backlight.h>
+#include <linux/cleanup.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dmi.h>
@@ -27,6 +28,7 @@
#include <linux/leds.h>
#include <linux/minmax.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/pci_hotplug.h>
#include <linux/platform_data/x86/asus-wmi.h>
@@ -341,6 +343,20 @@ static enum asus_ally_mcu_hack use_ally_mcu_hack = ASUS_WMI_ALLY_MCU_HACK_INIT;
/* WMI ************************************************************************/
+/*
+ * Concurrent evaluations of ASUS WMI methods can re-enter firmware
+ * SMI/EC mailbox handling and corrupt the mailbox.
+ */
+static DEFINE_MUTEX(asus_wmi_eval_lock);
+
+static acpi_status asus_wmi_evaluate_method_locked(u32 method_id,
+ struct acpi_buffer *input,
+ struct acpi_buffer *output)
+{
+ guard(mutex)(&asus_wmi_eval_lock);
+ return wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id, input, output);
+}
+
static int asus_wmi_evaluate_method3(u32 method_id,
u32 arg0, u32 arg1, u32 arg2, u32 *retval)
{
@@ -355,8 +371,7 @@ static int asus_wmi_evaluate_method3(u32 method_id,
union acpi_object *obj;
u32 tmp = 0;
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
+ status = asus_wmi_evaluate_method_locked(method_id, &input, &output);
pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x\n",
__func__, method_id, arg0, arg1, arg2);
@@ -407,8 +422,7 @@ static int asus_wmi_evaluate_method5(u32 method_id,
union acpi_object *obj;
u32 tmp = 0;
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
+ status = asus_wmi_evaluate_method_locked(method_id, &input, &output);
pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x\n",
__func__, method_id, arg0, arg1, arg2, arg3, arg4);
@@ -455,8 +469,7 @@ static int asus_wmi_evaluate_method_buf(u32 method_id,
union acpi_object *obj;
int err = 0;
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 0, method_id,
- &input, &output);
+ status = asus_wmi_evaluate_method_locked(method_id, &input, &output);
pr_debug("%s called (0x%08x) with args: 0x%08x, 0x%08x\n",
__func__, method_id, arg0, arg1);
@@ -4656,9 +4669,8 @@ static int show_call(struct seq_file *m, void *data)
union acpi_object *obj;
acpi_status status;
- status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
- 0, asus->debug.method_id,
- &input, &output);
+ status = asus_wmi_evaluate_method_locked(asus->debug.method_id,
+ &input, &output);
if (ACPI_FAILURE(status))
return -EIO;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 578/686] KVM: arm64: nv: Move L2->L1 switch on interrupt early
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (576 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 577/686] platform/x86: asus-wmi: Serialize WMI method evaluations with a mutex Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 579/686] media: rockchip: rga: use clk_bulk api Greg Kroah-Hartman
` (107 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fuad Tabba, Marc Zyngier,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier <maz@kernel.org>
[ Upstream commit 21d3b33234ebbb675c2a2a0fa7b12d2d83953d7a ]
NV request generation to switch from L2 to L1 on interrupt is buried
into the vgic flush code, while we should be able to deliver requests
as early as possible.
Similarly, MI generation happens *after* the need for a request has been
evaluated, which means we potentially delay the maintenance interrupt by
a full exit/entry cycle.
Move these two things to happen much earlier in the entry code, and make
sure the MI generation and PMU interrupt serve as input to the request
switching back from L2 to L1.
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-2-maz@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>
[ sashal: retained the maintenance-interrupt recalculation guard to accommodate delayed nested VGIC register synchronization ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kvm/arm.c | 4 ++--
arch/arm64/kvm/nested.c | 10 ++++++++++
arch/arm64/kvm/vgic/vgic.c | 11 ++---------
3 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c
index 4e0db01a528a8..1cf6b60382003 100644
--- a/arch/arm64/kvm/arm.c
+++ b/arch/arm64/kvm/arm.c
@@ -1225,11 +1225,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
*/
preempt_disable();
- kvm_nested_flush_hwstate(vcpu);
-
if (kvm_vcpu_has_pmu(vcpu))
kvm_pmu_flush_hwstate(vcpu);
+ kvm_nested_flush_hwstate(vcpu);
+
local_irq_disable();
/*
diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c
index 92853a343c429..9e1ce558fb7e9 100644
--- a/arch/arm64/kvm/nested.c
+++ b/arch/arm64/kvm/nested.c
@@ -16,6 +16,7 @@
#include <asm/sysreg.h>
#include "sys_regs.h"
+#include "vgic/vgic.h"
struct vncr_tlb {
/* The guest's VNCR_EL2 */
@@ -1879,6 +1880,9 @@ void check_nested_vcpu_requests(struct kvm_vcpu *vcpu)
*
* What follows is some slop to (1) react to exception routing / masking and (2)
* preserve the pending SError state across translation regimes.
+ *
+ * Also generate the maintenance interrupt state, and finally check that if
+ * we need to take an interrupt targetting the guest hypervisor.
*/
void kvm_nested_flush_hwstate(struct kvm_vcpu *vcpu)
{
@@ -1887,6 +1891,12 @@ void kvm_nested_flush_hwstate(struct kvm_vcpu *vcpu)
if (unlikely(vcpu_test_and_clear_flag(vcpu, NESTED_SERROR_PENDING)))
kvm_inject_serror_esr(vcpu, vcpu_get_vsesr(vcpu));
+
+ if (!vgic_state_is_nested(vcpu))
+ vgic_v3_nested_update_mi(vcpu);
+
+ if (vgic_state_is_nested(vcpu) && kvm_vgic_vcpu_pending_irq(vcpu))
+ kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu);
}
void kvm_nested_sync_hwstate(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/vgic/vgic.c b/arch/arm64/kvm/vgic/vgic.c
index 7c8ec44824157..23720e1131b40 100644
--- a/arch/arm64/kvm/vgic/vgic.c
+++ b/arch/arm64/kvm/vgic/vgic.c
@@ -969,7 +969,7 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
*
* We do that by placing a request to ourselves which will
* abort the entry procedure and inject the exception at the
- * beginning of the run loop.
+ * beginning of the run loop (see kvm_nested_flush_hwstate()).
*
* - Otherwise, do exactly *NOTHING*. The guest state is
* already loaded, and we can carry on with running it.
@@ -977,15 +977,8 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
* If we have NV, but are not in a nested state, compute the
* maintenance interrupt state, as it may fire.
*/
- if (vgic_state_is_nested(vcpu)) {
- if (kvm_vgic_vcpu_pending_irq(vcpu))
- kvm_make_request(KVM_REQ_GUEST_HYP_IRQ_PENDING, vcpu);
-
+ if (vgic_state_is_nested(vcpu))
return;
- }
-
- if (vcpu_has_nv(vcpu))
- vgic_v3_nested_update_mi(vcpu);
/*
* If there are no virtual interrupts active or pending for this
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 579/686] media: rockchip: rga: use clk_bulk api
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (577 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 578/686] KVM: arm64: nv: Move L2->L1 switch on interrupt early Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 580/686] media: rockchip: rga: quiesce IRQ before releasing m2m state Greg Kroah-Hartman
` (106 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolas Dufresne, Sven Püschel,
Hans Verkuil, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Püschel <s.pueschel@pengutronix.de>
[ Upstream commit a2a4f69fd2e333bacd17d1788eb5211cb6f373cc ]
Use the clk_bulk API to avoid code duplication for each of the three
clocks.
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Sven Püschel <s.pueschel@pengutronix.de>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Stable-dep-of: a875c43dd95e ("media: rockchip: rga: quiesce IRQ before releasing m2m state")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/rockchip/rga/rga.c | 65 +++--------------------
drivers/media/platform/rockchip/rga/rga.h | 6 +--
2 files changed, 11 insertions(+), 60 deletions(-)
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index 776046de979aa..f0bbd161fa92f 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -702,48 +702,10 @@ static const struct video_device rga_videodev = {
.device_caps = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_STREAMING,
};
-static int rga_enable_clocks(struct rockchip_rga *rga)
-{
- int ret;
-
- ret = clk_prepare_enable(rga->sclk);
- if (ret) {
- dev_err(rga->dev, "Cannot enable rga sclk: %d\n", ret);
- return ret;
- }
-
- ret = clk_prepare_enable(rga->aclk);
- if (ret) {
- dev_err(rga->dev, "Cannot enable rga aclk: %d\n", ret);
- goto err_disable_sclk;
- }
-
- ret = clk_prepare_enable(rga->hclk);
- if (ret) {
- dev_err(rga->dev, "Cannot enable rga hclk: %d\n", ret);
- goto err_disable_aclk;
- }
-
- return 0;
-
-err_disable_aclk:
- clk_disable_unprepare(rga->aclk);
-err_disable_sclk:
- clk_disable_unprepare(rga->sclk);
-
- return ret;
-}
-
-static void rga_disable_clocks(struct rockchip_rga *rga)
-{
- clk_disable_unprepare(rga->sclk);
- clk_disable_unprepare(rga->hclk);
- clk_disable_unprepare(rga->aclk);
-}
-
static int rga_parse_dt(struct rockchip_rga *rga)
{
struct reset_control *core_rst, *axi_rst, *ahb_rst;
+ int ret;
core_rst = devm_reset_control_get(rga->dev, "core");
if (IS_ERR(core_rst)) {
@@ -775,23 +737,12 @@ static int rga_parse_dt(struct rockchip_rga *rga)
udelay(1);
reset_control_deassert(ahb_rst);
- rga->sclk = devm_clk_get(rga->dev, "sclk");
- if (IS_ERR(rga->sclk)) {
- dev_err(rga->dev, "failed to get sclk clock\n");
- return PTR_ERR(rga->sclk);
- }
-
- rga->aclk = devm_clk_get(rga->dev, "aclk");
- if (IS_ERR(rga->aclk)) {
- dev_err(rga->dev, "failed to get aclk clock\n");
- return PTR_ERR(rga->aclk);
- }
-
- rga->hclk = devm_clk_get(rga->dev, "hclk");
- if (IS_ERR(rga->hclk)) {
- dev_err(rga->dev, "failed to get hclk clock\n");
- return PTR_ERR(rga->hclk);
+ ret = devm_clk_bulk_get_all(rga->dev, &rga->clks);
+ if (ret < 0) {
+ dev_err(rga->dev, "failed to get clocks\n");
+ return ret;
}
+ rga->num_clks = ret;
return 0;
}
@@ -939,7 +890,7 @@ static int __maybe_unused rga_runtime_suspend(struct device *dev)
{
struct rockchip_rga *rga = dev_get_drvdata(dev);
- rga_disable_clocks(rga);
+ clk_bulk_disable_unprepare(rga->num_clks, rga->clks);
return 0;
}
@@ -948,7 +899,7 @@ static int __maybe_unused rga_runtime_resume(struct device *dev)
{
struct rockchip_rga *rga = dev_get_drvdata(dev);
- return rga_enable_clocks(rga);
+ return clk_bulk_prepare_enable(rga->num_clks, rga->clks);
}
static const struct dev_pm_ops rga_pm = {
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
index 72a28b120fabf..2db10acecb405 100644
--- a/drivers/media/platform/rockchip/rga/rga.h
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -6,6 +6,7 @@
#ifndef __RGA_H__
#define __RGA_H__
+#include <linux/clk.h>
#include <linux/platform_device.h>
#include <media/videobuf2-v4l2.h>
#include <media/v4l2-ctrls.h>
@@ -81,9 +82,8 @@ struct rockchip_rga {
struct device *dev;
struct regmap *grf;
void __iomem *regs;
- struct clk *sclk;
- struct clk *aclk;
- struct clk *hclk;
+ struct clk_bulk_data *clks;
+ int num_clks;
struct rockchip_rga_version version;
/* vfd lock */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 580/686] media: rockchip: rga: quiesce IRQ before releasing m2m state
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (578 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 579/686] media: rockchip: rga: use clk_bulk api Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 581/686] filemap: Add folio_next_pos() Greg Kroah-Hartman
` (105 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fan Wu, Nicolas Dufresne,
Hans Verkuil, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
[ Upstream commit a875c43dd95ee4f9c4e3e5ae1cb8362cc6d7817d ]
rga_remove() releases the m2m state before the IRQ is freed. The IRQ is
devm-managed and is only released once rga_remove() returns, so rga_isr()
can still run while the m2m device state is being torn down.
Store the IRQ number in struct rockchip_rga, unregister the video device
first, and free the IRQ before releasing the m2m state so the handler
cannot run against the freed state.
Fixes: f7e7b48e6d79 ("[media] rockchip/rga: v4l2 m2m support")
Cc: stable@vger.kernel.org
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/rockchip/rga/rga.c | 4 +++-
drivers/media/platform/rockchip/rga/rga.h | 1 +
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/media/platform/rockchip/rga/rga.c b/drivers/media/platform/rockchip/rga/rga.c
index f0bbd161fa92f..f956f2fb222a1 100644
--- a/drivers/media/platform/rockchip/rga/rga.c
+++ b/drivers/media/platform/rockchip/rga/rga.c
@@ -782,6 +782,7 @@ static int rga_probe(struct platform_device *pdev)
ret = irq;
goto err_put_clk;
}
+ rga->irq = irq;
ret = devm_request_irq(rga->dev, irq, rga_isr, 0,
dev_name(rga->dev), rga);
@@ -879,8 +880,9 @@ static void rga_remove(struct platform_device *pdev)
v4l2_info(&rga->v4l2_dev, "Removing\n");
- v4l2_m2m_release(rga->m2m_dev);
video_unregister_device(rga->vfd);
+ devm_free_irq(rga->dev, rga->irq, rga);
+ v4l2_m2m_release(rga->m2m_dev);
v4l2_device_unregister(&rga->v4l2_dev);
pm_runtime_disable(rga->dev);
diff --git a/drivers/media/platform/rockchip/rga/rga.h b/drivers/media/platform/rockchip/rga/rga.h
index 2db10acecb405..0a15ec9aa8aae 100644
--- a/drivers/media/platform/rockchip/rga/rga.h
+++ b/drivers/media/platform/rockchip/rga/rga.h
@@ -82,6 +82,7 @@ struct rockchip_rga {
struct device *dev;
struct regmap *grf;
void __iomem *regs;
+ int irq;
struct clk_bulk_data *clks;
int num_clks;
struct rockchip_rga_version version;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 581/686] filemap: Add folio_next_pos()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (579 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 580/686] media: rockchip: rga: quiesce IRQ before releasing m2m state Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 582/686] xfs: Use folio_next_pos() Greg Kroah-Hartman
` (104 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Wilcox (Oracle), Joseph Qi,
Christoph Hellwig, Mark Fasheh, Joel Becker, ocfs2-devel,
Christian Brauner, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <willy@infradead.org>
[ Upstream commit 4511fd86db6f8f94f8aff01044f5c69aa38f81f4 ]
Replace the open-coded implementation in ocfs2 (which loses the top
32 bits on 32-bit architectures) with a helper in pagemap.h.
Fixes: 35edec1d52c0 (ocfs2: update truncate handling of partial clusters)
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Link: https://patch.msgid.link/20251024170822.1427218-2-willy@infradead.org
Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: ocfs2-devel@lists.linux.dev
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 329750292e9d ("xfarray: don't crash when sorting if array element crosses a folio")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/alloc.c | 2 +-
include/linux/pagemap.h | 11 +++++++++++
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index fb7d8dc2129be..d22ad99c9ebee 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6891,7 +6891,7 @@ static void ocfs2_zero_cluster_folios(struct inode *inode, loff_t start,
ocfs2_map_and_dirty_folio(inode, handle, from, to, folio, 1,
&phys);
- start = folio_next_index(folio) << PAGE_SHIFT;
+ start = folio_next_pos(folio);
}
out:
if (folios)
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 09b581c1d878d..e16576e3763a1 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -941,6 +941,17 @@ static inline pgoff_t folio_next_index(const struct folio *folio)
return folio->index + folio_nr_pages(folio);
}
+/**
+ * folio_next_pos - Get the file position of the next folio.
+ * @folio: The current folio.
+ *
+ * Return: The position of the folio which follows this folio in the file.
+ */
+static inline loff_t folio_next_pos(const struct folio *folio)
+{
+ return (loff_t)folio_next_index(folio) << PAGE_SHIFT;
+}
+
/**
* folio_file_page - The page for a particular index.
* @folio: The folio which contains this index.
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 582/686] xfs: Use folio_next_pos()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (580 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 581/686] filemap: Add folio_next_pos() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 583/686] xfarray: dont crash when sorting if array element crosses a folio Greg Kroah-Hartman
` (103 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Wilcox (Oracle),
Christoph Hellwig, Carlos Maiolino, linux-xfs, Christian Brauner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <willy@infradead.org>
[ Upstream commit ac0a11113de3f0007283d20f5a38615ea4c6e9fd ]
This is one instruction more efficient than open-coding folio_pos() +
folio_size(). It's the equivalent of (x + y) << z rather than
x << z + y << z.
Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
Link: https://patch.msgid.link/20251024170822.1427218-10-willy@infradead.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Cc: Carlos Maiolino <cem@kernel.org>
Cc: linux-xfs@vger.kernel.org
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 329750292e9d ("xfarray: don't crash when sorting if array element crosses a folio")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/xfs/scrub/xfarray.c | 2 +-
fs/xfs/xfs_aops.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/xfs/scrub/xfarray.c b/fs/xfs/scrub/xfarray.c
index ccf7cfb63bbc8..78880b76b15d0 100644
--- a/fs/xfs/scrub/xfarray.c
+++ b/fs/xfs/scrub/xfarray.c
@@ -833,7 +833,7 @@ xfarray_sort_scan(
si->first_folio_idx = xfarray_idx(si->array,
folio_pos(si->folio) + si->array->obj_size - 1);
- next_pos = folio_pos(si->folio) + folio_size(si->folio);
+ next_pos = folio_next_pos(si->folio);
si->last_folio_idx = xfarray_idx(si->array, next_pos - 1);
if (xfarray_pos(si->array, si->last_folio_idx + 1) > next_pos)
si->last_folio_idx--;
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 9845a5fcf8575..4c9afca35fefa 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -271,7 +271,7 @@ xfs_discard_folio(
* folio itself and not the start offset that is passed in.
*/
xfs_bmap_punch_delalloc_range(ip, XFS_DATA_FORK, pos,
- folio_pos(folio) + folio_size(folio), NULL);
+ folio_next_pos(folio), NULL);
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 583/686] xfarray: dont crash when sorting if array element crosses a folio
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (581 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 582/686] xfs: Use folio_next_pos() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 584/686] s390/pci: Add error cleanup in zpci_directed_irq_init() Greg Kroah-Hartman
` (102 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
[ Upstream commit 329750292e9dfbb594b375d7b30cf5ddb58b7bb9 ]
LOLLM points out that if an array element crosses a folio boundary,
xfile_get_folio returns a NULL folio pointer. If this happens,
si->folio is also set to NULL, and calling folio_pos/folio_address will
just crash the kernel. Teach this function to handle this condition by
falling back to reading the array element into scratchpad memory.
Cc: stable@vger.kernel.org # v6.6
Fixes: cf36f4f64c2d4e ("xfs: cache pages used for xfarray quicksort convergence")
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/xfarray.c | 69 ++++++++++++++++++++++++++++--------------
1 file changed, 47 insertions(+), 22 deletions(-)
diff --git a/fs/xfs/scrub/xfarray.c b/fs/xfs/scrub/xfarray.c
index 78880b76b15d0..5e1b56defabd0 100644
--- a/fs/xfs/scrub/xfarray.c
+++ b/fs/xfs/scrub/xfarray.c
@@ -794,6 +794,46 @@ xfarray_sort_scan_done(
si->folio = NULL;
}
+static int
+xfarray_sort_load_folio(
+ struct xfarray_sortinfo *si,
+ xfarray_idx_t idx,
+ loff_t idx_pos)
+{
+ struct folio *folio;
+ loff_t next_pos;
+
+ folio = xfile_get_folio(si->array->xfile, idx_pos, si->array->obj_size,
+ XFILE_ALLOC);
+ if (IS_ERR(folio))
+ return PTR_ERR(folio);
+ si->folio = folio;
+
+ /* No folio? Get the caller to read into the scratchpad. */
+ if (!si->folio)
+ return 0;
+
+ si->first_folio_idx = xfarray_idx(si->array,
+ folio_pos(si->folio) + si->array->obj_size - 1);
+
+ next_pos = folio_next_pos(si->folio);
+ si->last_folio_idx = xfarray_idx(si->array, next_pos - 1);
+ if (xfarray_pos(si->array, si->last_folio_idx + 1) > next_pos)
+ si->last_folio_idx--;
+
+ /*
+ * If this folio still doesn't cover the desired element, it must cross
+ * a folio boundary. Get the caller to read into the scratchpad.
+ */
+ if (idx < si->first_folio_idx || idx > si->last_folio_idx) {
+ xfarray_sort_scan_done(si);
+ return 0;
+ }
+
+ trace_xfarray_sort_scan(si, idx);
+ return 0;
+}
+
/*
* Cache the folio backing the start of the given array element. If the array
* element is contained entirely within the folio, return a pointer to the
@@ -819,33 +859,18 @@ xfarray_sort_scan(
(idx < si->first_folio_idx || idx > si->last_folio_idx))
xfarray_sort_scan_done(si);
- /* Grab the first folio that backs this array element. */
+ /* Grab the folio that backs this array element. */
if (!si->folio) {
- struct folio *folio;
- loff_t next_pos;
-
- folio = xfile_get_folio(si->array->xfile, idx_pos,
- si->array->obj_size, XFILE_ALLOC);
- if (IS_ERR(folio))
- return PTR_ERR(folio);
- si->folio = folio;
-
- si->first_folio_idx = xfarray_idx(si->array,
- folio_pos(si->folio) + si->array->obj_size - 1);
-
- next_pos = folio_next_pos(si->folio);
- si->last_folio_idx = xfarray_idx(si->array, next_pos - 1);
- if (xfarray_pos(si->array, si->last_folio_idx + 1) > next_pos)
- si->last_folio_idx--;
-
- trace_xfarray_sort_scan(si, idx);
+ error = xfarray_sort_load_folio(si, idx, idx_pos);
+ if (error)
+ return error;
}
/*
- * If this folio still doesn't cover the desired element, it must cross
- * a folio boundary. Read into the scratchpad and we're done.
+ * If we don't have a folio mapping the entire array element, read into
+ * the scratchpad and we're done.
*/
- if (idx < si->first_folio_idx || idx > si->last_folio_idx) {
+ if (!si->folio) {
void *temp = xfarray_scratch(si->array);
error = xfile_load(si->array->xfile, temp, si->array->obj_size,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 584/686] s390/pci: Add error cleanup in zpci_directed_irq_init()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (582 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 583/686] xfarray: dont crash when sorting if array element crosses a folio Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 585/686] serial: sc16is7xx: declare SPR/TLR/XOFF2 register as volatile Greg Kroah-Hartman
` (101 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tobias Schumacher, Niklas Schnelle,
Heiko Carstens, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tobias Schumacher <ts@linux.ibm.com>
[ Upstream commit 769f66f595c11185c66913ea5d96420504bfebc3 ]
If per-CPU airq_iv allocation fails in the loop, previously allocated
vectors and arrays leak. Add proper error path to release all resources
on failure.
The error path frees zpci_sbv, but SIC_IRQ_MODE_DIRECT has already
programmed its address into the hardware. Set the directed interrupt
mode only after all allocations have succeeded, so a failed init leaves
no freed memory registered with the hardware.
Fixes: e979ce7bced2 ("s390/pci: provide support for CPU directed interrupts")
Cc: stable@vger.kernel.org
Signed-off-by: Tobias Schumacher <ts@linux.ibm.com>
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
[ sashal: Adapted cleanup references from zpci_dibv to the existing zpci_ibv array. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/pci/pci_irq.c | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c
index e73be96ce5fe6..836db17f4e8f6 100644
--- a/arch/s390/pci/pci_irq.c
+++ b/arch/s390/pci/pci_irq.c
@@ -450,15 +450,10 @@ static int __init zpci_directed_irq_init(void)
if (!zpci_sbv)
return -ENOMEM;
- iib.diib.isc = PCI_ISC;
- iib.diib.nr_cpus = num_possible_cpus();
- iib.diib.disb_addr = virt_to_phys(zpci_sbv->vector);
- zpci_set_irq_ctrl(SIC_IRQ_MODE_DIRECT, 0, &iib);
-
zpci_ibv = kcalloc(num_possible_cpus(), sizeof(*zpci_ibv),
GFP_KERNEL);
if (!zpci_ibv)
- return -ENOMEM;
+ goto out_free_sbv;
for_each_possible_cpu(cpu) {
/*
@@ -470,13 +465,30 @@ static int __init zpci_directed_irq_init(void)
AIRQ_IV_CACHELINE |
(!cpu ? AIRQ_IV_ALLOC : 0), NULL);
if (!zpci_ibv[cpu])
- return -ENOMEM;
+ goto out_free_dibv;
}
+
+ iib.diib.isc = PCI_ISC;
+ iib.diib.nr_cpus = num_possible_cpus();
+ iib.diib.disb_addr = virt_to_phys(zpci_sbv->vector);
+ zpci_set_irq_ctrl(SIC_IRQ_MODE_DIRECT, 0, &iib);
on_each_cpu(cpu_enable_directed_irq, NULL, 1);
zpci_irq_chip.irq_set_affinity = zpci_set_irq_affinity;
return 0;
+
+out_free_dibv:
+ for_each_possible_cpu(cpu) {
+ if (zpci_ibv[cpu])
+ airq_iv_release(zpci_ibv[cpu]);
+ }
+ kfree(zpci_ibv);
+ zpci_ibv = NULL;
+out_free_sbv:
+ airq_iv_release(zpci_sbv);
+ zpci_sbv = NULL;
+ return -ENOMEM;
}
static int __init zpci_floating_irq_init(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 585/686] serial: sc16is7xx: declare SPR/TLR/XOFF2 register as volatile
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (583 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 584/686] s390/pci: Add error cleanup in zpci_directed_irq_init() Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 586/686] serial: sc16is7xx: add comments for lock requirements Greg Kroah-Hartman
` (100 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hugo Villeneuve, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
[ Upstream commit 983f91e5f13149ade6dbd9568053ecd0ab5e9265 ]
SPR shares the same address space as TLR and XOFF2. If SPR or TLR were to
be used eventually, this could lead to incorrect read value from the cache.
Prevent this potential bug by declaring SPR/TLR/XOFF2 as volatile.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Link: https://patch.msgid.link/20251027142957.1032073-8-hugo@hugovil.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 1c41d09dcd07 ("serial: sc16is7xx: declare MCR and IER as volatile registers")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/serial/sc16is7xx.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 42ad926f1fe68..7cf3056b93939 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -542,6 +542,7 @@ static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg)
case SC16IS7XX_IIR_REG:
case SC16IS7XX_LSR_REG:
case SC16IS7XX_MSR_REG:
+ case SC16IS7XX_SPR_REG: /* Shared address space with TLR & XOFF2 */
case SC16IS7XX_TXLVL_REG:
case SC16IS7XX_RXLVL_REG:
case SC16IS7XX_IOSTATE_REG:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 586/686] serial: sc16is7xx: add comments for lock requirements
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (584 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 585/686] serial: sc16is7xx: declare SPR/TLR/XOFF2 register as volatile Greg Kroah-Hartman
@ 2026-11-13 15:51 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 587/686] serial: sc16is7xx: declare MCR and IER as volatile registers Greg Kroah-Hartman
` (99 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:51 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hugo Villeneuve, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
[ Upstream commit 42405cb77fd35b5acc0e5a11d74eef68c2afa484 ]
Indicate why lock needs to be asserted when accessing
MSR register, as this is not immediately obvious when looking at this
register in the device datasheet.
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Link: https://patch.msgid.link/20251027142957.1032073-15-hugo@hugovil.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 1c41d09dcd07 ("serial: sc16is7xx: declare MCR and IER as volatile registers")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/serial/sc16is7xx.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index 7cf3056b93939..b2d020a0b20d0 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -538,10 +538,10 @@ EXPORT_SYMBOL_GPL(sc16is762_devtype);
static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
- case SC16IS7XX_RHR_REG:
- case SC16IS7XX_IIR_REG:
- case SC16IS7XX_LSR_REG:
- case SC16IS7XX_MSR_REG:
+ case SC16IS7XX_RHR_REG: /* Shared address space with THR & DLL */
+ case SC16IS7XX_IIR_REG: /* Shared address space with FCR & EFR */
+ case SC16IS7XX_LSR_REG: /* Shared address space with XON2 */
+ case SC16IS7XX_MSR_REG: /* Shared address space with TCR & XOFF1 */
case SC16IS7XX_SPR_REG: /* Shared address space with TLR & XOFF2 */
case SC16IS7XX_TXLVL_REG:
case SC16IS7XX_RXLVL_REG:
@@ -785,6 +785,7 @@ static void sc16is7xx_update_mlines(struct sc16is7xx_one *one)
unsigned long flags;
unsigned int status, changed;
+ /* Lock required as MSR address is shared with TCR and XOFF1. */
lockdep_assert_held_once(&one->lock);
status = sc16is7xx_get_hwmctrl(port);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 587/686] serial: sc16is7xx: declare MCR and IER as volatile registers
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (585 preceding siblings ...)
2026-11-13 15:51 ` [PATCH 6.18 586/686] serial: sc16is7xx: add comments for lock requirements Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 588/686] virtiofs: add FUSE protocol validation Greg Kroah-Hartman
` (98 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, stable, Hugo Villeneuve, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve <hvilleneuve@dimonoff.com>
[ Upstream commit 1c41d09dcd07ee9648e20aa8238e404c2e6a12fb ]
MCR register has the same address as XON1 register.
IER register has the same address as DLH register.
Which register is accessed depends on bits configuration in some
other registers.
To prevent potential access errors, declare MCR and IER as volatile
registers.
Fixes: dfeae619d781 ("serial: sc16is7xx")
Cc: stable@kernel.org
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
Link: https://patch.msgid.link/20261006192540.234402-1-hugo@hugovil.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/serial/sc16is7xx.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index b2d020a0b20d0..b5e301741b844 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -539,7 +539,9 @@ static bool sc16is7xx_regmap_volatile(struct device *dev, unsigned int reg)
{
switch (reg) {
case SC16IS7XX_RHR_REG: /* Shared address space with THR & DLL */
+ case SC16IS7XX_IER_REG: /* Shared address space with DLH */
case SC16IS7XX_IIR_REG: /* Shared address space with FCR & EFR */
+ case SC16IS7XX_MCR_REG: /* Shared address space with XON1 */
case SC16IS7XX_LSR_REG: /* Shared address space with XON2 */
case SC16IS7XX_MSR_REG: /* Shared address space with TCR & XOFF1 */
case SC16IS7XX_SPR_REG: /* Shared address space with TLR & XOFF2 */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 588/686] virtiofs: add FUSE protocol validation
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (586 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 587/686] serial: sc16is7xx: declare MCR and IER as volatile registers Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 589/686] virtiofs: validate fixed-output response length Greg Kroah-Hartman
` (97 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuto Ohnuki, Stefan Hajnoczi,
Miklos Szeredi, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuto Ohnuki <ytohnuki@amazon.com>
[ Upstream commit 68b69fa0edb241a946cd4c850110990f30705164 ]
Add virtio_fs_verify_response() to validate that the server properly
follows the FUSE protocol by checking:
- Response length is at least sizeof(struct fuse_out_header).
- oh.len matches the actual response length.
- oh.unique matches the request's unique identifier.
On validation failure, set error to -EIO and normalize oh.len to prevent
underflow in copy_args_from_argbuf().
Addresses the TODO comment in virtio_fs_request_complete().
Signed-off-by: Yuto Ohnuki <ytohnuki@amazon.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Stable-dep-of: 5364d081125a ("virtiofs: validate fixed-output response length")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/fuse/virtio_fs.c | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index e475f7f9e83d4..33962e1ad8c12 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -755,6 +755,27 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
req->argbuf = NULL;
}
+/* Verify that the server properly follows the FUSE protocol */
+static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
+{
+ struct fuse_out_header *oh = &req->out.h;
+
+ if (len < sizeof(*oh)) {
+ pr_warn("virtio-fs: response too short (%u)\n", len);
+ return false;
+ }
+ if (oh->len != len) {
+ pr_warn("virtio-fs: oh.len mismatch (%u != %u)\n", oh->len, len);
+ return false;
+ }
+ if (oh->unique != req->in.h.unique) {
+ pr_warn("virtio-fs: oh.unique mismatch (%llu != %llu)\n",
+ oh->unique, req->in.h.unique);
+ return false;
+ }
+ return true;
+}
+
/* Work function for request completion */
static void virtio_fs_request_complete(struct fuse_req *req,
struct virtio_fs_vq *fsvq)
@@ -764,10 +785,6 @@ static void virtio_fs_request_complete(struct fuse_req *req,
unsigned int len, i, thislen;
struct folio *folio;
- /*
- * TODO verify that server properly follows FUSE protocol
- * (oh.uniq, oh.len)
- */
args = req->args;
copy_args_from_argbuf(args, req);
@@ -821,6 +838,10 @@ static void virtio_fs_requests_done_work(struct work_struct *work)
virtqueue_disable_cb(vq);
while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
+ if (!virtio_fs_verify_response(req, len)) {
+ req->out.h.error = -EIO;
+ req->out.h.len = sizeof(struct fuse_out_header);
+ }
spin_lock(&fpq->lock);
list_move_tail(&req->list, &reqs);
spin_unlock(&fpq->lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 589/686] virtiofs: validate fixed-output response length
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (587 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 588/686] virtiofs: add FUSE protocol validation Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 590/686] rculist: Add hlist_nulls_replace_rcu() and hlist_nulls_replace_init_rcu() Greg Kroah-Hartman
` (96 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sung Byeongchan, Miklos Szeredi,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sung Byeongchan <tjdqudcks0424@naver.com>
[ Upstream commit 5364d081125a34e90851fbb46ecc93f79339ce78 ]
A short successful virtiofs response can leave the fixed-output portion of
the request argument buffer unwritten. The completion path nevertheless
copies the full declared output to the request destination, allowing stale
allocator contents to reach callers such as fuse_statfs().
Require successful fixed-output responses to contain their complete
declared output. Continue to permit a shorter final argument only for
out_argvar requests. Reject positive and internal restart error values
and require valid error replies to be header-only. The error already
stored in the FUSE output header is returned by fuse_request_end(), so do
not copy output arguments from an error reply.
This was found by source review with AI assistance. A header-only
successful FUSE_STATFS reply returned stale fields in nine of nine calls
across three boots. The fixed kernel rejected the short response and
preserved complete replies, valid negative-error replies, and
variable-output replies.
Fixes: a62a8ef9d97d ("virtio-fs: add virtiofs filesystem")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Sung Byeongchan <tjdqudcks0424@naver.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/fuse/virtio_fs.c | 30 ++++++++++++++++++++++++++++++
1 file changed, 30 insertions(+)
diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c
index 33962e1ad8c12..7075984a89aad 100644
--- a/fs/fuse/virtio_fs.c
+++ b/fs/fuse/virtio_fs.c
@@ -726,6 +726,10 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
unsigned int num_out;
unsigned int i;
+ /* fuse_request_end() returns this error; there are no args to copy. */
+ if (req->out.h.error)
+ goto out;
+
remaining = req->out.h.len - sizeof(req->out.h);
num_in = args->in_numargs - args->in_pages;
num_out = args->out_numargs - args->out_pages;
@@ -751,6 +755,7 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
if (args->out_argvar)
args->out_args[args->out_numargs - 1].size = remaining;
+out:
kfree(req->argbuf);
req->argbuf = NULL;
}
@@ -758,7 +763,9 @@ static void copy_args_from_argbuf(struct fuse_args *args, struct fuse_req *req)
/* Verify that the server properly follows the FUSE protocol */
static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
{
+ struct fuse_args *args = req->args;
struct fuse_out_header *oh = &req->out.h;
+ unsigned int expected;
if (len < sizeof(*oh)) {
pr_warn("virtio-fs: response too short (%u)\n", len);
@@ -773,6 +780,29 @@ static bool virtio_fs_verify_response(struct fuse_req *req, unsigned int len)
oh->unique, req->in.h.unique);
return false;
}
+ if (oh->error <= -ERESTARTSYS || oh->error > 0) {
+ pr_warn("virtio-fs: invalid error value (%d)\n", oh->error);
+ return false;
+ }
+
+ if (oh->error) {
+ if (len != sizeof(*oh)) {
+ pr_warn("virtio-fs: error response too long (%u)\n", len);
+ return false;
+ }
+ return true;
+ }
+
+ expected = sizeof(*oh) +
+ fuse_len_args(args->out_numargs, args->out_args);
+ if (len > expected ||
+ (len < expected &&
+ (!args->out_argvar ||
+ expected - len > args->out_args[args->out_numargs - 1].size))) {
+ pr_warn("virtio-fs: invalid response length (%u, expected %u)\n",
+ len, expected);
+ return false;
+ }
return true;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 590/686] rculist: Add hlist_nulls_replace_rcu() and hlist_nulls_replace_init_rcu()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (588 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 589/686] virtiofs: validate fixed-output response length Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 591/686] mptcp: fix MP_CAPABLE token migration when cloning reqsk Greg Kroah-Hartman
` (95 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kuniyuki Iwashima,
Frederic Weisbecker, Eric Dumazet, Xuanqiang Luo, Jakub Kicinski,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
[ Upstream commit 9c4609225ec1cb551006d6a03c7c4ad8cb5584c0 ]
Add two functions to atomically replace RCU-protected hlist_nulls entries.
Keep using WRITE_ONCE() to assign values to ->next and ->pprev, as
mentioned in the patch below:
commit efd04f8a8b45 ("rcu: Use WRITE_ONCE() for assignments to ->next for
rculist_nulls")
commit 860c8802ace1 ("rcu: Use WRITE_ONCE() for assignments to ->pprev for
hlist_nulls")
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Link: https://patch.msgid.link/20251015020236.431822-2-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 2093bc7fa500 ("mptcp: fix MP_CAPABLE token migration when cloning reqsk")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/rculist_nulls.h | 59 +++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/include/linux/rculist_nulls.h b/include/linux/rculist_nulls.h
index 89186c499dd47..c26cb83ca0711 100644
--- a/include/linux/rculist_nulls.h
+++ b/include/linux/rculist_nulls.h
@@ -52,6 +52,13 @@ static inline void hlist_nulls_del_init_rcu(struct hlist_nulls_node *n)
#define hlist_nulls_next_rcu(node) \
(*((struct hlist_nulls_node __rcu __force **)&(node)->next))
+/**
+ * hlist_nulls_pprev_rcu - returns the dereferenced pprev of @node.
+ * @node: element of the list.
+ */
+#define hlist_nulls_pprev_rcu(node) \
+ (*((struct hlist_nulls_node __rcu __force **)(node)->pprev))
+
/**
* hlist_nulls_del_rcu - deletes entry from hash list without re-initialization
* @n: the element to delete from the hash list.
@@ -152,6 +159,58 @@ static inline void hlist_nulls_add_fake(struct hlist_nulls_node *n)
n->next = (struct hlist_nulls_node *)NULLS_MARKER(NULL);
}
+/**
+ * hlist_nulls_replace_rcu - replace an old entry by a new one
+ * @old: the element to be replaced
+ * @new: the new element to insert
+ *
+ * Description:
+ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while
+ * permitting racing traversals.
+ *
+ * The caller must take whatever precautions are necessary (such as holding
+ * appropriate locks) to avoid racing with another list-mutation primitive, such
+ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same
+ * list. However, it is perfectly legal to run concurrently with the _rcu
+ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu().
+ */
+static inline void hlist_nulls_replace_rcu(struct hlist_nulls_node *old,
+ struct hlist_nulls_node *new)
+{
+ struct hlist_nulls_node *next = old->next;
+
+ WRITE_ONCE(new->next, next);
+ WRITE_ONCE(new->pprev, old->pprev);
+ rcu_assign_pointer(hlist_nulls_pprev_rcu(new), new);
+ if (!is_a_nulls(next))
+ WRITE_ONCE(next->pprev, &new->next);
+}
+
+/**
+ * hlist_nulls_replace_init_rcu - replace an old entry by a new one and
+ * initialize the old
+ * @old: the element to be replaced
+ * @new: the new element to insert
+ *
+ * Description:
+ * Replace the old entry with the new one in a RCU-protected hlist_nulls, while
+ * permitting racing traversals, and reinitialize the old entry.
+ *
+ * Note: @old must be hashed.
+ *
+ * The caller must take whatever precautions are necessary (such as holding
+ * appropriate locks) to avoid racing with another list-mutation primitive, such
+ * as hlist_nulls_add_head_rcu() or hlist_nulls_del_rcu(), running on this same
+ * list. However, it is perfectly legal to run concurrently with the _rcu
+ * list-traversal primitives, such as hlist_nulls_for_each_entry_rcu().
+ */
+static inline void hlist_nulls_replace_init_rcu(struct hlist_nulls_node *old,
+ struct hlist_nulls_node *new)
+{
+ hlist_nulls_replace_rcu(old, new);
+ WRITE_ONCE(old->pprev, NULL);
+}
+
/**
* hlist_nulls_for_each_entry_rcu - iterate over rcu list of given type
* @tpos: the type * to use as a loop cursor.
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 591/686] mptcp: fix MP_CAPABLE token migration when cloning reqsk
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (589 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 590/686] rculist: Add hlist_nulls_replace_rcu() and hlist_nulls_replace_init_rcu() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 592/686] ALSA: ua101: Bound packet copies by the PCM buffer size Greg Kroah-Hartman
` (94 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Sashiko, Ruide Cao, Ren Wei,
Matthieu Baerts (NGI0), Jakub Kicinski, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ruide Cao <caoruide123@gmail.com>
[ Upstream commit 2093bc7fa50056fef8620d2b82bcb2e9a0a5575d ]
TCP request migration clones pending request sockets with
inet_reqsk_clone(). For MPTCP MP_CAPABLE requests this byte-copies the
token_node hlist state into the clone even though the token table still
names the original request, and the following warning can be seen:
WARNING: net/mptcp/token.c:364 at mptcp_token_destroy_request+0x2b0/0x330, CPU#2: swapper/2/0
CPU: 2 UID: 0 PID: 0 Comm: swapper/2 Not tainted 7.2.0-rc5-00353-gc27e36054537 #10 PREEMPT(full)
RIP: 0010:mptcp_token_destroy_request (net/mptcp/token.c:364 (discriminator 1))
Call Trace:
<IRQ>
subflow_v4_req_destructor (net/mptcp/subflow.c:694)
__reqsk_free (net/ipv4/inet_connection_sock.c:906)
reqsk_timer_handler (include/net/request_sock.h:137 net/ipv4/inet_connection_sock.c:1147)
call_timer_fn (kernel/time/timer.c:1748)
Move token request ownership from the original request to the clone under
the token bucket lock. Make mptcp_token_accept() and
mptcp_token_destroy_request() re-check token_node under the same lock and
treat an already moved or removed request as a normal race instead of
warning. This also keeps token bucket chain_len accounting balanced.
If a passive MP_CAPABLE socket cannot claim the token, destroy the
provisional MPTCP socket and let the subflow fall back rather than
installing a socket with mismatched token ownership. Mark that path as a
passive handshake fallback so MPCapableFallbackACK records the downgrade.
If the speculative clone later loses the inet_ehash_insert() ownership
arbitration, the original request may find that its token was already moved
and fall back to plain TCP. The clone destructor then releases the token
reservation and keeps chain_len balanced. This trades an exceptionally
rare fallback for eliminating the warning and persistent accounting drift.
Fixes: c905dee62232 ("tcp: Migrate TCP_NEW_SYN_RECV requests at retransmitting SYN+ACKs.")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/86e2514b533bf4d55d4aa2fdbf1404022e8c9430.1776149210.git.caoruide123%40gmail.com
Signed-off-by: Ruide Cao <caoruide123@gmail.com>
Signed-off-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20261013-net-mptcp-misc-fixes-7-3-rc8-v1-4-932c9b182fc7@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/protocol.c | 31 +++++++++++++++----
net/mptcp/protocol.h | 4 ++-
net/mptcp/subflow.c | 6 +++-
net/mptcp/token.c | 68 +++++++++++++++++++++++++++++++++++++-----
net/mptcp/token_test.c | 4 +--
5 files changed, 97 insertions(+), 16 deletions(-)
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index df09dcfd15ce3..fdd4c7d87775b 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3410,6 +3410,24 @@ static void mptcp_copy_ip_options(struct sock *newsk, const struct sock *sk)
rcu_read_unlock();
}
+static void mptcp_sk_clone_destroy(struct sock *nsk)
+{
+ struct mptcp_sock *msk = mptcp_sk(nsk);
+
+ mptcp_release_sched(msk);
+ mptcp_set_state(nsk, TCP_CLOSE);
+ /* inet_csk_prepare_forced_close() clears TCP sock_ops state via
+ * tcp_sk(), but nsk is an MPTCP master socket; keep the inet-level
+ * destroy preparation here.
+ */
+ bh_unlock_sock(nsk);
+ sock_put(nsk);
+ sock_set_flag(nsk, SOCK_DEAD);
+ tcp_orphan_count_inc();
+ inet_sk(nsk)->inet_num = 0;
+ inet_csk_destroy_sock(nsk);
+}
+
struct sock *mptcp_sk_clone_init(const struct sock *sk,
const struct mptcp_options_received *mp_opt,
struct sock *ssk,
@@ -3469,11 +3487,6 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
list_add(&subflow->node, &msk->conn_list);
sock_hold(ssk);
- /* new mpc subflow takes ownership of the newly
- * created mptcp socket
- */
- mptcp_token_accept(subflow_req, msk);
-
/* set msk addresses early to ensure mptcp_pm_get_local_id()
* uses the correct data
*/
@@ -3482,6 +3495,14 @@ struct sock *mptcp_sk_clone_init(const struct sock *sk,
mptcp_rcv_space_init(msk, ssk);
msk->rcvq_space.time = mptcp_stamp();
+ if (!mptcp_token_accept(subflow_req, msk)) {
+ list_del_init(&subflow->node);
+ WRITE_ONCE(msk->first, NULL);
+ sock_put(ssk);
+ mptcp_sk_clone_destroy(nsk);
+ return NULL;
+ }
+
if (mp_opt->suboptions & OPTION_MPTCP_MPC_ACK)
__mptcp_subflow_fully_established(msk, subflow, mp_opt);
bh_unlock_sock(nsk);
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 184831b5b624a..1b6335408b17f 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -1033,9 +1033,11 @@ static inline void mptcp_token_init_request(struct request_sock *req)
}
int mptcp_token_new_request(struct request_sock *req);
+void mptcp_token_move_request(struct request_sock *req,
+ struct request_sock *new_req);
void mptcp_token_destroy_request(struct request_sock *req);
int mptcp_token_new_connect(struct sock *ssk);
-void mptcp_token_accept(struct mptcp_subflow_request_sock *r,
+bool mptcp_token_accept(struct mptcp_subflow_request_sock *r,
struct mptcp_sock *msk);
bool mptcp_token_exists(u32 token);
struct mptcp_sock *mptcp_token_get_sock(struct net *net, u32 token);
diff --git a/net/mptcp/subflow.c b/net/mptcp/subflow.c
index c2d6a7adca6b2..0f8b7396f446e 100644
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -78,6 +78,8 @@ void mptcp_subflow_reqsk_clone(struct request_sock *req,
}
new_subflow_req->msk = msk;
+
+ mptcp_token_move_request(req, new_req);
}
static void subflow_generate_hmac(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
@@ -931,8 +933,10 @@ static struct sock *subflow_syn_recv_sock(const struct sock *sk,
if (ctx->mp_capable) {
ctx->conn = mptcp_sk_clone_init(listener->conn, &mp_opt, child, req);
- if (!ctx->conn)
+ if (!ctx->conn) {
+ fallback = true;
goto fallback;
+ }
ctx->subflow_id = 1;
owner = mptcp_sk(ctx->conn);
diff --git a/net/mptcp/token.c b/net/mptcp/token.c
index 5bb9245343874..d5735d3ac793b 100644
--- a/net/mptcp/token.c
+++ b/net/mptcp/token.c
@@ -180,6 +180,43 @@ int mptcp_token_new_connect(struct sock *ssk)
return 0;
}
+/**
+ * mptcp_token_move_request - move request token ownership to a clone
+ * @req: original request socket
+ * @new_req: cloned request socket
+ *
+ * Move the token hash entry from the original request to its clone.
+ */
+void mptcp_token_move_request(struct request_sock *req,
+ struct request_sock *new_req)
+{
+ struct mptcp_subflow_request_sock *subflow_req = mptcp_subflow_rsk(req);
+ struct mptcp_subflow_request_sock *new_subflow_req;
+ struct mptcp_subflow_request_sock *pos;
+ struct token_bucket *bucket;
+
+ new_subflow_req = mptcp_subflow_rsk(new_req);
+
+ if (hlist_nulls_unhashed_lockless(&subflow_req->token_node)) {
+ mptcp_token_init_request(new_req);
+ return;
+ }
+
+ bucket = token_bucket(subflow_req->token);
+ spin_lock_bh(&bucket->lock);
+ if (hlist_nulls_unhashed(&subflow_req->token_node)) {
+ mptcp_token_init_request(new_req);
+ } else {
+ pos = __token_lookup_req(bucket, subflow_req->token);
+ if (pos == subflow_req)
+ hlist_nulls_replace_init_rcu(&subflow_req->token_node,
+ &new_subflow_req->token_node);
+ else
+ mptcp_token_init_request(new_req);
+ }
+ spin_unlock_bh(&bucket->lock);
+}
+
/**
* mptcp_token_accept - replace a req sk with full sock in token hash
* @req: the request socket to be removed
@@ -187,24 +224,36 @@ int mptcp_token_new_connect(struct sock *ssk)
*
* Called when a SYN packet creates a new logical connection, i.e.
* is not a join request.
+ *
+ * Return: true on success.
*/
-void mptcp_token_accept(struct mptcp_subflow_request_sock *req,
+bool mptcp_token_accept(struct mptcp_subflow_request_sock *req,
struct mptcp_sock *msk)
{
struct mptcp_subflow_request_sock *pos;
struct sock *sk = (struct sock *)msk;
struct token_bucket *bucket;
+ bool ret = false;
- sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
bucket = token_bucket(req->token);
spin_lock_bh(&bucket->lock);
+ if (hlist_nulls_unhashed(&req->token_node))
+ goto unlock;
- /* pedantic lookup check for the moved token */
pos = __token_lookup_req(bucket, req->token);
- if (!WARN_ON_ONCE(pos != req))
- hlist_nulls_del_init_rcu(&req->token_node);
+ if (pos != req)
+ goto unlock;
+
+ hlist_nulls_del_init_rcu(&req->token_node);
__sk_nulls_add_node_rcu((struct sock *)msk, &bucket->msk_chain);
+ ret = true;
+
+unlock:
spin_unlock_bh(&bucket->lock);
+ if (ret)
+ sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
+
+ return ret;
}
bool mptcp_token_exists(u32 token)
@@ -353,16 +402,21 @@ void mptcp_token_destroy_request(struct request_sock *req)
struct mptcp_subflow_request_sock *pos;
struct token_bucket *bucket;
- if (hlist_nulls_unhashed(&subflow_req->token_node))
+ if (hlist_nulls_unhashed_lockless(&subflow_req->token_node))
return;
bucket = token_bucket(subflow_req->token);
spin_lock_bh(&bucket->lock);
+ if (hlist_nulls_unhashed(&subflow_req->token_node))
+ goto unlock;
+
pos = __token_lookup_req(bucket, subflow_req->token);
- if (!WARN_ON_ONCE(pos != subflow_req)) {
+ if (pos == subflow_req) {
hlist_nulls_del_init_rcu(&pos->token_node);
bucket->chain_len--;
}
+
+unlock:
spin_unlock_bh(&bucket->lock);
}
diff --git a/net/mptcp/token_test.c b/net/mptcp/token_test.c
index 4fc39fa2e262d..be9acce8a5673 100644
--- a/net/mptcp/token_test.c
+++ b/net/mptcp/token_test.c
@@ -99,7 +99,7 @@ static void mptcp_token_test_accept(struct kunit *test)
KUNIT_ASSERT_EQ(test, 0,
mptcp_token_new_request((struct request_sock *)req));
msk->token = req->token;
- mptcp_token_accept(req, msk);
+ KUNIT_EXPECT_TRUE(test, mptcp_token_accept(req, msk));
KUNIT_EXPECT_PTR_EQ(test, msk, mptcp_token_get_sock(&init_net, msk->token));
/* this is now a no-op */
@@ -122,7 +122,7 @@ static void mptcp_token_test_destroyed(struct kunit *test)
KUNIT_ASSERT_EQ(test, 0,
mptcp_token_new_request((struct request_sock *)req));
msk->token = req->token;
- mptcp_token_accept(req, msk);
+ KUNIT_EXPECT_TRUE(test, mptcp_token_accept(req, msk));
/* simulate race on removal */
refcount_set(&sk->sk_refcnt, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 592/686] ALSA: ua101: Bound packet copies by the PCM buffer size
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (590 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 591/686] mptcp: fix MP_CAPABLE token migration when cloning reqsk Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 593/686] serial: sc16is7xx: fix data corruption due to unexpected xon/xoff Greg Kroah-Hartman
` (93 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sinan Turunc, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sinan Turunc <enscrpt@pm.me>
[ Upstream commit 493a77a9f20fca07ca5654f61c1b03bef035df25 ]
copy_capture_data() and copy_playback_data() wrap the ring buffer
position once and split the memcpy() in two at the buffer end, which is
only correct when one packet holds at most buffer_size frames. The
capture packet size is the device's (actual_length up to wMaxPacketSize,
divided by 3 * bNrChannels from its own descriptor), the playback packet
size is taken from the capture packets, and set_stream_hw() lets the
PCM client pick period_bytes_min 1, periods_min 2 and a period time of
1.5 packet intervals: 9 frames at 44.1 kHz high speed, an 18-frame
buffer. A device sending 672-byte mono 24-bit packets delivers 224
frames per packet.
After the first packet buffer_pos is 206 and stays beyond buffer_size.
On the next packet frames1 = buffer_size - buffer_pos wraps and memcpy()
runs away:
snd-ua101 2-1:1.0: invalid position: , pos = 206, buffer size = 18,
period size = 9
BUG: KASAN: slab-out-of-bounds in capture_urb_complete+0x9eb/0xcb0
Read of size 4294966732 at addr ffff88800d73e7e0 by task vhci_rx/81
and for playback:
BUG: KASAN: vmalloc-out-of-bounds in playback_work+0x789/0xac0
Read of size 4294966732 at addr ffffc9000002626a by task kworker/0:1H/80
Clamp the capture copy to buffer_size. On playback, copy at most one
buffer and fill the rest of the packet with silence, so the URB length,
the delay accounting and the data sent stay consistent. With that bound
the single wrap and both memcpy() halves stay inside the buffer. A
device whose packets do not fit the buffer never played correctly
anyway.
Reproduced on 7.3-rc7 with a USB/IP device presenting the UA-101
interface layout and a 672-byte isochronous endpoint.
Fixes: 63978ab3e3e9 ("sound: add Edirol UA-101 support")
Cc: stable@vger.kernel.org
Signed-off-by: Sinan Turunc <enscrpt@pm.me>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20261026223543.620-3-enscrpt@pm.me
[ sashal: changed urb->transfer_buffer to urb->urb.transfer_buffer to match the embedded URB representation ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/misc/ua101.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/sound/usb/misc/ua101.c b/sound/usb/misc/ua101.c
index 426171aa6dd28..c1d081231d7c8 100644
--- a/sound/usb/misc/ua101.c
+++ b/sound/usb/misc/ua101.c
@@ -282,13 +282,29 @@ static void playback_work(struct work_struct *work)
/* fill packet with data or silence */
urb->urb.iso_frame_desc[0].length =
frames * ua->playback.frame_bytes;
- if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states))
+ if (test_bit(ALSA_PLAYBACK_RUNNING, &ua->states)) {
+ /*
+ * The packet size comes from the capture stream,
+ * i.e. from the device, while the ring buffer can
+ * be as small as two tiny periods. The single wrap
+ * in copy_playback_data() is only valid for
+ * frames <= buffer_size, so copy at most one
+ * buffer and send silence for the rest.
+ */
+ unsigned int copy_frames = min(frames,
+ ua->playback.substream->runtime->buffer_size);
+
do_period_elapsed |= copy_playback_data(&ua->playback,
&urb->urb,
- frames);
- else
+ copy_frames);
+ memset(urb->urb.transfer_buffer +
+ copy_frames * ua->playback.frame_bytes, 0,
+ (frames - copy_frames) *
+ ua->playback.frame_bytes);
+ } else {
memset(urb->urb.transfer_buffer, 0,
urb->urb.iso_frame_desc[0].length);
+ }
/* and off you go ... */
err = usb_submit_urb(&urb->urb, GFP_ATOMIC);
@@ -317,6 +333,13 @@ static bool copy_capture_data(struct ua101_stream *stream, struct urb *urb,
runtime = stream->substream->runtime;
frame_bytes = stream->frame_bytes;
+ /*
+ * A packet can carry up to max_packet_bytes, the device's
+ * wMaxPacketSize, which may exceed the whole ring buffer; keep what
+ * fits so the single wrap below stays valid.
+ */
+ if (unlikely(frames > runtime->buffer_size))
+ frames = runtime->buffer_size;
dest = runtime->dma_area + stream->buffer_pos * frame_bytes;
if (stream->buffer_pos + frames <= runtime->buffer_size) {
memcpy(dest, urb->transfer_buffer, frames * frame_bytes);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 593/686] serial: sc16is7xx: fix data corruption due to unexpected xon/xoff
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (591 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 592/686] ALSA: ua101: Bound packet copies by the PCM buffer size Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 594/686] media: iris: Fix power-off ordering to disable power domain after clocks Greg Kroah-Hartman
` (92 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Martin Fuzzey, stable, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Fuzzey <martin.fuzzey@flowbird.group>
[ Upstream commit 8bb50e95c0abd44607bc60a43032c1dbf7470d5a ]
The hardware supports automatically sending XON/OFF based on the
FIFO status and that is already implemented by the driver.
However that capability was not announced with the UPF_SOFT_FLOW bit.
When the port is opened with the default of XON enabled the driver
configures that in the hardware.
If userspace does not want XON/OFF (which is normally the case) it will
use TCSETS to disactivate it. However the serial core optimises this
to only notify the driver if someting imporant has changed, and for
XON/XOFF thit is only if the driver declares UPF_SOFT_FLOW.
So we end up with unwanted XON/XOFF in the data stream.
The problem only occurs if nothing else needed to be set by termios,
ie if the user space requested values are the same as the default values,
except for XON/XOFF.
Since the default speed is 9600 this means that the problem only occurs
when requesting 9600, otherwise the call to the driver will be made to
change the speed, and that will also clear the XON/XOFF.
As 9600 is quite rare these days that probably explains why this hasn't
already been seen.
It also only occurs on the first port open after boot since the subsequent
opens will use the "logical state" set by TCSETS but not communicated to
the driver the first time.
Signed-off-by: Martin Fuzzey <martin.fuzzey@flowbird.group>
Fixes: dfeae619d781 ("serial: sc16is7xx")
Cc: stable@kernel.org
Link: https://patch.msgid.link/20261001100534.1225894-1-martin.fuzzey@flowbird.group
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
[ sashal: applied the flag change in sc16is7xx_probe() instead of sc16is7xx_setup_channel() to match the existing initialization layout ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/tty/serial/sc16is7xx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
index b5e301741b844..870b27973a7b1 100644
--- a/drivers/tty/serial/sc16is7xx.c
+++ b/drivers/tty/serial/sc16is7xx.c
@@ -1650,7 +1650,7 @@ int sc16is7xx_probe(struct device *dev, const struct sc16is7xx_devtype *devtype,
s->p[i].port.irq = irq;
s->p[i].port.type = PORT_SC16IS7XX;
s->p[i].port.fifosize = SC16IS7XX_FIFO_SIZE;
- s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY;
+ s->p[i].port.flags = UPF_FIXED_TYPE | UPF_LOW_LATENCY | UPF_SOFT_FLOW;
s->p[i].port.iobase = i;
/*
* Use all ones as membase to make sure uart_configure_port() in
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 594/686] media: iris: Fix power-off ordering to disable power domain after clocks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (592 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 593/686] serial: sc16is7xx: fix data corruption due to unexpected xon/xoff Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 595/686] ASoC: qcom: q6apm-dai: wrap the position of a full ring to 0 Greg Kroah-Hartman
` (91 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bryan ODonoghue, Vishnu Reddy,
Bryan ODonoghue, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
[ Upstream commit 9cfae7726a9a9f526e8905dbddde355be2674e3d ]
In iris_vpu_power_off_hw(), iris_disable_power_domains() was called
before the associated clocks (IRIS_BSE_HW_CLK, IRIS_HW_AHB_CLK,
IRIS_HW_CLK) were disabled and unprepared. This reverses the correct
power-down sequence: with the power domain already removed, the
subsequent clk_disable_unprepare() calls end up operating on
clock-controller hardware that is no longer powered, which can hang
or behave unpredictably.
Reorder the calls so iris_disable_power_domains() runs after all
three clocks are disabled, ensuring clocks are always turned off
while their power domain is still active, and mirroring the reverse
of the power-on sequence.
Fixes: bb8a95aa038e ("media: iris: implement power management")
Cc: stable@vger.kernel.org
Reviewed-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Vishnu Reddy <busanna.reddy@oss.qualcomm.com>
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
[ sashal: Adjusted context to account for absent IRIS_HW_AHB_CLK and IRIS_BSE_HW_CLK clock-disable calls. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/platform/qcom/iris/iris_vpu_common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/media/platform/qcom/iris/iris_vpu_common.c b/drivers/media/platform/qcom/iris/iris_vpu_common.c
index 6839e293d9b50..a20565abef6a6 100644
--- a/drivers/media/platform/qcom/iris/iris_vpu_common.c
+++ b/drivers/media/platform/qcom/iris/iris_vpu_common.c
@@ -260,8 +260,8 @@ int iris_vpu_power_off_controller(struct iris_core *core)
void iris_vpu_power_off_hw(struct iris_core *core)
{
dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], false);
- iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
iris_disable_unprepare_clock(core, IRIS_HW_CLK);
+ iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]);
}
void iris_vpu_power_off(struct iris_core *core)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 595/686] ASoC: qcom: q6apm-dai: wrap the position of a full ring to 0
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (593 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 594/686] media: iris: Fix power-off ordering to disable power domain after clocks Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 596/686] iomap: use largest_zero_folio() in iomap_dio_zero() Greg Kroah-Hartman
` (90 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vladyslav Tymoshchuk,
Srinivas Kandagatla, Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladyslav Tymoshchuk <tvlad744@gmail.com>
[ Upstream commit 0ea3e0b196f9dcc17b40ac881a6efef06459975b ]
q6apm_dai_pointer() turns the number of period buffers the DSP has
returned in the current lap, 1..periods, into a position and reports
one frame less than that. Commit a93dad6f4e6a ("ASoC: q6apm-dai: make
use of q6apm_get_hw_pointer") added the "- 1" so that the end of the
ring is not reported as a position equal to the buffer size.
One frame short has a cost once the application stops feeding the
stream. The DSP returns the last queued buffer and the position stops
at appl_ptr - 1, so avail stays at buffer_size - 1, below the default
stop_threshold. The DSP sends nothing more as its queue is empty, so
no period interrupt comes either: ALSA never detects the underrun and
the stream stays RUNNING. A poll-driven application that missed its
last wakeup waits forever, and drain only ends on its timeout, with
-EIO. On capture, the last frame of each period is held back until
the next one.
Before that commit the position wrapped to 0 at the end of the ring.
Do that again. A full lap is the start of the ring, and
snd_pcm_update_hw_ptr0() accounts for the wrap: the position cannot
move by more than one lap between two updates, as each returned buffer
calls snd_pcm_period_elapsed() and the DSP holds at most periods
buffers.
Seen on a OnePlus Pad 3 (SM8750) with PipeWire in interrupt-driven
scheduling: after a stall the PCM sat at hw_ptr 78239, appl_ptr 78240
(avail 3839 of 3840) for two hours.
Fixes: a93dad6f4e6a ("ASoC: q6apm-dai: make use of q6apm_get_hw_pointer")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Vladyslav Tymoshchuk <tvlad744@gmail.com>
Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Tested-by: Srinivas Kandagatla <srinivas.kandagatla@oss.qualcomm.com>
Link: https://patch.msgid.link/20261014162703.10172-2-tvlad744@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
[ sashal: Adjusted context in q6apm_dai_pointer() because the push/pull-mode branch is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/qcom/qdsp6/q6apm-dai.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-dai.c
index 54c1a33f9f937..4ea2c9869d5a1 100644
--- a/sound/soc/qcom/qdsp6/q6apm-dai.c
+++ b/sound/soc/qcom/qdsp6/q6apm-dai.c
@@ -442,11 +442,15 @@ static snd_pcm_uframes_t q6apm_dai_pointer(struct snd_soc_component *component,
struct q6apm_dai_rtd *prtd = runtime->private_data;
snd_pcm_uframes_t ptr;
- ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) * runtime->period_size;
- if (ptr)
- return ptr - 1;
+ /*
+ * The hw pointer counts the period buffers the DSP has returned in
+ * this lap, 1..periods. A full lap is the start of the ring again:
+ * report 0 rather than one frame less, so that the position of a
+ * drained buffer reaches appl_ptr and ALSA sees the underrun.
+ */
+ ptr = q6apm_get_hw_pointer(prtd->graph, substream->stream) % runtime->periods;
- return 0;
+ return ptr * runtime->period_size;
}
static int q6apm_dai_hw_params(struct snd_soc_component *component,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 596/686] iomap: use largest_zero_folio() in iomap_dio_zero()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (594 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 595/686] ASoC: qcom: q6apm-dai: wrap the position of a full ring to 0 Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 597/686] iomap: dont lose a failed direct I/O bios error when zeroing the tail Greg Kroah-Hartman
` (89 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pankaj Raghav, Darrick J. Wong,
Christian Brauner, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pankaj Raghav <p.raghav@samsung.com>
[ Upstream commit 10436adf9df60ae73390754b47a4bdebf728529f ]
iomap_dio_zero() uses a custom allocated memory of zeroes for padding
zeroes. This was a temporary solution until there was a way to request a
zero folio that was greater than the PAGE_SIZE.
Use largest_zero_folio() function instead of using the custom allocated
memory of zeroes. There is no guarantee from largest_zero_folio()
function that it will always return a PMD sized folio. Adapt the code so
that it can also work if largest_zero_folio() returns a ZERO_PAGE.
Signed-off-by: Pankaj Raghav <p.raghav@samsung.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: a9fd24bcbe69 ("iomap: don't lose a failed direct I/O bio's error when zeroing the tail")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/iomap/direct-io.c | 38 +++++++++++++++-----------------------
1 file changed, 15 insertions(+), 23 deletions(-)
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index bb276321c9521..5a97614507530 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -24,13 +24,6 @@
#define IOMAP_DIO_WRITE (1U << 30)
#define IOMAP_DIO_DIRTY (1U << 31)
-/*
- * Used for sub block zeroing in iomap_dio_zero()
- */
-#define IOMAP_ZERO_PAGE_SIZE (SZ_64K)
-#define IOMAP_ZERO_PAGE_ORDER (get_order(IOMAP_ZERO_PAGE_SIZE))
-static struct page *zero_page;
-
struct iomap_dio {
struct kiocb *iocb;
const struct iomap_dio_ops *dops;
@@ -296,24 +289,35 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
{
struct inode *inode = file_inode(dio->iocb->ki_filp);
struct bio *bio;
+ struct folio *zero_folio = largest_zero_folio();
+ int nr_vecs = max(1, i_blocksize(inode) / folio_size(zero_folio));
if (!len)
return 0;
+
/*
- * Max block size supported is 64k
+ * This limit shall never be reached as most filesystems have a
+ * maximum blocksize of 64k.
*/
- if (WARN_ON_ONCE(len > IOMAP_ZERO_PAGE_SIZE))
+ if (WARN_ON_ONCE(nr_vecs > BIO_MAX_VECS))
return -EINVAL;
- bio = iomap_dio_alloc_bio(iter, dio, 1, REQ_OP_WRITE | REQ_SYNC | REQ_IDLE);
+ bio = iomap_dio_alloc_bio(iter, dio, nr_vecs,
+ REQ_OP_WRITE | REQ_SYNC | REQ_IDLE);
fscrypt_set_bio_crypt_ctx(bio, inode, pos >> inode->i_blkbits,
GFP_KERNEL);
bio->bi_iter.bi_sector = iomap_sector(&iter->iomap, pos);
bio->bi_private = dio;
bio->bi_end_io = iomap_dio_bio_end_io;
- __bio_add_page(bio, zero_page, len, 0);
+ while (len > 0) {
+ unsigned int io_len = min(len, folio_size(zero_folio));
+
+ bio_add_folio_nofail(bio, zero_folio, io_len, 0);
+ len -= io_len;
+ }
iomap_dio_submit_bio(iter, dio, bio, pos);
+
return 0;
}
@@ -841,15 +845,3 @@ iomap_dio_rw(struct kiocb *iocb, struct iov_iter *iter,
return iomap_dio_complete(dio);
}
EXPORT_SYMBOL_GPL(iomap_dio_rw);
-
-static int __init iomap_dio_init(void)
-{
- zero_page = alloc_pages(GFP_KERNEL | __GFP_ZERO,
- IOMAP_ZERO_PAGE_ORDER);
-
- if (!zero_page)
- return -ENOMEM;
-
- return 0;
-}
-fs_initcall(iomap_dio_init);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 597/686] iomap: dont lose a failed direct I/O bios error when zeroing the tail
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (595 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 596/686] iomap: use largest_zero_folio() in iomap_dio_zero() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 598/686] exfat: advance valid_size to EOF for append writes Greg Kroah-Hartman
` (88 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Pankaj Raghav,
Andrea Parri, Christoph Hellwig, Christian Brauner (Amutable),
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Parri <parri.andrea@gmail.com>
[ Upstream commit a9fd24bcbe690ed4a5b8ea6a7516fa297fae9360 ]
iomap_dio_bio_iter() falls through to the sub-block tail zeroing when
the data bio submission fails, so that the rest of the block is still
zeroed and stale data is not exposed. The zeroing result was assigned
to ret, which overwrote the submission error with the successful
zeroing result (zero) and the failed write was reported as success.
iomap_dio_zero() can only return an error from a can't-happen
WARN_ON_ONCE() (nr_vecs exceeding BIO_MAX_VECS, which the existing
comment there says "shall never be reached" for any in-tree
filesystem), so it isn't a real runtime failure worth reporting to
userspace, let alone one worth losing the actual submission error for.
Make iomap_dio_zero() return void and drop the error handling at both
call sites instead of threading the result through a separate
variable.
Fixes: 10553a91652d ("iomap: fix iomap_dio_zero() for fs bs > system page size")
Cc: stable@vger.kernel.org # v6.12
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Pankaj Raghav <p.raghav@samsung.com>
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Link: https://patch.msgid.link/0cbce1012f5333690be36a9adafb3e190fe2ca77.1790342457.git.parri.andrea@gmail.com
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/iomap/direct-io.c | 16 +++++-----------
1 file changed, 5 insertions(+), 11 deletions(-)
diff --git a/fs/iomap/direct-io.c b/fs/iomap/direct-io.c
index 5a97614507530..4301145674259 100644
--- a/fs/iomap/direct-io.c
+++ b/fs/iomap/direct-io.c
@@ -284,7 +284,7 @@ u32 iomap_finish_ioend_direct(struct iomap_ioend *ioend)
return vec_count;
}
-static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
+static void iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
loff_t pos, unsigned len)
{
struct inode *inode = file_inode(dio->iocb->ki_filp);
@@ -293,14 +293,14 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
int nr_vecs = max(1, i_blocksize(inode) / folio_size(zero_folio));
if (!len)
- return 0;
+ return;
/*
* This limit shall never be reached as most filesystems have a
* maximum blocksize of 64k.
*/
if (WARN_ON_ONCE(nr_vecs > BIO_MAX_VECS))
- return -EINVAL;
+ return;
bio = iomap_dio_alloc_bio(iter, dio, nr_vecs,
REQ_OP_WRITE | REQ_SYNC | REQ_IDLE);
@@ -317,8 +317,6 @@ static int iomap_dio_zero(const struct iomap_iter *iter, struct iomap_dio *dio,
len -= io_len;
}
iomap_dio_submit_bio(iter, dio, bio, pos);
-
- return 0;
}
/*
@@ -424,10 +422,7 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
if (need_zeroout) {
/* zero out from the start of the block to the write offset */
pad = pos & (fs_block_size - 1);
-
- ret = iomap_dio_zero(iter, dio, pos - pad, pad);
- if (ret)
- goto out;
+ iomap_dio_zero(iter, dio, pos - pad, pad);
}
nr_pages = bio_iov_vecs_to_alloc(dio->submit.iter, BIO_MAX_VECS);
@@ -509,8 +504,7 @@ static int iomap_dio_bio_iter(struct iomap_iter *iter, struct iomap_dio *dio)
/* zero out from the end of the write to the end of the block */
pad = pos & (fs_block_size - 1);
if (pad)
- ret = iomap_dio_zero(iter, dio, pos,
- fs_block_size - pad);
+ iomap_dio_zero(iter, dio, pos, fs_block_size - pad);
}
out:
/* Undo iter limitation to current extent */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 598/686] exfat: advance valid_size to EOF for append writes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (596 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 597/686] iomap: dont lose a failed direct I/O bios error when zeroing the tail Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 599/686] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack Greg Kroah-Hartman
` (87 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chi Zhiling, Namjae Jeon,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chi Zhiling <chizhiling@kylinos.cn>
[ Upstream commit b70ab407503706289163dd59f1ac3e942bacc37d ]
For an append write, the write position is recalculated by
generic_write_checks(). Therefore, the write position must be obtained
after generic_write_checks() returns.
Using the original write position to advance valid_size may cause the
valid_size update to be skipped, potentially exposing stale data.
Also move the truncate_pagecache() check below the recalculated
position, so that pos is never read before it is assigned.
Fixes: 11a347fb6cef ("exfat: change to get file size from DataLength")
Cc: stable@vger.kernel.org
Signed-off-by: Chi Zhiling <chizhiling@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
[ sashal: Moved the pos assignment immediately after generic_write_checks() so the existing direct-I/O alignment check reads an initialized value. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/exfat/file.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/fs/exfat/file.c b/fs/exfat/file.c
index 536c8078f0c19..64569d8ba8d73 100644
--- a/fs/exfat/file.c
+++ b/fs/exfat/file.c
@@ -633,23 +633,18 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file);
struct exfat_inode_info *ei = EXFAT_I(inode);
- loff_t pos = iocb->ki_pos;
- loff_t valid_size;
+ loff_t pos, valid_size;
if (unlikely(exfat_forced_shutdown(inode->i_sb)))
return -EIO;
inode_lock(inode);
- if (pos > i_size_read(inode))
- truncate_pagecache(inode, i_size_read(inode));
-
- valid_size = ei->valid_size;
-
ret = generic_write_checks(iocb, iter);
if (ret <= 0)
goto unlock;
+ pos = iocb->ki_pos;
if (iocb->ki_flags & IOCB_DIRECT) {
unsigned long align = pos | iov_iter_alignment(iter);
@@ -660,6 +655,10 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
}
}
+ if (pos > i_size_read(inode))
+ truncate_pagecache(inode, i_size_read(inode));
+
+ valid_size = ei->valid_size;
if (pos > valid_size) {
ret = exfat_extend_valid_size(inode, pos);
if (ret < 0 && ret != -ENOSPC) {
@@ -669,6 +668,8 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
}
if (ret < 0)
goto unlock;
+
+ pos = valid_size;
}
ret = __generic_file_write_iter(iocb, iter);
@@ -677,9 +678,6 @@ static ssize_t exfat_file_write_iter(struct kiocb *iocb, struct iov_iter *iter)
inode_unlock(inode);
- if (pos > valid_size)
- pos = valid_size;
-
if (iocb->ki_pos > pos) {
ssize_t err = generic_write_sync(iocb, iocb->ki_pos - pos);
if (err < 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 599/686] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (597 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 598/686] exfat: advance valid_size to EOF for append writes Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 600/686] block: introduce bio_in_atomic() Greg Kroah-Hartman
` (86 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Kaixuan Li, Chao Yu,
Jaegeuk Kim, Sasha Levin
6.18-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 the two 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 69d36e1a301bf..93e6575706add 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -4128,6 +4128,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);
@@ -4259,6 +4260,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] 687+ messages in thread
* [PATCH 6.18 600/686] block: introduce bio_in_atomic()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (598 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 599/686] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 601/686] f2fs: fix to use bio_in_atomic() in f2fs_read_end_io() Greg Kroah-Hartman
` (85 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Tal Zussman,
Jan Kara, Christoph Hellwig, Jens Axboe, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tal Zussman <tz2294@columbia.edu>
[ Upstream commit 8ed0831b5263e1aa48d99063795a1f20e4e69b50 ]
Move the atomic context detection logic from erofs's z_erofs_in_atomic()
into the block layer as bio_in_atomic(). This helper returns true when
the current context is unsafe for sleeping bio completion handlers (e.g.,
hard/soft IRQ, preempt-disabled).
The logic was originally added to erofs in commit c99fab6e80b7 ("erofs:
fix atomic context detection when !CONFIG_DEBUG_LOCK_ALLOC"). A
subsequent patch will use it in the block layer's bio completion
infrastructure, so move it to include/linux/bio.h where both subsystems
can share it.
Convert erofs to call the new bio_in_atomic() directly.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tal Zussman <tz2294@columbia.edu>
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260730-blk-dontcache-v7-1-3e8e6850068d@columbia.edu
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Stable-dep-of: a605d5d71a6d ("f2fs: fix to use bio_in_atomic() in f2fs_read_end_io()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/zdata.c | 11 +----------
include/linux/bio.h | 15 +++++++++++++++
2 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index 0af259e22026f..ab4b222aae899 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -1414,15 +1414,6 @@ static void z_erofs_decompressqueue_kthread_work(struct kthread_work *work)
}
#endif
-/* Use (kthread_)work in atomic contexts to minimize scheduling overhead */
-static inline bool z_erofs_in_atomic(void)
-{
- if (IS_ENABLED(CONFIG_PREEMPTION) && rcu_preempt_depth())
- return true;
- if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
- return true;
- return !preemptible();
-}
static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
int bios)
@@ -1439,7 +1430,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
if (atomic_add_return(bios, &io->pending_bios))
return;
- if (z_erofs_in_atomic()) {
+ if (bio_in_atomic()) {
/* See `sync_decompress` in sysfs-fs-erofs for more details */
if (sbi->sync_decompress == EROFS_SYNC_DECOMPRESS_AUTO)
sbi->sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_ON;
diff --git a/include/linux/bio.h b/include/linux/bio.h
index fb747b053b98c..a5763f11fb137 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -376,6 +376,21 @@ static inline struct bio *bio_alloc(struct block_device *bdev,
void submit_bio(struct bio *bio);
+/**
+ * bio_in_atomic - check if the current context is unsafe for bio completion
+ *
+ * Return: %true in atomic contexts (e.g. hard/soft IRQ, preempt-disabled);
+ * %false when a bio can be safely completed in the current context.
+ */
+static inline bool bio_in_atomic(void)
+{
+ if (IS_ENABLED(CONFIG_PREEMPTION) && rcu_preempt_depth())
+ return true;
+ if (!IS_ENABLED(CONFIG_PREEMPT_COUNT))
+ return true;
+ return !preemptible();
+}
+
extern void bio_endio(struct bio *);
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 601/686] f2fs: fix to use bio_in_atomic() in f2fs_read_end_io()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (599 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 600/686] block: introduce bio_in_atomic() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 602/686] scsi: ufs: core: Add a helper for clearing hba->outstanding_reqs Greg Kroah-Hartman
` (84 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit a605d5d71a6d280c43c7ede9778dda63fb5c3f22 ]
f2fs_read_end_io() uses "in_task() && !irqs_disabled()" to decide
whether it is safe to sleep, the result is passed down as @in_task to:
- f2fs_put_dic() -> f2fs_free_dic() -> f2fs_release_decomp_mem()
-> vm_unmap_ram(), which may sleep.
- f2fs_end_read_compressed_page() -> f2fs_cache_compressed_page()
-> f2fs_grab_cache() -> f2fs_lock_cache(), which may sleep in
wait_on_bit_lock().
However, the check still treats below task contexts as sleepable:
- with spinlock held via spin_lock(), i.e. preempt count != 0 while
irqs are enabled.
- with BH disabled via local_bh_disable().
- inside an RCU read lock on kernels with CONFIG_PREEMPTION.
- with any spinlock held on kernels without CONFIG_PREEMPT_COUNT.
So the "sleeping function called from invalid context" issue fixed by
commit 08a7efc5b02a ("f2fs: vm_unmap_ram() may be called from an
invalid context") can still be triggered.
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:
old: intask = in_task() && !irqs_disabled()
new: intask = !bio_in_atomic()
Context | old intask | new intask
-------------------------------------+----------------+----------------
Hard IRQ / softirq | false | false
IRQs disabled | false | false
spin_lock() held, IRQs enabled | true (wrong) | false
BH disabled by local_bh_disable() | true (wrong) | false
RCU read lock (CONFIG_PREEMPTION) | true (wrong) | false
Spinlock held, w/o PREEMPT_COUNT | true (wrong) | false
Note that on kernels without CONFIG_PREEMPT_COUNT, bio_in_atomic()
always returns true, so dic freeing will always be offloaded to sbi->wq,
and compressed pages will not be cached in f2fs_read_end_io(); this is
the price of correctness, since there is no way to tell whether the
current context can sleep.
Cc: stable@kernel.org
Fixes: 08a7efc5b02a ("f2fs: vm_unmap_ram() may be called from an invalid context")
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/f2fs/data.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index ab58d3d2235bb..868af16755109 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -288,7 +288,7 @@ static void f2fs_read_end_io(struct bio *bio)
{
struct f2fs_sb_info *sbi = F2FS_F_SB(bio_first_folio_all(bio));
struct bio_post_read_ctx *ctx;
- bool intask = in_task() && !irqs_disabled();
+ bool intask = !bio_in_atomic();
iostat_update_and_unbind_ctx(bio);
ctx = bio->bi_private;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 602/686] scsi: ufs: core: Add a helper for clearing hba->outstanding_reqs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (600 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 601/686] f2fs: fix to use bio_in_atomic() in f2fs_read_end_io() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 603/686] wifi: mt76: mt7921: assert sniffer on chanctx change Greg Kroah-Hartman
` (83 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bart Van Assche, Bean Huo,
Peter Wang, Stanley Jhu, Martin K. Petersen (Oracle), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanley Jhu <stanleyjhu@google.com>
[ Upstream commit 22d14117ec1845a81acb3a5c4be325f7e8332f70 ]
ufshcd_poll() and ufshcd_abort() each have their own copy of the code that
clears bits in hba->outstanding_reqs under hba->outstanding_lock.
Move that code into ufshcd_clear_outstanding_reqs() and its locked variant
__ufshcd_clear_outstanding_reqs(), and use them in both functions. No
functional change.
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/3779e125-9acc-42c8-9489-51b9e3c6716d@acm.org
Suggested-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Bean Huo <beanhuo@micron.com>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20261022034443.3034432-3-stanleyjhu@google.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ sashal: Retained the lrbp argument instead of cmd in ufshcd_release_scsi_cmd() to match the existing API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/core/ufshcd.c | 48 +++++++++++++++++++++++++++++----------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 97f86b6905b56..d595072f7c0a4 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -5694,6 +5694,37 @@ static void ufshcd_clear_polled(struct ufs_hba *hba,
}
}
+/*
+ * Return a bitmask of the transfer requests cleared from
+ * @hba->outstanding_reqs.
+ */
+static unsigned long __ufshcd_clear_outstanding_reqs(struct ufs_hba *hba,
+ unsigned long mask,
+ bool from_irq)
+ __must_hold(&hba->outstanding_lock)
+{
+ unsigned long completed_reqs = mask & hba->outstanding_reqs;
+
+ if (from_irq) {
+ /* Do not complete polled requests from interrupt context. */
+ ufshcd_clear_polled(hba, &completed_reqs);
+ }
+ hba->outstanding_reqs &= ~completed_reqs;
+
+ return completed_reqs;
+}
+
+/*
+ * Return a bitmask of the transfer requests cleared from
+ * @hba->outstanding_reqs.
+ */
+static unsigned long ufshcd_clear_outstanding_reqs(struct ufs_hba *hba,
+ unsigned long mask)
+{
+ guard(spinlock_irqsave)(&hba->outstanding_lock);
+ return __ufshcd_clear_outstanding_reqs(hba, mask, false);
+}
+
/*
* Return: > 0 if one or more commands have been completed or 0 if no
* requests have been completed.
@@ -5704,6 +5735,7 @@ static int ufshcd_poll(struct Scsi_Host *shost, unsigned int queue_num)
unsigned long completed_reqs, flags;
u32 tr_doorbell;
struct ufs_hw_queue *hwq;
+ bool from_irq;
if (hba->mcq_enabled) {
hwq = &hba->uhq[queue_num];
@@ -5713,12 +5745,9 @@ static int ufshcd_poll(struct Scsi_Host *shost, unsigned int queue_num)
spin_lock_irqsave(&hba->outstanding_lock, flags);
tr_doorbell = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
- completed_reqs = ~tr_doorbell & hba->outstanding_reqs;
- if (queue_num == UFSHCD_POLL_FROM_INTERRUPT_CONTEXT) {
- /* Do not complete polled requests from interrupt context. */
- ufshcd_clear_polled(hba, &completed_reqs);
- }
- hba->outstanding_reqs &= ~completed_reqs;
+ from_irq = queue_num == UFSHCD_POLL_FROM_INTERRUPT_CONTEXT;
+ completed_reqs = __ufshcd_clear_outstanding_reqs(hba, ~tr_doorbell,
+ from_irq);
spin_unlock_irqrestore(&hba->outstanding_lock, flags);
if (completed_reqs)
@@ -7739,7 +7768,6 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
struct ufshcd_lrb *lrbp = &hba->lrb[tag];
unsigned long flags;
int err = FAILED;
- bool outstanding;
u32 reg;
ufshcd_hold(hba);
@@ -7820,11 +7848,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
* Clear the corresponding bit from outstanding_reqs since the command
* has been aborted successfully.
*/
- spin_lock_irqsave(&hba->outstanding_lock, flags);
- outstanding = __test_and_clear_bit(tag, &hba->outstanding_reqs);
- spin_unlock_irqrestore(&hba->outstanding_lock, flags);
-
- if (outstanding)
+ if (ufshcd_clear_outstanding_reqs(hba, BIT(tag)))
ufshcd_release_scsi_cmd(hba, lrbp);
err = SUCCESS;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 603/686] wifi: mt76: mt7921: assert sniffer on chanctx change
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (601 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 602/686] scsi: ufs: core: Add a helper for clearing hba->outstanding_reqs Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 604/686] wifi: mt76: move the channel survey when the channel changes Greg Kroah-Hartman
` (82 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nick Morrow, Devin Wittmayer,
Felix Fietkau, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devin Wittmayer <lucid_duck@justthetip.ca>
[ Upstream commit a7d35545c2ce11849de4b4397abaf664d79acd28 ]
mt7921_change_chanctx() configures the channel for monitor vifs but
does not re-assert sniffer mode. mt7925_change_chanctx() does. Match
mt7925 by adding the missing mt7921_mcu_set_sniffer(true) call,
completing the architectural pattern from commit 914189af23b8 ("wifi:
mt76: mt7921: fix channel switch fail in monitor mode").
The user-visible regression this asymmetry produced on v6.17 and v6.18
was addressed by commit cdb2941a516c ("Revert "wifi: mt76: mt792x:
improve monitor interface handling"") in v6.19 and backported to the
6.17.y and 6.18.y stable trees. This patch is defense in depth in
case the NO_VIRTUAL_MONITOR change is reintroduced in a future series.
Tested-by: Nick Morrow <morrownr@gmail.com>
Tested-on: RasPi4B, RasPiOS 64 bit, Alfa AWUS036AXML mt7921u
Tested-on: RasPi4B, RasPiOS 64 bit, Netgear A9000 mt7925u
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20260515183921.23484-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Stable-dep-of: 68342a7bd7e5 ("wifi: mt76: move the channel survey when the channel changes")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7921/main.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 35ece0f617337..1e9070a010345 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -1405,10 +1405,12 @@ mt7921_change_chanctx(struct ieee80211_hw *hw,
vif = container_of((void *)mvif, struct ieee80211_vif, drv_priv);
mt792x_mutex_acquire(phy->dev);
- if (vif->type == NL80211_IFTYPE_MONITOR)
+ if (vif->type == NL80211_IFTYPE_MONITOR) {
+ mt7921_mcu_set_sniffer(mvif->phy->dev, vif, true);
mt7921_mcu_config_sniffer(mvif, ctx);
- else
+ } else {
mt76_connac_mcu_uni_set_chctx(mvif->phy->mt76, &mvif->bss_conf.mt76, ctx);
+ }
mt792x_mutex_release(phy->dev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 604/686] wifi: mt76: move the channel survey when the channel changes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (602 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 603/686] wifi: mt76: mt7921: assert sniffer on chanctx change Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 605/686] ASoC: amd: acp: add DMI override for ACP70 flag Greg Kroah-Hartman
` (81 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chris, Devin Wittmayer,
Felix Fietkau, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devin Wittmayer <lucid_duck@justthetip.ca>
[ Upstream commit 68342a7bd7e5e273e2969e3c0f4c62ee3d006ce8 ]
mt7921 and mt7925 report every survey counter against one channel and
never mark the one in use. With firmware channel management, both use
channel contexts and never call __mt76_set_channel(), so
phy->chan_state, phy->chandef and phy->main_chandef keep the first
channel of the band.
Update them when a context is assigned or changed, after booking the
time spent on the old channel. This also makes the legacy rate lookup
in mt76_connac2_mac_fill_txs() and mt7925_mac_add_txs_skb() use the
band of the current channel.
With two channel contexts (multi-channel or MLO), the survey follows
the context that was assigned or changed last, since the driver reads
the band 0 counters only.
Tested on MT7922 over PCIe, MT7921AU and MT7925 over USB.
Fixes: 41ac53c899bd ("wifi: mt76: mt7921: introduce chanctx support")
Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Cc: stable@vger.kernel.org
Reported-by: Chris <hoopyfrood42@gmail.com>
Closes: https://lore.kernel.org/linux-wireless/CAHaeJsT8O8Nhq351hFp3NAL8e0iU85N-LBdYZ9nYHFHVy7t_hQ@mail.gmail.com/
Signed-off-by: Devin Wittmayer <lucid_duck@justthetip.ca>
Link: https://patch.msgid.link/20261001003501.2425492-1-lucid_duck@justthetip.ca
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mac80211.c | 14 ++++++++++++++
drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++
drivers/net/wireless/mediatek/mt76/mt7921/main.c | 1 +
drivers/net/wireless/mediatek/mt76/mt7925/main.c | 2 ++
drivers/net/wireless/mediatek/mt76/mt792x_core.c | 1 +
5 files changed, 20 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mac80211.c b/drivers/net/wireless/mediatek/mt76/mac80211.c
index 2d8cd627ef4c6..53c9cd0cfadb7 100644
--- a/drivers/net/wireless/mediatek/mt76/mac80211.c
+++ b/drivers/net/wireless/mediatek/mt76/mac80211.c
@@ -1034,6 +1034,20 @@ void mt76_update_survey(struct mt76_phy *phy)
}
EXPORT_SYMBOL_GPL(mt76_update_survey);
+void mt76_phy_chandef_set(struct mt76_phy *phy,
+ struct cfg80211_chan_def *chandef)
+{
+ if (!chandef->chan)
+ return;
+
+ mt76_update_survey(phy);
+
+ phy->chandef = *chandef;
+ phy->main_chandef = *chandef;
+ phy->chan_state = mt76_channel_state(phy, chandef->chan);
+}
+EXPORT_SYMBOL_GPL(mt76_phy_chandef_set);
+
int __mt76_set_channel(struct mt76_phy *phy, struct cfg80211_chan_def *chandef,
bool offchannel)
{
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 6ca5f3b2c6ba8..9542c4fbdee23 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -1531,6 +1531,8 @@ void mt76_sta_ps_transition(struct mt76_dev *dev, struct mt76_wcid *wcid,
bool mt76_has_tx_pending(struct mt76_phy *phy);
int mt76_update_channel(struct mt76_phy *phy);
void mt76_update_survey(struct mt76_phy *phy);
+void mt76_phy_chandef_set(struct mt76_phy *phy,
+ struct cfg80211_chan_def *chandef);
void mt76_update_survey_active_time(struct mt76_phy *phy, ktime_t time);
int mt76_get_survey(struct ieee80211_hw *hw, int idx,
struct survey_info *survey);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 1e9070a010345..26595de275bff 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -1411,6 +1411,7 @@ mt7921_change_chanctx(struct ieee80211_hw *hw,
} else {
mt76_connac_mcu_uni_set_chctx(mvif->phy->mt76, &mvif->bss_conf.mt76, ctx);
}
+ mt76_phy_chandef_set(mvif->phy->mt76, &ctx->def);
mt792x_mutex_release(phy->dev);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7925/main.c b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
index 7c63c7f5caf3e..70068c9eb8ea8 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7925/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7925/main.c
@@ -1864,6 +1864,7 @@ mt7925_change_chanctx(struct ieee80211_hw *hw,
link_conf, ctx);
}
}
+ mt76_phy_chandef_set(mvif->phy->mt76, &ctx->def);
mt792x_mutex_release(phy->dev);
}
@@ -2176,6 +2177,7 @@ static int mt7925_assign_vif_chanctx(struct ieee80211_hw *hw,
mconf->mt76.ctx = ctx;
mctx->bss_conf = mconf;
+ mt76_phy_chandef_set(mvif->phy->mt76, &ctx->def);
mutex_unlock(&dev->mt76.mutex);
return 0;
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
index d00807075c71f..62c40450472af 100644
--- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c
+++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c
@@ -342,6 +342,7 @@ int mt792x_assign_vif_chanctx(struct ieee80211_hw *hw,
mutex_lock(&dev->mt76.mutex);
mvif->bss_conf.mt76.ctx = ctx;
mctx->bss_conf = &mvif->bss_conf;
+ mt76_phy_chandef_set(&dev->mphy, &ctx->def);
mutex_unlock(&dev->mt76.mutex);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 605/686] ASoC: amd: acp: add DMI override for ACP70 flag
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (603 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 604/686] wifi: mt76: move the channel survey when the channel changes Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 606/686] ASoC: amd: acp: Add DMI quirk for ASUS Zenbook S16 UM5606GA Greg Kroah-Hartman
` (80 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hasun Park, Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hasun Park <hasunpark@gmail.com>
[ Upstream commit d0426510a9e1fabf074e274ceff26ffc6500980a ]
Some ASUS ProArt PX13 systems expose ACP ACPI config flags that can
select a non-working fallback path.
Add a DMI override in snd_amd_acp_find_config() for ACP70+ boards and
return 0 so ACP ACPI flag-based selection is skipped on this platform.
This keeps machine driver selection on the intended SoundWire path.
Signed-off-by: Hasun Park <hasunpark@gmail.com>
Link: https://patch.msgid.link/20260308151654.29059-2-hasunpark@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 38cb2ef26b64 ("ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/acp-config.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c
index 653e8ce946082..8d7b968c4402c 100644
--- a/sound/soc/amd/acp-config.c
+++ b/sound/soc/amd/acp-config.c
@@ -23,6 +23,16 @@
static int acp_quirk_data;
+static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
+ {
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "HN7306EA"),
+ },
+ },
+ {}
+};
+
static const struct config_entry config_table[] = {
{
.flags = FLAG_AMD_SOF,
@@ -200,8 +210,11 @@ int snd_amd_acp_find_config(struct pci_dev *pci)
*/
if (!pci->revision)
return 0;
- else if (pci->revision >= ACP_7_0_REV)
+ else if (pci->revision >= ACP_7_0_REV) {
+ if (dmi_check_system(acp70_acpi_flag_override_table))
+ return 0;
return snd_amd_acp_acpi_find_config(pci);
+ }
for (i = 0; i < ARRAY_SIZE(config_table); i++, table++) {
if (table->device != device)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 606/686] ASoC: amd: acp: Add DMI quirk for ASUS Zenbook S16 UM5606GA
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (604 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 605/686] ASoC: amd: acp: add DMI override for ACP70 flag Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 607/686] ASoC: amd: acp: Add DMI quirk for Lenovo Yoga Pro 7 15ASH11 Greg Kroah-Hartman
` (79 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jasper Smet, Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jasper Smet <josbeir@gmail.com>
[ Upstream commit 6e4bfd9da8851f562f04503d8e43221957f96eeb ]
The ASUS Zenbook S16 (UM5606GA) with AMD Ryzen AI 9 465 (Strix Point,
ACP 7.0) has a BIOS that incorrectly sets the ACPI property
'acp-audio-config-flag' to 0x10 (FLAG_AMD_LEGACY_ONLY_DMIC) for the ACP
device. This prevents snd_pci_ps from probing the SoundWire bus, resulting
in no internal audio (dummy output only).
The hardware uses a Cirrus Logic CS42L43 (headphone/jack) and four CS35L56
smart amplifiers (speakers), all on SoundWire link 1. The corresponding
machine table entry (acp70_cs42l43_l1u0_cs35l56x4_l1u0123) already exists
in amd-acp70-acpi-match.c and correctly describes this topology.
Add a DMI quirk to override the flag to 0, consistent with the existing
entry for the HN7306EA.
Signed-off-by: Jasper Smet <josbeir@gmail.com>
Link: https://patch.msgid.link/20260513052137.56703-1-josbeir@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 38cb2ef26b64 ("ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/acp-config.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c
index 8d7b968c4402c..cc3620db62bf1 100644
--- a/sound/soc/amd/acp-config.c
+++ b/sound/soc/amd/acp-config.c
@@ -30,6 +30,13 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "HN7306EA"),
},
},
+ {
+ /* ASUS Zenbook S16 UM5606GA (Strix Point, ACP 7.0) */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Zenbook S16 UM5606GA"),
+ },
+ },
{}
};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 607/686] ASoC: amd: acp: Add DMI quirk for Lenovo Yoga Pro 7 15ASH11
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (605 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 606/686] ASoC: amd: acp: Add DMI quirk for ASUS Zenbook S16 UM5606GA Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 608/686] ASoC: amd: acp-config: force SoundWire probe on HP OmniBook X Flip 16 Greg Kroah-Hartman
` (78 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jackie Dong, Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jackie Dong <xy-jackie@139.com>
[ Upstream commit fc12cf16df9af867e1455b011cdd9310474a612e ]
Lenovo Yoga Pro 7 15ASH11 with AMD RYZEN AI MAX+ 388 (Strix Halo, ACP
7.0) uses Realtek ALC287 series codec and no any DMIC connected by ACP.
All DMICs directly connet with ALC codec.
Without this quirk, Input Device of Gnome Sound settings shows Internal
Stereo Microphone and Digital Microphone by default. In fact, Digital
Microphone of ACP doesn't work due to no connecting with ALC287 codec,
the Internal Stereo Microphone as analog device based on snd_hda_intel
driver can work well.
Add a DMI quirk to override the flag to 0, consistent with the existing
entry for the HN7306EA.
Signed-off-by: Jackie Dong <xy-jackie@139.com>
Link: https://patch.msgid.link/20260527102005.58528-1-xy-jackie@139.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 38cb2ef26b64 ("ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/acp-config.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c
index cc3620db62bf1..a46b9a029cbb0 100644
--- a/sound/soc/amd/acp-config.c
+++ b/sound/soc/amd/acp-config.c
@@ -37,6 +37,13 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Zenbook S16 UM5606GA"),
},
},
+ {
+ /* Lenovo Yoga Pro 7 15ASH11 (Strix Halo, ACP 7.0) */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "83W5"),
+ },
+ },
{}
};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 608/686] ASoC: amd: acp-config: force SoundWire probe on HP OmniBook X Flip 16
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (606 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 607/686] ASoC: amd: acp: Add DMI quirk for Lenovo Yoga Pro 7 15ASH11 Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 609/686] ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265 Greg Kroah-Hartman
` (77 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sehat Mahde, Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sehat Mahde <hskmahde@gmail.com>
[ Upstream commit 4d6642d64cd00f276549ec2c0b0278aea2f8c1aa ]
The BIOS on the HP OmniBook X Flip 16-cc0xxx (board 8EA2) reports
acp-audio-config-flag = FLAG_AMD_LEGACY_ONLY_DMIC. This binds the
legacy ACP driver and registers a PDM-only card, so the SoundWire
links are never scanned and the two TAS2783 speaker amplifiers and
RT712-VB codec do not enumerate.
Add a DMI entry for board 8EA2 to the ACP70 ACPI flag override table
so the firmware-provided flag is overridden and snd_pci_ps probes
instead.
On the affected system, an otherwise identical upstream kernel
without this entry binds snd_acp_pci, enumerates no SoundWire slave
devices and exposes no internal speaker PCM. With the entry added,
snd_pci_ps binds, both TAS2783 amplifiers and the RT712-VB enumerate
over SoundWire, and the amd-soundwire card exposes the internal
speaker playback PCM.
Developed with AI assistance. ChatGPT helped analyze the ACP and
SoundWire behavior, structure the controlled A/B testing, and draft
the patch changelog. All hardware measurements, kernel builds,
reboots and playback tests were performed by the submitter. The
submitter has reviewed the change, understands it and takes
responsibility for it.
Assisted-by: ChatGPT:GPT-5.6 Sol
Signed-off-by: Sehat Mahde <hskmahde@gmail.com>
Link: https://patch.msgid.link/20260825224640.13662-1-hskmahde@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 38cb2ef26b64 ("ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/acp-config.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c
index a46b9a029cbb0..d73059f400d57 100644
--- a/sound/soc/amd/acp-config.c
+++ b/sound/soc/amd/acp-config.c
@@ -44,6 +44,13 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "83W5"),
},
},
+ {
+ /* HP OmniBook X Flip 16-cc0xxx */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "HP"),
+ DMI_MATCH(DMI_BOARD_NAME, "8EA2"),
+ },
+ },
{}
};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 609/686] ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (607 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 608/686] ASoC: amd: acp-config: force SoundWire probe on HP OmniBook X Flip 16 Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 610/686] perf evsel: Restrict incremental open error unwind Greg Kroah-Hartman
` (76 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Art O Cathain, Vijendar Mukunda,
Mark Brown, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Art O Cathain <art.home@gmail.com>
[ Upstream commit 38cb2ef26b6411277826da54c6bcf94523541058 ]
The BIOS on the Dell 14S DS14265 (ACP PCI revision 0x72) reports
acp-audio-config-flag = FLAG_AMD_LEGACY_ONLY_DMIC. As a result
snd_pci_ps returns early and the SoundWire links are never scanned,
while the legacy snd_acp_pci driver probes the device, finds no
matching machine driver ("No matching ASoC machine driver found") and
no internal sound card is created. The CS42L45 headset codec on link 0
and the two CS35L63 speaker amplifiers on link 1 never enumerate.
Add a DMI entry for the model to the ACP70 ACPI flag override table so
the firmware-provided flag is overridden and snd_pci_ps probes instead.
Match on the product name rather than the board name, as the same
symptom has been reported on several boards of this model (09PVND,
0M0J65, 0C7F12).
Tested on a DS14265 (board 09PVND, BIOS 1.5.3) with Debian's 7.2.6
kernel, with and without this entry. With it, snd_pci_ps binds, both
SoundWire links come up, the CS42L45 and both CS35L63 enumerate, the
existing CS42L45 + 2x CS35L63 machine entry matches, the amplifiers
load their firmware and calibration, and the amd-soundwire card plays
through both the internal speakers and the headphone jack. Also
build-tested on asoc-next with W=1.
Developed with AI assistance. Claude read the ACP driver source,
identified the BIOS flag as the cause and the override table as the
fix, wrote the DMI entry and the out-of-tree test module, and drafted
this changelog. All hardware testing was done by the submitter, who
has reviewed the change, understands it and takes responsibility for
it.
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Art O Cathain <art.home@gmail.com>
Reviewed-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://patch.msgid.link/20261016-dell-14s-acp-v1-1-89b40d95720c@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/acp-config.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/amd/acp-config.c b/sound/soc/amd/acp-config.c
index d73059f400d57..7ed461c1d5192 100644
--- a/sound/soc/amd/acp-config.c
+++ b/sound/soc/amd/acp-config.c
@@ -51,6 +51,13 @@ static const struct dmi_system_id acp70_acpi_flag_override_table[] = {
DMI_MATCH(DMI_BOARD_NAME, "8EA2"),
},
},
+ {
+ /* Dell 14S DS14265 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Dell 14S DS14265"),
+ },
+ },
{}
};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 610/686] perf evsel: Restrict incremental open error unwind
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (608 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 609/686] ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265 Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 611/686] perf evsel: Close the fds opened so far when disabling missing features Greg Kroah-Hartman
` (75 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ian Rogers, Hui Su, Namhyung Kim,
Arnaldo Carvalho de Melo, Sasha Levin
6.18-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")
[ sashal: used evlist__delete() in the new test because evlist__put() is unavailable ]
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 1e900ef92e378..5dcb747a6391c 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)
@@ -99,9 +107,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__delete(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__delete(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 e01103443b23f..4fa7cbc51047c 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2810,7 +2810,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 b24cdc3299447..7c1ac23e41324 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 f075098488bad..601fbf6ae4098 100644
--- a/tools/perf/util/tool_pmu.c
+++ b/tools/perf/util/tool_pmu.c
@@ -296,7 +296,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] 687+ messages in thread
* [PATCH 6.18 611/686] perf evsel: Close the fds opened so far when disabling missing features
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (609 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 610/686] perf evsel: Restrict incremental open error unwind Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 612/686] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs Greg Kroah-Hartman
` (74 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Ian Rogers,
Arnaldo Carvalho de Melo, Sasha Levin
6.18-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 4fa7cbc51047c..654e9bbd66f98 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -2642,6 +2642,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)
@@ -2792,8 +2805,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;
@@ -2803,14 +2822,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] 687+ messages in thread
* [PATCH 6.18 612/686] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (610 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 611/686] perf evsel: Close the fds opened so far when disabling missing features Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 613/686] platform/x86: Rename lenovo-wmi-capdata01 to lenovo-wmi-capdata Greg Kroah-Hartman
` (73 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Oliver Upton, Fuad Tabba,
Marc Zyngier, Sasha Levin
6.18-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 missing kvm_pause_vcpu() and kvm_resume_vcpu() calls with whole-guest kvm_arm_halt_guest() and kvm_arm_resume_guest() calls. ]
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 79e018cec0f96..5ba3bb576bb15 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] 687+ messages in thread
* [PATCH 6.18 613/686] platform/x86: Rename lenovo-wmi-capdata01 to lenovo-wmi-capdata
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (611 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 612/686] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 614/686] platform/x86: lenovo-wmi-capdata: Do not stop the AC notifier chain on error Greg Kroah-Hartman
` (72 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rong Zhang, Derek J. Clark,
Ilpo Järvinen, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rong Zhang <i@rong.moe>
[ Upstream commit f28d76b17561bd5f1b7b2c8f139a00158218c2d2 ]
Prepare for the upcoming changes to make it suitable to retrieve
and provide other Capability Data as well.
Signed-off-by: Rong Zhang <i@rong.moe>
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Tested-by: Derek J. Clark <derekjohn.clark@gmail.com>
Link: https://patch.msgid.link/20260120182104.163424-3-i@rong.moe
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Stable-dep-of: 3b53e691e907 ("platform/x86: lenovo-wmi-capdata: Do not stop the AC notifier chain on error")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/lenovo/Kconfig | 4 +-
drivers/platform/x86/lenovo/Makefile | 2 +-
.../lenovo/{wmi-capdata01.c => wmi-capdata.c} | 124 +++++++++---------
.../lenovo/{wmi-capdata01.h => wmi-capdata.h} | 10 +-
drivers/platform/x86/lenovo/wmi-other.c | 11 +-
5 files changed, 78 insertions(+), 73 deletions(-)
rename drivers/platform/x86/lenovo/{wmi-capdata01.c => wmi-capdata.c} (60%)
rename drivers/platform/x86/lenovo/{wmi-capdata01.h => wmi-capdata.h} (60%)
diff --git a/drivers/platform/x86/lenovo/Kconfig b/drivers/platform/x86/lenovo/Kconfig
index d22b774e0236f..587da1c602ca0 100644
--- a/drivers/platform/x86/lenovo/Kconfig
+++ b/drivers/platform/x86/lenovo/Kconfig
@@ -233,7 +233,7 @@ config YT2_1380
To compile this driver as a module, choose M here: the module will
be called lenovo-yogabook.
-config LENOVO_WMI_DATA01
+config LENOVO_WMI_CAPDATA
tristate
depends on ACPI_WMI
@@ -264,7 +264,7 @@ config LENOVO_WMI_TUNING
tristate "Lenovo Other Mode WMI Driver"
depends on ACPI_WMI
select FW_ATTR_CLASS
- select LENOVO_WMI_DATA01
+ select LENOVO_WMI_CAPDATA
select LENOVO_WMI_EVENTS
select LENOVO_WMI_HELPERS
help
diff --git a/drivers/platform/x86/lenovo/Makefile b/drivers/platform/x86/lenovo/Makefile
index 7b2128e3a2142..91a9370f11b3a 100644
--- a/drivers/platform/x86/lenovo/Makefile
+++ b/drivers/platform/x86/lenovo/Makefile
@@ -12,7 +12,7 @@ lenovo-target-$(CONFIG_LENOVO_YMC) += ymc.o
lenovo-target-$(CONFIG_YOGABOOK) += yogabook.o
lenovo-target-$(CONFIG_YT2_1380) += yoga-tab2-pro-1380-fastcharger.o
lenovo-target-$(CONFIG_LENOVO_WMI_CAMERA) += wmi-camera.o
-lenovo-target-$(CONFIG_LENOVO_WMI_DATA01) += wmi-capdata01.o
+lenovo-target-$(CONFIG_LENOVO_WMI_CAPDATA) += wmi-capdata.o
lenovo-target-$(CONFIG_LENOVO_WMI_EVENTS) += wmi-events.o
lenovo-target-$(CONFIG_LENOVO_WMI_HELPERS) += wmi-helpers.o
lenovo-target-$(CONFIG_LENOVO_WMI_GAMEZONE) += wmi-gamezone.o
diff --git a/drivers/platform/x86/lenovo/wmi-capdata01.c b/drivers/platform/x86/lenovo/wmi-capdata.c
similarity index 60%
rename from drivers/platform/x86/lenovo/wmi-capdata01.c
rename to drivers/platform/x86/lenovo/wmi-capdata.c
index fc7e3454e71dc..ba843b6604b06 100644
--- a/drivers/platform/x86/lenovo/wmi-capdata01.c
+++ b/drivers/platform/x86/lenovo/wmi-capdata.c
@@ -1,14 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
- * Lenovo Capability Data 01 WMI Data Block driver.
+ * Lenovo Capability Data WMI Data Block driver.
*
- * Lenovo Capability Data 01 provides information on tunable attributes used by
- * the "Other Mode" WMI interface. The data includes if the attribute is
- * supported by the hardware, the default_value, max_value, min_value, and step
- * increment. Each attribute has multiple pages, one for each of the thermal
- * modes managed by the Gamezone interface.
+ * Lenovo Capability Data provides information on tunable attributes used by
+ * the "Other Mode" WMI interface.
+ *
+ * Capability Data 01 includes if the attribute is supported by the hardware,
+ * and the default_value, max_value, min_value, and step increment. Each
+ * attribute has multiple pages, one for each of the thermal modes managed by
+ * the Gamezone interface.
*
* Copyright (C) 2025 Derek J. Clark <derekjohn.clark@gmail.com>
+ * - Initial implementation (formerly named lenovo-wmi-capdata01)
*/
#include <linux/acpi.h>
@@ -26,55 +29,55 @@
#include <linux/types.h>
#include <linux/wmi.h>
-#include "wmi-capdata01.h"
+#include "wmi-capdata.h"
#define LENOVO_CAPABILITY_DATA_01_GUID "7A8F5407-CB67-4D6E-B547-39B3BE018154"
#define ACPI_AC_CLASS "ac_adapter"
#define ACPI_AC_NOTIFY_STATUS 0x80
-struct lwmi_cd01_priv {
+struct lwmi_cd_priv {
struct notifier_block acpi_nb; /* ACPI events */
struct wmi_device *wdev;
- struct cd01_list *list;
+ struct cd_list *list;
};
-struct cd01_list {
+struct cd_list {
struct mutex list_mutex; /* list R/W mutex */
u8 count;
struct capdata01 data[];
};
/**
- * lwmi_cd01_component_bind() - Bind component to master device.
- * @cd01_dev: Pointer to the lenovo-wmi-capdata01 driver parent device.
+ * lwmi_cd_component_bind() - Bind component to master device.
+ * @cd_dev: Pointer to the lenovo-wmi-capdata driver parent device.
* @om_dev: Pointer to the lenovo-wmi-other driver parent device.
- * @data: capdata01_list object pointer used to return the capability data.
+ * @data: cd_list object pointer used to return the capability data.
*
- * On lenovo-wmi-other's master bind, provide a pointer to the local capdata01
- * list. This is used to call lwmi_cd01_get_data to look up attribute data
+ * On lenovo-wmi-other's master bind, provide a pointer to the local capdata
+ * list. This is used to call lwmi_cd*_get_data to look up attribute data
* from the lenovo-wmi-other driver.
*
* Return: 0
*/
-static int lwmi_cd01_component_bind(struct device *cd01_dev,
- struct device *om_dev, void *data)
+static int lwmi_cd_component_bind(struct device *cd_dev,
+ struct device *om_dev, void *data)
{
- struct lwmi_cd01_priv *priv = dev_get_drvdata(cd01_dev);
- struct cd01_list **cd01_list = data;
+ struct lwmi_cd_priv *priv = dev_get_drvdata(cd_dev);
+ struct cd_list **cd_list = data;
- *cd01_list = priv->list;
+ *cd_list = priv->list;
return 0;
}
-static const struct component_ops lwmi_cd01_component_ops = {
- .bind = lwmi_cd01_component_bind,
+static const struct component_ops lwmi_cd_component_ops = {
+ .bind = lwmi_cd_component_bind,
};
/**
* lwmi_cd01_get_data - Get the data of the specified attribute
- * @list: The lenovo-wmi-capdata01 pointer to its cd01_list struct.
+ * @list: The lenovo-wmi-capdata pointer to its cd_list struct.
* @attribute_id: The capdata attribute ID to be found.
* @output: Pointer to a capdata01 struct to return the data.
*
@@ -83,7 +86,7 @@ static const struct component_ops lwmi_cd01_component_ops = {
*
* Return: 0 on success, or -EINVAL.
*/
-int lwmi_cd01_get_data(struct cd01_list *list, u32 attribute_id, struct capdata01 *output)
+int lwmi_cd01_get_data(struct cd_list *list, u32 attribute_id, struct capdata01 *output)
{
u8 idx;
@@ -97,17 +100,17 @@ int lwmi_cd01_get_data(struct cd01_list *list, u32 attribute_id, struct capdata0
return -EINVAL;
}
-EXPORT_SYMBOL_NS_GPL(lwmi_cd01_get_data, "LENOVO_WMI_CD01");
+EXPORT_SYMBOL_NS_GPL(lwmi_cd01_get_data, "LENOVO_WMI_CAPDATA");
/**
- * lwmi_cd01_cache() - Cache all WMI data block information
- * @priv: lenovo-wmi-capdata01 driver data.
+ * lwmi_cd_cache() - Cache all WMI data block information
+ * @priv: lenovo-wmi-capdata driver data.
*
* Loop through each WMI data block and cache the data.
*
* Return: 0 on success, or an error.
*/
-static int lwmi_cd01_cache(struct lwmi_cd01_priv *priv)
+static int lwmi_cd_cache(struct lwmi_cd_priv *priv)
{
int idx;
@@ -131,17 +134,17 @@ static int lwmi_cd01_cache(struct lwmi_cd01_priv *priv)
}
/**
- * lwmi_cd01_alloc() - Allocate a cd01_list struct in drvdata
- * @priv: lenovo-wmi-capdata01 driver data.
+ * lwmi_cd_alloc() - Allocate a cd_list struct in drvdata
+ * @priv: lenovo-wmi-capdata driver data.
*
- * Allocate a cd01_list struct large enough to contain data from all WMI data
+ * Allocate a cd_list struct large enough to contain data from all WMI data
* blocks provided by the interface.
*
* Return: 0 on success, or an error.
*/
-static int lwmi_cd01_alloc(struct lwmi_cd01_priv *priv)
+static int lwmi_cd_alloc(struct lwmi_cd_priv *priv)
{
- struct cd01_list *list;
+ struct cd_list *list;
size_t list_size;
int count, ret;
@@ -163,28 +166,28 @@ static int lwmi_cd01_alloc(struct lwmi_cd01_priv *priv)
}
/**
- * lwmi_cd01_setup() - Cache all WMI data block information
- * @priv: lenovo-wmi-capdata01 driver data.
+ * lwmi_cd_setup() - Cache all WMI data block information
+ * @priv: lenovo-wmi-capdata driver data.
*
- * Allocate a cd01_list struct large enough to contain data from all WMI data
+ * Allocate a cd_list struct large enough to contain data from all WMI data
* blocks provided by the interface. Then loop through each data block and
* cache the data.
*
* Return: 0 on success, or an error code.
*/
-static int lwmi_cd01_setup(struct lwmi_cd01_priv *priv)
+static int lwmi_cd_setup(struct lwmi_cd_priv *priv)
{
int ret;
- ret = lwmi_cd01_alloc(priv);
+ ret = lwmi_cd_alloc(priv);
if (ret)
return ret;
- return lwmi_cd01_cache(priv);
+ return lwmi_cd_cache(priv);
}
/**
- * lwmi_cd01_notifier_call() - Call method for lenovo-wmi-capdata01 driver notifier.
+ * lwmi_cd01_notifier_call() - Call method for cd01 notifier.
* block call chain.
* @nb: The notifier_block registered to lenovo-wmi-events driver.
* @action: Unused.
@@ -199,17 +202,17 @@ static int lwmi_cd01_notifier_call(struct notifier_block *nb, unsigned long acti
void *data)
{
struct acpi_bus_event *event = data;
- struct lwmi_cd01_priv *priv;
+ struct lwmi_cd_priv *priv;
int ret;
if (strcmp(event->device_class, ACPI_AC_CLASS) != 0)
return NOTIFY_DONE;
- priv = container_of(nb, struct lwmi_cd01_priv, acpi_nb);
+ priv = container_of(nb, struct lwmi_cd_priv, acpi_nb);
switch (event->type) {
case ACPI_AC_NOTIFY_STATUS:
- ret = lwmi_cd01_cache(priv);
+ ret = lwmi_cd_cache(priv);
if (ret)
return NOTIFY_BAD;
@@ -230,10 +233,9 @@ static void lwmi_cd01_unregister(void *data)
unregister_acpi_notifier(acpi_nb);
}
-static int lwmi_cd01_probe(struct wmi_device *wdev, const void *context)
-
+static int lwmi_cd_probe(struct wmi_device *wdev, const void *context)
{
- struct lwmi_cd01_priv *priv;
+ struct lwmi_cd_priv *priv;
int ret;
priv = devm_kzalloc(&wdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -243,7 +245,7 @@ static int lwmi_cd01_probe(struct wmi_device *wdev, const void *context)
priv->wdev = wdev;
dev_set_drvdata(&wdev->dev, priv);
- ret = lwmi_cd01_setup(priv);
+ ret = lwmi_cd_setup(priv);
if (ret)
return ret;
@@ -257,27 +259,27 @@ static int lwmi_cd01_probe(struct wmi_device *wdev, const void *context)
if (ret)
return ret;
- return component_add(&wdev->dev, &lwmi_cd01_component_ops);
+ return component_add(&wdev->dev, &lwmi_cd_component_ops);
}
-static void lwmi_cd01_remove(struct wmi_device *wdev)
+static void lwmi_cd_remove(struct wmi_device *wdev)
{
- component_del(&wdev->dev, &lwmi_cd01_component_ops);
+ component_del(&wdev->dev, &lwmi_cd_component_ops);
}
-static const struct wmi_device_id lwmi_cd01_id_table[] = {
+static const struct wmi_device_id lwmi_cd_id_table[] = {
{ LENOVO_CAPABILITY_DATA_01_GUID, NULL },
{}
};
-static struct wmi_driver lwmi_cd01_driver = {
+static struct wmi_driver lwmi_cd_driver = {
.driver = {
- .name = "lenovo_wmi_cd01",
+ .name = "lenovo_wmi_capdata",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
},
- .id_table = lwmi_cd01_id_table,
- .probe = lwmi_cd01_probe,
- .remove = lwmi_cd01_remove,
+ .id_table = lwmi_cd_id_table,
+ .probe = lwmi_cd_probe,
+ .remove = lwmi_cd_remove,
.no_singleton = true,
};
@@ -290,13 +292,13 @@ static struct wmi_driver lwmi_cd01_driver = {
*/
int lwmi_cd01_match(struct device *dev, void *data)
{
- return dev->driver == &lwmi_cd01_driver.driver;
+ return dev->driver == &lwmi_cd_driver.driver;
}
-EXPORT_SYMBOL_NS_GPL(lwmi_cd01_match, "LENOVO_WMI_CD01");
+EXPORT_SYMBOL_NS_GPL(lwmi_cd01_match, "LENOVO_WMI_CAPDATA");
-module_wmi_driver(lwmi_cd01_driver);
+module_wmi_driver(lwmi_cd_driver);
-MODULE_DEVICE_TABLE(wmi, lwmi_cd01_id_table);
+MODULE_DEVICE_TABLE(wmi, lwmi_cd_id_table);
MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
-MODULE_DESCRIPTION("Lenovo Capability Data 01 WMI Driver");
+MODULE_DESCRIPTION("Lenovo Capability Data WMI Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/lenovo/wmi-capdata01.h b/drivers/platform/x86/lenovo/wmi-capdata.h
similarity index 60%
rename from drivers/platform/x86/lenovo/wmi-capdata01.h
rename to drivers/platform/x86/lenovo/wmi-capdata.h
index bd06c5751f68b..2a4746e38ad43 100644
--- a/drivers/platform/x86/lenovo/wmi-capdata01.h
+++ b/drivers/platform/x86/lenovo/wmi-capdata.h
@@ -2,13 +2,13 @@
/* Copyright (C) 2025 Derek J. Clark <derekjohn.clark@gmail.com> */
-#ifndef _LENOVO_WMI_CAPDATA01_H_
-#define _LENOVO_WMI_CAPDATA01_H_
+#ifndef _LENOVO_WMI_CAPDATA_H_
+#define _LENOVO_WMI_CAPDATA_H_
#include <linux/types.h>
struct device;
-struct cd01_list;
+struct cd_list;
struct capdata01 {
u32 id;
@@ -19,7 +19,7 @@ struct capdata01 {
u32 max_value;
};
-int lwmi_cd01_get_data(struct cd01_list *list, u32 attribute_id, struct capdata01 *output);
+int lwmi_cd01_get_data(struct cd_list *list, u32 attribute_id, struct capdata01 *output);
int lwmi_cd01_match(struct device *dev, void *data);
-#endif /* !_LENOVO_WMI_CAPDATA01_H_ */
+#endif /* !_LENOVO_WMI_CAPDATA_H_ */
diff --git a/drivers/platform/x86/lenovo/wmi-other.c b/drivers/platform/x86/lenovo/wmi-other.c
index dc7c60df7ad3b..eaab925068766 100644
--- a/drivers/platform/x86/lenovo/wmi-other.c
+++ b/drivers/platform/x86/lenovo/wmi-other.c
@@ -34,7 +34,7 @@
#include <linux/types.h>
#include <linux/wmi.h>
-#include "wmi-capdata01.h"
+#include "wmi-capdata.h"
#include "wmi-events.h"
#include "wmi-helpers.h"
#include "wmi-other.h"
@@ -73,7 +73,10 @@ enum attribute_property {
struct lwmi_om_priv {
struct component_master_ops *ops;
- struct cd01_list *cd01_list; /* only valid after capdata01 bind */
+
+ /* only valid after capdata bind */
+ struct cd_list *cd01_list;
+
struct device *fw_attr_dev;
struct kset *fw_attr_kset;
struct notifier_block nb;
@@ -574,7 +577,7 @@ static void lwmi_om_fw_attr_remove(struct lwmi_om_priv *priv)
static int lwmi_om_master_bind(struct device *dev)
{
struct lwmi_om_priv *priv = dev_get_drvdata(dev);
- struct cd01_list *tmp_list;
+ struct cd_list *tmp_list;
int ret;
ret = component_bind_all(dev, &tmp_list);
@@ -655,7 +658,7 @@ static struct wmi_driver lwmi_other_driver = {
module_wmi_driver(lwmi_other_driver);
-MODULE_IMPORT_NS("LENOVO_WMI_CD01");
+MODULE_IMPORT_NS("LENOVO_WMI_CAPDATA");
MODULE_IMPORT_NS("LENOVO_WMI_HELPERS");
MODULE_DEVICE_TABLE(wmi, lwmi_other_id_table);
MODULE_AUTHOR("Derek J. Clark <derekjohn.clark@gmail.com>");
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 614/686] platform/x86: lenovo-wmi-capdata: Do not stop the AC notifier chain on error
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (612 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 613/686] platform/x86: Rename lenovo-wmi-capdata01 to lenovo-wmi-capdata Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 615/686] iio: adc: ad4080: enable address ascension for chip identification Greg Kroah-Hartman
` (71 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Navon John Lukose, Derek J. Clark,
Mark Pearson, Rong Zhang, Ilpo Järvinen, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rong Zhang <i@rong.moe>
[ Upstream commit 3b53e691e907086672b72d0544e4bf27efd4250d ]
Returning NOTIFY_BAD to the AC notifier chain stops it by preventing
later notifier blocks from being called, but our error is non-fatal for
other AC notifier blocks, which should continue to consume the event.
Return NOTIFY_DONE and add a dev_warn() on error, so that the AC
notifier chain continues. This also aligns with hp-wmi.
The function documentation was copied from elsewhere and makes no sense
here, so correct it as well.
Fixes: e1a5fe662b59 ("platform/x86: Add Lenovo Capability Data 01 WMI Driver")
Cc: stable@vger.kernel.org
Tested-by: Navon John Lukose <navonjohnlukose@gmail.com>
Reviewed-by: Derek J. Clark <derekjohn.clark@gmail.com>
Reviewed-by: Mark Pearson <mpearson-lenovo@squebb.ca>
Signed-off-by: Rong Zhang <i@rong.moe>
Link: https://patch.msgid.link/20261019-lwmi-wmi-new-api-v5-2-71557d28d058@rong.moe
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/lenovo/wmi-capdata.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/platform/x86/lenovo/wmi-capdata.c b/drivers/platform/x86/lenovo/wmi-capdata.c
index ba843b6604b06..c7fa1c2969561 100644
--- a/drivers/platform/x86/lenovo/wmi-capdata.c
+++ b/drivers/platform/x86/lenovo/wmi-capdata.c
@@ -188,13 +188,11 @@ static int lwmi_cd_setup(struct lwmi_cd_priv *priv)
/**
* lwmi_cd01_notifier_call() - Call method for cd01 notifier.
- * block call chain.
- * @nb: The notifier_block registered to lenovo-wmi-events driver.
+ * @nb: The cd01 ACPI notifier_block.
* @action: Unused.
* @data: The ACPI event.
*
- * For LWMI_EVENT_THERMAL_MODE, set current_mode and notify platform_profile
- * of a change.
+ * Refresh cached capdata on AC status change.
*
* Return: notifier_block status.
*/
@@ -213,8 +211,16 @@ static int lwmi_cd01_notifier_call(struct notifier_block *nb, unsigned long acti
switch (event->type) {
case ACPI_AC_NOTIFY_STATUS:
ret = lwmi_cd_cache(priv);
- if (ret)
- return NOTIFY_BAD;
+ if (ret) {
+ dev_warn(&priv->wdev->dev,
+ "failed to refresh capdata on AC change: %d\n", ret);
+
+ /*
+ * Our error is non-fatal for others, and we still want
+ * the other event consumers to process it.
+ */
+ return NOTIFY_DONE;
+ }
return NOTIFY_OK;
default:
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 615/686] iio: adc: ad4080: enable address ascension for chip identification
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (613 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 614/686] platform/x86: lenovo-wmi-capdata: Do not stop the AC notifier chain on error Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 616/686] fbcon: Retry rotated font allocation after failure Greg Kroah-Hartman
` (70 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Antoniu Miclaus, Nuno Sá,
Jonathan Cameron, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <antoniu.miclaus@analog.com>
[ Upstream commit c051d08d98771132868abf0cb95b6de95ab3060a ]
The two byte bulk read at AD4080_REG_PRODUCT_ID_L expects PRODUCT_ID_L
followed by PRODUCT_ID_H. After a software reset the AD408x defaults to
descending address mode, so the second byte comes from CHIP_TYPE (0x03)
instead. CHIP_TYPE reads 0x07 on all AD408x parts, so an AD4080 reports
0x0750 rather than 0x0050 and every part logs "Unrecognized CHIP_ID".
Set ADDR_ASC along with SDO_ENABLE before the read. This is the only
multi byte transfer in the driver, so no other access is affected.
Fixes: b66cddc8be72 ("iio: adc: ad4080: fix chip identification")
Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
Reviewed-by: Nuno Sá <nuno.sa@analog.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jonathan Cameron <jonathan.cameron@oss.qualcomm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iio/adc/ad4080.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/iio/adc/ad4080.c b/drivers/iio/adc/ad4080.c
index e15310fcd21a3..584f273c6bb35 100644
--- a/drivers/iio/adc/ad4080.c
+++ b/drivers/iio/adc/ad4080.c
@@ -455,7 +455,8 @@ static int ad4080_setup(struct iio_dev *indio_dev)
return ret;
ret = regmap_write(st->regmap, AD4080_REG_INTERFACE_CONFIG_A,
- AD4080_INTERFACE_CONFIG_A_SDO_ENABLE);
+ AD4080_INTERFACE_CONFIG_A_SDO_ENABLE |
+ AD4080_INTERFACE_CONFIG_A_ADDR_ASC);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 616/686] fbcon: Retry rotated font allocation after failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (614 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 615/686] iio: adc: ad4080: enable address ascension for chip identification Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 617/686] mm: hugetlb: return -ENOSPC on memcg charge failure Greg Kroah-Hartman
` (69 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yao Yiqi, Thomas Zimmermann,
Helge Deller, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yao Yiqi <yaoyiqi3@huawei.com>
[ Upstream commit 7935db1a4a0f83a63590a222500e5016e2f6c85e ]
fbcon_rotate_font() records the font, its geometry and the rotation in
par->rotated before calling font_data_rotate(). If the allocation
fails, the error path clears par->rotated.buf, but the recorded key
already looks up to date, so the next call takes the early-out and
never retries. The rotated putcs/cursor ops keep returning early on
the NULL buffer, and the console stays blank even after memory is
available again.
Also test par->rotated.buf in the early-out, so a failed allocation
is retried on the next call: at the next fbcon_switch(),
fbcon_modechanged() or font change.
Fixes: e4ef723d8975 ("fbcon: Avoid OOB font access if console rotation fails")
Cc: stable@vger.kernel.org
Signed-off-by: Yao Yiqi <yaoyiqi3@huawei.com>
Acked-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>
[ sashal: Adapted the par->rotated.buf check to use par->fontbuffer in the existing cache condition. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/video/fbdev/core/fbcon_rotate.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
index a3f507825eed8..3105682075c87 100644
--- a/drivers/video/fbdev/core/fbcon_rotate.c
+++ b/drivers/video/fbdev/core/fbcon_rotate.c
@@ -27,7 +27,8 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
u8 *dst;
if (vc->vc_font.data == par->fontdata &&
- par->p->con_rotate == par->cur_rotate)
+ par->p->con_rotate == par->cur_rotate &&
+ par->fontbuffer)
goto finished;
src = par->fontdata = vc->vc_font.data;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 617/686] mm: hugetlb: return -ENOSPC on memcg charge failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (615 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 616/686] fbcon: Retry rotated font allocation after failure Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 618/686] mm: hugetlb: drop refcount before freeing " Greg Kroah-Hartman
` (68 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ackerley Tng, Andrew Morton,
Muchun Song, Joshua Hahn, Alex Shi, David Hildenbrand,
David Rientjes, Dongliang Mu, Frank van der Linden, Hongxiang Lou,
James Houghton, Johannes Weiner, Jonathan Corbet, Liam R. Howlett,
Lorenzo Stoakes, Ma Wupeng, Miaohe Lin, Michal Hocko,
Mike Rapoport, Nhat Pham, Oscar Salvador, Peter Xu,
Roman Gushchin, Shakeel Butt, Suren Baghdasaryan,
Vishal Annapurve, Vlastimil Babka, Yanteng Si, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ackerley Tng <ackerleytng@google.com>
[ Upstream commit 956aeff185e7e16b989202bde0bb29859adba99d ]
Patch series "Fix bugs in HugeTLB allocation when
mem_cgroup_charge_hugetlb() fails", v2.
In hugetlb_alloc_folio(), when mem_cgroup_charge_hugetlb() fails, there
are 2 issues:
1. free_huge_folio() expects a non-refcounted folio and will
VM_BUG_ON_FOLIO().
2. -ENOMEM is returned, causing an infinite loop retrying the fault.
This patch (of 2):
When mem_cgroup_charge_hugetlb() fails with -ENOMEM, alloc_hugetlb_folio()
currently propagates this error. This results in the page fault handler
returning VM_FAULT_OOM.
Because HugeTLB allocations are high-order and use __GFP_RETRY_MAYFAIL,
they bypass the OOM killer. Returning VM_FAULT_OOM to the #PF handler
without triggering the OOM killer (or having it make progress) leads to an
infinite loop of retrying the fault.
Avoid this loop by returning -ENOSPC when charging fails, which maps to
VM_FAULT_SIGBUS, terminating the process cleanly.
Make mem_cgroup_charge_hugetlb() fault handling use a common error
handling path, the same handling used for
hugetlb_cgroup_uncharge_cgroup{,_rsvd}(), which also don't trigger the OOM
killer and hence opt to terminate the process with a SIGBUS.
Link: https://lore.kernel.org/20260909-hugetlb-alloc-folio-memcg-charge-error-handling-v2-1-4b4a8a19a7f7@google.com
Fixes: 991135774c0e ("memcg/hugetlb: introduce mem_cgroup_charge_hugetlb")
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Alex Shi <alexs@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Dongliang Mu <dzm91@hust.edu.cn>
Cc: Frank van der Linden <fvdl@google.com>
Cc: Hongxiang Lou <louhongxiang@huawei.com>
Cc: James Houghton <jthoughton@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Ma Wupeng <mawupeng1@huawei.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Peter Xu <peterx@redhat.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vishal Annapurve <vannapurve@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Yanteng Si <si.yanteng@linux.dev>
Cc: <stable@vger.kernel.org>
[ sashal: Adapted the change to alloc_hugetlb_folio() because hugetlb_alloc_folio() has not been extracted. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index fccff6d6ca64e..1bfeaecf9b4fa 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3134,7 +3134,11 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
if (ret == -ENOMEM) {
free_huge_folio(folio);
- return ERR_PTR(-ENOMEM);
+ /*
+ * Return -ENOSPC, since retrying the fault is futile:
+ * the OOM killer is not triggered for HugeTLB.
+ */
+ return ERR_PTR(-ENOSPC);
}
return folio;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 618/686] mm: hugetlb: drop refcount before freeing on memcg charge failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (616 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 617/686] mm: hugetlb: return -ENOSPC on memcg charge failure Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 619/686] xen/gntdev: Fix gntdev_dmabuf ref leak in dmabuf_exp_wait_released() Greg Kroah-Hartman
` (67 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ackerley Tng, Andrew Morton,
Muchun Song, Joshua Hahn, Alex Shi, David Hildenbrand,
David Rientjes, Dongliang Mu, Frank van der Linden, Hongxiang Lou,
James Houghton, Johannes Weiner, Jonathan Corbet, Liam R. Howlett,
Lorenzo Stoakes, Ma Wupeng, Miaohe Lin, Michal Hocko,
Mike Rapoport, Nhat Pham, Oscar Salvador, Peter Xu,
Roman Gushchin, Shakeel Butt, Suren Baghdasaryan,
Vishal Annapurve, Vlastimil Babka, Yanteng Si, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ackerley Tng <ackerleytng@google.com>
[ Upstream commit e95d29c5df84f19881cd30b491fc81aa98f44b45 ]
When mem_cgroup_charge_hugetlb(folio, gfp) returns -ENOMEM, the folio has
its refcount set to 1 via folio_ref_unfreeze(folio, 1).
The error path calls free_huge_folio(folio) directly, which expects a
refcount of 0. Hence, VM_BUG_ON_FOLIO(folio_ref_count(folio), folio) is
triggered.
Even with CONFIG_DEBUG_VM disabled, returning a folio with refcount 1 to
the freelist can corrupt allocator state later.
Use folio_put(folio) instead of free_huge_folio(folio) to properly drop
the reference before freeing it.
Link: https://lore.kernel.org/20260909-hugetlb-alloc-folio-memcg-charge-error-handling-v2-2-4b4a8a19a7f7@google.com
Fixes: 991135774c0e ("memcg/hugetlb: introduce mem_cgroup_charge_hugetlb")
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Alex Shi <alexs@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Dongliang Mu <dzm91@hust.edu.cn>
Cc: Frank van der Linden <fvdl@google.com>
Cc: Hongxiang Lou <louhongxiang@huawei.com>
Cc: James Houghton <jthoughton@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Ma Wupeng <mawupeng1@huawei.com>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Peter Xu <peterx@redhat.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vishal Annapurve <vannapurve@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Yanteng Si <si.yanteng@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/hugetlb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 1bfeaecf9b4fa..225c04d583adc 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3133,7 +3133,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
lruvec_stat_mod_folio(folio, NR_HUGETLB, pages_per_huge_page(h));
if (ret == -ENOMEM) {
- free_huge_folio(folio);
+ folio_put(folio);
/*
* Return -ENOSPC, since retrying the fault is futile:
* the OOM killer is not triggered for HugeTLB.
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 619/686] xen/gntdev: Fix gntdev_dmabuf ref leak in dmabuf_exp_wait_released()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (617 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 618/686] mm: hugetlb: drop refcount before freeing " Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 620/686] mm/mempolicy: use vm_normal_folio_pmd() in queue_folios_pmd() Greg Kroah-Hartman
` (66 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Juergen Gross,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
[ Upstream commit 6f165abe2b40ede71c98956cd74cd17c18505e75 ]
dmabuf_exp_wait_released() takes a reference on the exported
gntdev_dmabuf with dmabuf_exp_wait_obj_get_dmabuf() and passes it to
dmabuf_exp_wait_obj_new(), which drops that reference after adding the
wait object to the wait list. When the wait object allocation fails,
dmabuf_exp_wait_obj_new() returns ERR_PTR(-ENOMEM) early and the
reference is never dropped, leaking a reference to the exported
gntdev_dmabuf.
Drop the reference on the allocation failure path so the reference is
consumed whether the wait object is created or not.
Fixes: 932d6562179e ("xen/gntdev: Add initial support for dma-buf UAPI")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Reviewed-by: Juergen Gross <jgross@suse.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Message-ID: <20260916170956.2086505-1-vulab@iscas.ac.cn>
[ sashal: Retained kzalloc(sizeof(*obj), GFP_KERNEL) allocation context instead of kzalloc_obj(*obj). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/xen/gntdev-dmabuf.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/xen/gntdev-dmabuf.c b/drivers/xen/gntdev-dmabuf.c
index 550980dd3b0bc..5d38506a14f44 100644
--- a/drivers/xen/gntdev-dmabuf.c
+++ b/drivers/xen/gntdev-dmabuf.c
@@ -96,8 +96,10 @@ dmabuf_exp_wait_obj_new(struct gntdev_dmabuf_priv *priv,
struct gntdev_dmabuf_wait_obj *obj;
obj = kzalloc(sizeof(*obj), GFP_KERNEL);
- if (!obj)
+ if (!obj) {
+ kref_put(&gntdev_dmabuf->u.exp.refcount, dmabuf_exp_release);
return ERR_PTR(-ENOMEM);
+ }
init_completion(&obj->completion);
obj->gntdev_dmabuf = gntdev_dmabuf;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 620/686] mm/mempolicy: use vm_normal_folio_pmd() in queue_folios_pmd()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (618 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 619/686] xen/gntdev: Fix gntdev_dmabuf ref leak in dmabuf_exp_wait_released() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 621/686] ublk: mark the io command cancelable before publishing it Greg Kroah-Hartman
` (65 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gregory Price (Meta), Andrew Morton,
sashiko-bot, David Hildenbrand (Arm), Zi Yan, Liam R. Howlett,
Lorenzo Stoakes, Vlastimil Babka, Jann Horn, Joshua Hahn,
Rakie Kim, Ying Huang, Peter Xu, Jason Gunthorpe, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory Price <gourry@gourry.net>
[ Upstream commit 9057170a941f0c5f4058f6fb9ab5d5fc9fcc9e83 ]
Patch series "mm: stop calling pmd_folio() on special PMDs", v3.
Two page table walkers resolve the folio behind a PMD with pmd_folio(),
which is only valid for a PMD mapping a refcounted struct page:
madvise_cold_or_pageout_pte_range() mm/madvise.c
queue_folios_pmd() mm/mempolicy.c
vmf_insert_pfn_pmd() installs special PMDs holding a raw pfn that need not
have a memmap entry at all. Both walkers can reach one and fault on the
first folio field read. The PTE halves of both already use
vm_normal_folio(); these two patches make the PMD halves match.
The four callers of vmf_insert_pfn_pmd(), and which walker each reaches:
drivers/vfio/pci/vfio_pci_core.c VM_PFNMAP mempolicy
drivers/gpu/drm/drm_gem_shmem_helper.c VM_PFNMAP mempolicy
drivers/gpu/drm/panthor/panthor_gem.c VM_PFNMAP mempolicy
drivers/hv/mshv_vtl_main.c VM_MIXEDMAP both
can_madv_lru_vma() rejects VM_PFNMAP, so only mshv_vtl_low reaches the
madvise walker, and that needs CAP_SYS_ADMIN. queue_pages_walk_ops
supplies its own ->test_walk, so walk_page_test()'s generic VM_PFNMAP skip
never runs and vfio-pci is reachable by any process holding the device fd.
Hence the different stable tags.
One behaviour change: mbind(MPOL_MF_STRICT) over a PMD mapped VM_PFNMAP
region now returns 0 rather than -EIO. The PTE loop already returned 0
there. drm_gem_shmem and panthor are where this is observable, since they
PMD map pages that do have a memmap entry and so never faulted.
Reproducer
==========
No hardware needed. An out of tree module stands in for the drivers
above: three misc devices, each with a ->huge_fault calling
vmf_insert_pfn_pmd(), plus VM_HUGEPAGE so the fault path takes the PMD
branch.
/dev/pmdspec_mixed VM_MIXEDMAP, pfn at the 1 TiB mark, no memmap
/dev/pmdspec_pfnmap VM_PFNMAP, pfn at the 1 TiB mark, no memmap
/dev/pmdspec_real VM_PFNMAP, real alloc_pages(PMD_ORDER) on node 0
Userspace maps the device into a PMD aligned window, reads one byte to
fault the PMD in, checks a module parameter to confirm it went in, then
issues the operation.
vng --run <bzImage> --user root --memory 4G --verbose \
--append "numa=fake=2" \
--exec "insmod pmdspec.ko && ./pmdspec_test <subtest>"
numa=fake=2 gives a node 1 to bind to; the module allocates its real page
on node 0, which is what makes queue_folio_required() true.
subtest operation parent series
--------------------------------------------------------------------
madv_cold madvise(MADV_COLD) oops ret=0
madv_pageout madvise(MADV_PAGEOUT) oops ret=0
mbind_mixed mbind(MPOL_BIND, n1, MPOL_MF_MOVE) oops ret=0
mbind_pfnmap mbind(MPOL_BIND, n1, MPOL_MF_STRICT) oops ret=0
mbind_real mbind(MPOL_BIND, n1, MPOL_MF_STRICT) -EIO ret=0
Two things the table shows that are easy to miss in the code:
- mbind_mixed passes only MPOL_MF_MOVE. MPOL_MF_STRICT is not needed for
a VM_MIXEDMAP vma: walk_page_test() only skips VM_PFNMAP, and
vma_migratable() is true for VM_MIXEDMAP.
- mbind_real demonstrates the user visible change (-EIO -> 0)
This patch (of 2):
mmap a VM_PFNMAP region whose ->huge_fault installs a PMD through
vmf_insert_pfn_pmd() - a vfio-pci MMIO BAR does this - then
mbind(p, len, MPOL_BIND, &mask, maxnode, MPOL_MF_STRICT);
With a stand-in module for the driver:
BUG: unable to handle page fault for address: fffff96dc0000008
RIP: 0010:queue_folios_pte_range+0xaf/0x440
walk_pgd_range+0x52b/0xaf0
__walk_page_range+0x6a/0x1d0
walk_page_range_mm_unsafe+0x193/0x230
queue_pages_range+0x64/0xa0
do_mbind+0x25e/0x640
queue_folios_pmd(), inlined above, calls pmd_folio() on that PMD. The pfn
is raw MMIO with no memmap entry, so the folio lands in unpopulated
vmemmap. Neither guard stops the walk:
walk_page_test() skips VM_PFNMAP, but queue_pages_walk_ops
supplies ->test_walk, so it never runs
queue_pages_test_walk() honours vma_migratable(), but only while
MPOL_MF_STRICT is clear
A VM_MIXEDMAP vma needs neither flag, being vma_migratable(), so plain
mbind(MPOL_MF_MOVE) reaches this too - and there the bad folio carries on
into migrate_folio_add() and folio_isolate_lru(). mshv_vtl_low is such a
mapping.
Use vm_normal_folio_pmd() and skip on NULL, as the PTE loop in
queue_folios_pte_range() already does with vm_normal_folio(). This also
filters the huge zero PMD, so its separate check is no longer needed.
mbind(MPOL_MF_STRICT) over a PMD mapped VM_PFNMAP region now returns 0
rather than -EIO. The PTE loop already returned 0 there.
Link: https://lore.kernel.org/20260926105110.2156652-1-gourry@gourry.net
Link: https://lore.kernel.org/20260926105110.2156652-2-gourry@gourry.net
Fixes: 3c8e44c9b369 ("mm: mark special bits for huge pfn mappings when inject")
Signed-off-by: Gregory Price (Meta) <gourry@gourry.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260817220810.1175596-1-gourry%40gourry.net
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Assisted-by: LLM
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Ying Huang <ying.huang@linux.alibaba.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: <stable@vger.kernel.org>
[ sashal: Passed *pmd to vm_normal_folio_pmd() instead of the upstream cached pmdval variable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/mempolicy.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 3dfd20b55a9d7..5a9743c2c00f2 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -646,7 +646,8 @@ static inline bool queue_folio_required(struct folio *folio,
return node_isset(nid, *qp->nmask) == !(flags & MPOL_MF_INVERT);
}
-static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
+static void queue_folios_pmd(pmd_t *pmd, unsigned long addr,
+ struct mm_walk *walk)
{
struct folio *folio;
struct queue_pages *qp = walk->private;
@@ -655,11 +656,9 @@ static void queue_folios_pmd(pmd_t *pmd, struct mm_walk *walk)
qp->nr_failed++;
return;
}
- folio = pmd_folio(*pmd);
- if (is_huge_zero_folio(folio)) {
- walk->action = ACTION_CONTINUE;
+ folio = vm_normal_folio_pmd(walk->vma, addr, *pmd);
+ if (!folio || folio_is_zone_device(folio))
return;
- }
if (!queue_folio_required(folio, qp))
return;
if (!(qp->flags & (MPOL_MF_MOVE | MPOL_MF_MOVE_ALL)) ||
@@ -692,7 +691,7 @@ static int queue_folios_pte_range(pmd_t *pmd, unsigned long addr,
ptl = pmd_trans_huge_lock(pmd, vma);
if (ptl) {
- queue_folios_pmd(pmd, walk);
+ queue_folios_pmd(pmd, addr, walk);
spin_unlock(ptl);
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 621/686] ublk: mark the io command cancelable before publishing it
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (619 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 620/686] mm/mempolicy: use vm_normal_folio_pmd() in queue_folios_pmd() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 622/686] nvmem: rockchip-otp: alloc clks with main struct Greg Kroah-Hartman
` (64 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, Ming Lei, Jens Axboe,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei <tom.leiming@gmail.com>
[ Upstream commit a261f0cacacc022e4fab5b8e38c59f74ce4942e8 ]
FETCH, COMMIT_AND_FETCH and NEED_GET_DATA publish the command in io->cmd
before marking it cancelable. A cancel from the control path (STOP_DEV,
QUIESCE_DEV) can complete it in between:
issue path control-path cancel
io->cmd = C
take C, io_uring_cmd_done(C):
C not marked, nothing to unlink
ublk_prep_cancel(C)
the completed C is linked on the cancelable list
ring exit: the cancel walk hits it → GPF (KASAN, with a delay added)
Mark the command before ublk_fill_io_cmd() publishes it. The handlers
run with uring_lock held, as io_uring's cancel walk does, so marking
takes no lock and the walk can't see a marked command before it is
published. smp_wmb() orders the mark before the io->cmd store; the
cancel loads cmd with READ_ONCE(io->cmd) before reading cmd->flags.
A marked command has to be completed by io_uring_cmd_done(), so a failed
FETCH and the inline UBLK_IO_RES_OK of NEED_GET_DATA now do that. The CQE
is the same.
Fixes: 216c8f5ef0f2 ("ublk: replace monitor with cancelable uring_cmd")
Cc: stable@vger.kernel.org
Tested-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20261011063555.1142277-3-tom.leiming@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
[ sashal: passed READ_ONCE(io->cmd) directly to io_uring_cmd_done() instead of storing it in a local variable ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/ublk_drv.c | 28 ++++++++++++++++++++++------
1 file changed, 22 insertions(+), 6 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index c0e4f94cc43b0..197825f44b1d0 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -2003,8 +2003,10 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, unsigned tag,
io->flags |= UBLK_IO_FLAG_CANCELED;
spin_unlock(&ubq->cancel_lock);
+ /* dependency ordered against smp_wmb() in ublk_prep_cancel() */
if (!done)
- io_uring_cmd_done(io->cmd, UBLK_IO_RES_ABORT, issue_flags);
+ io_uring_cmd_done(READ_ONCE(io->cmd), UBLK_IO_RES_ABORT,
+ issue_flags);
}
/*
@@ -2274,6 +2276,12 @@ ublk_fill_io_cmd(struct ublk_io *io, struct io_uring_cmd *cmd)
return req;
}
+/*
+ * Call before ublk_fill_io_cmd() publishes @cmd in io->cmd: a control-path
+ * cancel may complete any command found there, and io_uring_cmd_done() only
+ * takes it off the cancelable list if it is marked already. The handlers
+ * hold uring_lock, so marking takes no lock.
+ */
static inline void ublk_prep_cancel(struct io_uring_cmd *cmd,
unsigned int issue_flags,
struct ublk_queue *ubq, unsigned int tag)
@@ -2287,6 +2295,8 @@ static inline void ublk_prep_cancel(struct io_uring_cmd *cmd,
pdu->ubq = ubq;
pdu->tag = tag;
io_uring_cmd_mark_cancelable(cmd, issue_flags);
+ /* pairs with the cancel loading cmd from io->cmd, then cmd->flags */
+ smp_wmb();
}
static void ublk_io_release(void *priv)
@@ -2527,11 +2537,11 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
ret = ublk_check_fetch_buf(ub, addr);
if (ret)
goto out;
+ /* before ublk_fetch() publishes io->cmd, see ublk_prep_cancel() */
+ ublk_prep_cancel(cmd, issue_flags, ubq, tag);
ret = ublk_fetch(cmd, ub, ubq, io, addr);
if (ret)
- goto out;
-
- ublk_prep_cancel(cmd, issue_flags, ubq, tag);
+ goto out_done;
return -EIOCBQUEUED;
}
@@ -2575,6 +2585,7 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
if (ret)
goto out;
io->res = result;
+ ublk_prep_cancel(cmd, issue_flags, ubq, tag);
req = ublk_fill_io_cmd(io, cmd);
ublk_apply_io_buf(ub, io, cmd, addr, &auto_buf, &buf_idx);
if (buf_idx != UBLK_INVALID_BUF_IDX)
@@ -2594,19 +2605,24 @@ static int ublk_ch_uring_cmd_local(struct io_uring_cmd *cmd,
* uring_cmd active first and prepare for handling new requeued
* request
*/
+ ublk_prep_cancel(cmd, issue_flags, ubq, tag);
req = ublk_fill_io_cmd(io, cmd);
io->buf.addr = addr;
if (likely(ublk_get_data(ubq, io, req))) {
__ublk_prep_compl_io_cmd(io, req);
- return UBLK_IO_RES_OK;
+ ret = UBLK_IO_RES_OK;
+ goto out_done;
}
break;
default:
goto out;
}
- ublk_prep_cancel(cmd, issue_flags, ubq, tag);
return -EIOCBQUEUED;
+ out_done:
+ /* marked cancelable: complete through io_uring_cmd_done() */
+ io_uring_cmd_done(cmd, ret, issue_flags);
+ return -EIOCBQUEUED;
out:
pr_devel("%s: complete: cmd op %d, tag %d ret %x io_flags %x\n",
__func__, cmd_op, tag, ret, io ? io->flags : 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 622/686] nvmem: rockchip-otp: alloc clks with main struct
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (620 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 621/686] ublk: mark the io command cancelable before publishing it Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 623/686] nvmem: rockchip-otp: Serialize reads Greg Kroah-Hartman
` (63 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rosen Penev, Srinivas Kandagatla,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rosen Penev <rosenp@gmail.com>
[ Upstream commit 9f99bb979f930e52e6861114fe03535d4bc2f374 ]
Use a flexible array member to simplify allocation slightly. No need for
a separate calloc.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
Signed-off-by: Srinivas Kandagatla <srini@kernel.org>
Link: https://patch.msgid.link/20260530205333.117458-3-srini@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 9fc6a1592d84 ("nvmem: rockchip-otp: Serialize reads")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvmem/rockchip-otp.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
index d88f12c532426..00921b9fe9aae 100644
--- a/drivers/nvmem/rockchip-otp.c
+++ b/drivers/nvmem/rockchip-otp.c
@@ -77,9 +77,9 @@ struct rockchip_data {
struct rockchip_otp {
struct device *dev;
void __iomem *base;
- struct clk_bulk_data *clks;
struct reset_control *rst;
const struct rockchip_data *data;
+ struct clk_bulk_data clks[];
};
static int rockchip_otp_reset(struct rockchip_otp *otp)
@@ -327,7 +327,7 @@ static int rockchip_otp_probe(struct platform_device *pdev)
if (!data)
return dev_err_probe(dev, -EINVAL, "failed to get match data\n");
- otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
+ otp = devm_kzalloc(&pdev->dev, struct_size(otp, clks, data->num_clks),
GFP_KERNEL);
if (!otp)
return -ENOMEM;
@@ -339,11 +339,6 @@ static int rockchip_otp_probe(struct platform_device *pdev)
return dev_err_probe(dev, PTR_ERR(otp->base),
"failed to ioremap resource\n");
- otp->clks = devm_kcalloc(dev, data->num_clks, sizeof(*otp->clks),
- GFP_KERNEL);
- if (!otp->clks)
- return -ENOMEM;
-
for (i = 0; i < data->num_clks; ++i)
otp->clks[i].id = data->clks[i];
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 623/686] nvmem: rockchip-otp: Serialize reads
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (621 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 622/686] nvmem: rockchip-otp: alloc clks with main struct Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 624/686] tpm: tpm2_probe: propagate transport errors Greg Kroah-Hartman
` (62 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miquel Raynal, Alexey Charkov,
Srinivas Kandagatla, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Charkov <alchark@flipper.net>
[ Upstream commit 9fc6a1592d844c0397f115ee8cbd935169b9a71e ]
The OTP controller is driven through a single set of registers holding a
state machine which has to be stepped through for every word read, yet
nothing keeps two readers out of each other's way. Concurrent reads
interleave, and the outcome is either a reader bailing out:
rockchip-otp 2a580000.otp: timeout during read setup
or, worse, one of them silently taking delivery of the other's data.
Reading two cells in parallel from userspace on RK3576 reproduces both
within 150 iterations - 53 read errors and 9 corrupted results, the latter
either losing their first word or, in one case, ending in the two bytes
which belong to the other reader's cell - whereas the same reads issued
sequentially never fail. Concurrency is not hypothetical here, as six
thermal sensors source their trim values from the OTP and reach the driver
straight from asynchronous driver probing.
Guard the read path with a mutex. Reads are the only way into the hardware,
as the driver registers no write callback, and they always run in process
context, so a plain mutex spanning the whole clock-enable, read,
clock-disable sequence is enough.
Fixes: 755864feb729 ("nvmem: add Rockchip OTP driver")
Cc: stable@vger.kernel.org
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
Signed-off-by: Srinivas Kandagatla <srini@kernel.org>
Link: https://patch.msgid.link/20261002101329.1084348-2-srini@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvmem/rockchip-otp.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/nvmem/rockchip-otp.c b/drivers/nvmem/rockchip-otp.c
index 00921b9fe9aae..1475ce11a9c74 100644
--- a/drivers/nvmem/rockchip-otp.c
+++ b/drivers/nvmem/rockchip-otp.c
@@ -12,6 +12,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/nvmem-provider.h>
#include <linux/reset.h>
#include <linux/slab.h>
@@ -79,6 +80,8 @@ struct rockchip_otp {
void __iomem *base;
struct reset_control *rst;
const struct rockchip_data *data;
+ /* Serializes access to the OTP controller state machine */
+ struct mutex mutex;
struct clk_bulk_data clks[];
};
@@ -239,16 +242,21 @@ static int rockchip_otp_read(void *context, unsigned int offset,
if (!otp->data || !otp->data->reg_read)
return -EINVAL;
+ mutex_lock(&otp->mutex);
+
ret = clk_bulk_prepare_enable(otp->data->num_clks, otp->clks);
if (ret < 0) {
dev_err(otp->dev, "failed to prepare/enable clks\n");
- return ret;
+ goto unlock;
}
ret = otp->data->reg_read(context, offset, val, bytes);
clk_bulk_disable_unprepare(otp->data->num_clks, otp->clks);
+unlock:
+ mutex_unlock(&otp->mutex);
+
return ret;
}
@@ -334,6 +342,11 @@ static int rockchip_otp_probe(struct platform_device *pdev)
otp->data = data;
otp->dev = dev;
+
+ ret = devm_mutex_init(dev, &otp->mutex);
+ if (ret)
+ return ret;
+
otp->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(otp->base))
return dev_err_probe(dev, PTR_ERR(otp->base),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 624/686] tpm: tpm2_probe: propagate transport errors
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (622 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 623/686] nvmem: rockchip-otp: Serialize reads Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 625/686] fs: assert on ->i_count in iput_final() Greg Kroah-Hartman
` (61 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Sverdlin, Jarkko Sakkinen,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Sverdlin <alexander.sverdlin@siemens.com>
[ Upstream commit 7d4f1cbfe063af5581dac66abe9e9c965e1031cc ]
tpm2_probe() reads the protocol version from the response tag and is
documented to return -errno on failure, but it always returns 0. A
transport error (tpm_transmit_cmd() < 0) is thus swallowed together with
the intentionally ignored TPM response code, leaving TPM_CHIP_FLAG_TPM2
unset. A transient bus failure on the first command then misdetects a
TPM 2.0 as a 1.2 and the probe fails on the TPM 1.2 path:
tpm_tis_i2c 0-002e: 1.2 TPM (device-id 0x1C, rev-id 22)
tpm tpm0: A TPM error (-62) occurred attempting to determine the timeouts
Return the transport error instead; rc >= 0 still means a valid header was
received and the TPM's own response code is still ignored.
Fixes: 94e266ba1fa3 ("tpm: migrate tpm2_probe() to use struct tpm_buf")
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20261001060114.1582092-1-alexander.sverdlin@siemens.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
[ sashal: Replaced the early return with rc = 0 so explicit tpm_buf_destroy() cleanup still runs. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/char/tpm/tpm2-cmd.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index c5465834396af..85496fc5306b3 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -487,9 +487,10 @@ int tpm2_probe(struct tpm_chip *chip)
out = (struct tpm_header *)buf.data;
if (be16_to_cpu(out->tag) == TPM2_ST_NO_SESSIONS)
chip->flags |= TPM_CHIP_FLAG_TPM2;
+ rc = 0;
}
tpm_buf_destroy(&buf);
- return 0;
+ return rc;
}
EXPORT_SYMBOL_GPL(tpm2_probe);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 625/686] fs: assert on ->i_count in iput_final()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (623 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 624/686] tpm: tpm2_probe: propagate transport errors Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 626/686] fs: add missing fences to I_NEW handling Greg Kroah-Hartman
` (60 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mateusz Guzik, Christian Brauner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mateusz Guzik <mjguzik@gmail.com>
[ Upstream commit be97a4b63ca8c3ed8f5c3f5606a15a8379c78afb ]
Notably make sure the count is 0 after the return from ->drop_inode(),
provided we are going to drop.
Inspired by suspicious games played by f2fs.
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 8ee09f597763 ("fs: rotate inodes whose page cache could not be dropped")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/inode.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/inode.c b/fs/inode.c
index 24762fd1f2f77..acf09822535ed 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1875,6 +1875,7 @@ static void iput_final(struct inode *inode)
int drop;
WARN_ON(inode->i_state & I_NEW);
+ VFS_BUG_ON_INODE(atomic_read(&inode->i_count) != 0, inode);
if (op->drop_inode)
drop = op->drop_inode(inode);
@@ -1889,6 +1890,12 @@ static void iput_final(struct inode *inode)
return;
}
+ /*
+ * Re-check ->i_count in case the ->drop_inode() hooks played games.
+ * Note we only execute this if the verdict was to drop the inode.
+ */
+ VFS_BUG_ON_INODE(atomic_read(&inode->i_count) != 0, inode);
+
state = inode->i_state;
if (!drop) {
WRITE_ONCE(inode->i_state, state | I_WILL_FREE);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 626/686] fs: add missing fences to I_NEW handling
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (624 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 625/686] fs: assert on ->i_count in iput_final() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 627/686] fs: spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb Greg Kroah-Hartman
` (59 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mateusz Guzik, Christian Brauner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mateusz Guzik <mjguzik@gmail.com>
[ Upstream commit 31e332b911fca54df467d264d7e2a2ef9317f3ca ]
Suppose there are 2 CPUs racing inode hash lookup func (say ilookup5())
and unlock_new_inode().
In principle the latter can clear the I_NEW flag before prior stores
into the inode were made visible.
The former can in turn observe I_NEW is cleared and proceed to use the
inode, while possibly reading from not-yet-published areas.
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 8ee09f597763 ("fs: rotate inodes whose page cache could not be dropped")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/dcache.c | 4 ++++
fs/inode.c | 8 ++++++++
include/linux/writeback.h | 4 ++++
3 files changed, 16 insertions(+)
diff --git a/fs/dcache.c b/fs/dcache.c
index 3ad74a3abf9ad..84952f6bbf406 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1995,6 +1995,10 @@ void d_instantiate_new(struct dentry *entry, struct inode *inode)
spin_lock(&inode->i_lock);
__d_instantiate(entry, inode);
WARN_ON(!(inode->i_state & I_NEW));
+ /*
+ * Pairs with smp_rmb in wait_on_inode().
+ */
+ smp_wmb();
inode->i_state &= ~I_NEW & ~I_CREATING;
/*
* Pairs with the barrier in prepare_to_wait_event() to make sure
diff --git a/fs/inode.c b/fs/inode.c
index acf09822535ed..7adfc787e934a 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1177,6 +1177,10 @@ void unlock_new_inode(struct inode *inode)
lockdep_annotate_inode_mutex_key(inode);
spin_lock(&inode->i_lock);
WARN_ON(!(inode->i_state & I_NEW));
+ /*
+ * Pairs with smp_rmb in wait_on_inode().
+ */
+ smp_wmb();
inode->i_state &= ~I_NEW & ~I_CREATING;
/*
* Pairs with the barrier in prepare_to_wait_event() to make sure
@@ -1194,6 +1198,10 @@ void discard_new_inode(struct inode *inode)
lockdep_annotate_inode_mutex_key(inode);
spin_lock(&inode->i_lock);
WARN_ON(!(inode->i_state & I_NEW));
+ /*
+ * Pairs with smp_rmb in wait_on_inode().
+ */
+ smp_wmb();
inode->i_state &= ~I_NEW;
/*
* Pairs with the barrier in prepare_to_wait_event() to make sure
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 22dd4adc5667d..e1e1231a68303 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -194,6 +194,10 @@ static inline void wait_on_inode(struct inode *inode)
{
wait_var_event(inode_state_wait_address(inode, __I_NEW),
!(READ_ONCE(inode->i_state) & I_NEW));
+ /*
+ * Pairs with routines clearing I_NEW.
+ */
+ smp_rmb();
}
#ifdef CONFIG_CGROUP_WRITEBACK
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 627/686] fs: spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (625 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 626/686] fs: add missing fences to I_NEW handling Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 628/686] fs: provide accessors for ->i_state Greg Kroah-Hartman
` (58 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mateusz Guzik, Christian Brauner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mateusz Guzik <mjguzik@gmail.com>
[ Upstream commit cb5db358ab5769cbd3e8e864f14af321126cccdb ]
The incomming helpers don't ship with _release/_acquire variants, for
the time being anyway.
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 8ee09f597763 ("fs: rotate inodes whose page cache could not be dropped")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/fs-writeback.c | 5 +++--
include/linux/backing-dev.h | 5 +++--
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 85f21ecc59958..e479e310f92c6 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -476,10 +476,11 @@ static bool inode_do_switch_wbs(struct inode *inode,
switched = true;
skip_switch:
/*
- * Paired with load_acquire in unlocked_inode_to_wb_begin() and
+ * Paired with an acquire fence in unlocked_inode_to_wb_begin() and
* ensures that the new wb is visible if they see !I_WB_SWITCH.
*/
- smp_store_release(&inode->i_state, inode->i_state & ~I_WB_SWITCH);
+ smp_wmb();
+ inode->i_state &= ~I_WB_SWITCH;
xa_unlock_irq(&mapping->i_pages);
spin_unlock(&inode->i_lock);
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 3e64f14739dd2..065cba5dc111b 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -277,10 +277,11 @@ unlocked_inode_to_wb_begin(struct inode *inode, struct wb_lock_cookie *cookie)
rcu_read_lock();
/*
- * Paired with store_release in inode_switch_wbs_work_fn() and
+ * Paired with a release fence in inode_do_switch_wbs() and
* ensures that we see the new wb if we see cleared I_WB_SWITCH.
*/
- cookie->locked = smp_load_acquire(&inode->i_state) & I_WB_SWITCH;
+ cookie->locked = inode->i_state & I_WB_SWITCH;
+ smp_rmb();
if (unlikely(cookie->locked))
xa_lock_irqsave(&inode->i_mapping->i_pages, cookie->flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 628/686] fs: provide accessors for ->i_state
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (626 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 627/686] fs: spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 629/686] fs: Ignore inode metadata buffers in inode_lru_isolate() Greg Kroah-Hartman
` (57 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mateusz Guzik, Christian Brauner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mateusz Guzik <mjguzik@gmail.com>
[ Upstream commit d8753f788ab4916341d9fab81795be9f2f49c264 ]
Open-coded accesses prevent asserting they are done correctly. One
obvious aspect is locking, but significantly more can checked. For
example it can be detected when the code is clearing flags which are
already missing, or is setting flags when it is illegal (e.g., I_FREEING
when ->i_count > 0).
In order to keep things manageable this patchset merely gets the thing
off the ground with only lockdep checks baked in.
Current consumers can be trivially converted.
Suppose flags I_A and I_B are to be handled.
If ->i_lock is held, then:
state = inode->i_state => state = inode_state_read(inode)
inode->i_state |= (I_A | I_B) => inode_state_set(inode, I_A | I_B)
inode->i_state &= ~(I_A | I_B) => inode_state_clear(inode, I_A | I_B)
inode->i_state = I_A | I_B => inode_state_assign(inode, I_A | I_B)
If ->i_lock is not held or only held conditionally:
state = inode->i_state => state = inode_state_read_once(inode)
inode->i_state |= (I_A | I_B) => inode_state_set_raw(inode, I_A | I_B)
inode->i_state &= ~(I_A | I_B) => inode_state_clear_raw(inode, I_A | I_B)
inode->i_state = I_A | I_B => inode_state_assign_raw(inode, I_A | I_B)
The "_once" vs "_raw" discrepancy stems from the read variant differing
by READ_ONCE as opposed to just lockdep checks.
Finally, if you want to atomically clear flags and set new ones, the
following:
state = inode->i_state;
state &= ~I_A;
state |= I_B;
inode->i_state = state;
turns into:
inode_state_replace(inode, I_A, I_B);
Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 8ee09f597763 ("fs: rotate inodes whose page cache could not be dropped")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/fs.h | 78 ++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 76 insertions(+), 2 deletions(-)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 349b7fc57db36..09cbcfbf295f6 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -759,7 +759,7 @@ enum inode_state_bits {
/* reserved wait address bit 3 */
};
-enum inode_state_flags_t {
+enum inode_state_flags_enum {
I_NEW = (1U << __I_NEW),
I_SYNC = (1U << __I_SYNC),
I_LRU_ISOLATING = (1U << __I_LRU_ISOLATING),
@@ -843,7 +843,7 @@ struct inode {
#endif
/* Misc */
- enum inode_state_flags_t i_state;
+ enum inode_state_flags_enum i_state;
/* 32-bit hole */
struct rw_semaphore i_rwsem;
@@ -904,6 +904,80 @@ struct inode {
void *i_private; /* fs or device private pointer */
} __randomize_layout;
+/*
+ * i_state handling
+ *
+ * We hide all of it behind helpers so that we can validate consumers.
+ */
+static inline enum inode_state_flags_enum inode_state_read_once(struct inode *inode)
+{
+ return READ_ONCE(inode->i_state);
+}
+
+static inline enum inode_state_flags_enum inode_state_read(struct inode *inode)
+{
+ lockdep_assert_held(&inode->i_lock);
+ return inode->i_state;
+}
+
+static inline void inode_state_set_raw(struct inode *inode,
+ enum inode_state_flags_enum flags)
+{
+ WRITE_ONCE(inode->i_state, inode->i_state | flags);
+}
+
+static inline void inode_state_set(struct inode *inode,
+ enum inode_state_flags_enum flags)
+{
+ lockdep_assert_held(&inode->i_lock);
+ inode_state_set_raw(inode, flags);
+}
+
+static inline void inode_state_clear_raw(struct inode *inode,
+ enum inode_state_flags_enum flags)
+{
+ WRITE_ONCE(inode->i_state, inode->i_state & ~flags);
+}
+
+static inline void inode_state_clear(struct inode *inode,
+ enum inode_state_flags_enum flags)
+{
+ lockdep_assert_held(&inode->i_lock);
+ inode_state_clear_raw(inode, flags);
+}
+
+static inline void inode_state_assign_raw(struct inode *inode,
+ enum inode_state_flags_enum flags)
+{
+ WRITE_ONCE(inode->i_state, flags);
+}
+
+static inline void inode_state_assign(struct inode *inode,
+ enum inode_state_flags_enum flags)
+{
+ lockdep_assert_held(&inode->i_lock);
+ inode_state_assign_raw(inode, flags);
+}
+
+static inline void inode_state_replace_raw(struct inode *inode,
+ enum inode_state_flags_enum clearflags,
+ enum inode_state_flags_enum setflags)
+{
+ enum inode_state_flags_enum flags;
+ flags = inode->i_state;
+ flags &= ~clearflags;
+ flags |= setflags;
+ inode_state_assign_raw(inode, flags);
+}
+
+static inline void inode_state_replace(struct inode *inode,
+ enum inode_state_flags_enum clearflags,
+ enum inode_state_flags_enum setflags)
+{
+ lockdep_assert_held(&inode->i_lock);
+ inode_state_replace_raw(inode, clearflags, setflags);
+}
+
static inline void inode_set_cached_link(struct inode *inode, char *link, int linklen)
{
VFS_WARN_ON_INODE(strlen(link) != linklen, inode);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 629/686] fs: Ignore inode metadata buffers in inode_lru_isolate()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (627 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 628/686] fs: provide accessors for ->i_state Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 630/686] fs: rotate inodes whose page cache could not be dropped Greg Kroah-Hartman
` (56 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jan Kara, syzbot, Christian Brauner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
[ Upstream commit 972b9dd4e4180fbb2352bf2f0e015b7b63f5cca0 ]
There are only a few filesystems that use generic tracking of inode
metadata buffer heads. As such the logic to reclaim tracked metadata
buffer heads in inode_lru_isolate() doesn't bring a benefit big enough
to justify intertwining of inode reclaim and metadata buffer head
tracking. Just treat tracked metadata buffer heads as any other metadata
filesystem has to properly clean up on inode eviction and stop handling
it in inode_lru_isolate(). As a result filesystems using generic
tracking of metadata buffer heads may now see dirty metadata buffers in
their .evict methods more often which can slow down inode reclaim but
given these filesystems aren't used in performance demanding setups we
should be fine.
Signed-off-by: Jan Kara <jack@suse.cz>
Link: https://patch.msgid.link/20260326095354.16340-64-jack@suse.cz
Tested-by: syzbot@syzkaller.appspotmail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>
Stable-dep-of: 8ee09f597763 ("fs: rotate inodes whose page cache could not be dropped")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/buffer.c | 29 -----------------------------
fs/inode.c | 21 +++++++++------------
include/linux/buffer_head.h | 3 ---
3 files changed, 9 insertions(+), 44 deletions(-)
diff --git a/fs/buffer.c b/fs/buffer.c
index 261f521dbc583..b5a1ff2d559fb 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -880,35 +880,6 @@ void invalidate_inode_buffers(struct inode *inode)
}
EXPORT_SYMBOL(invalidate_inode_buffers);
-/*
- * Remove any clean buffers from the inode's buffer list. This is called
- * when we're trying to free the inode itself. Those buffers can pin it.
- *
- * Returns true if all buffers were removed.
- */
-int remove_inode_buffers(struct inode *inode)
-{
- int ret = 1;
-
- if (inode_has_buffers(inode)) {
- struct address_space *mapping = &inode->i_data;
- struct list_head *list = &mapping->i_private_list;
- struct address_space *buffer_mapping = mapping->i_private_data;
-
- spin_lock(&buffer_mapping->i_private_lock);
- while (!list_empty(list)) {
- struct buffer_head *bh = BH_ENTRY(list->next);
- if (buffer_dirty(bh)) {
- ret = 0;
- break;
- }
- __remove_assoc_queue(bh);
- }
- spin_unlock(&buffer_mapping->i_private_lock);
- }
- return ret;
-}
-
/*
* Create the appropriate buffers when given a folio for data area and
* the size of each buffer.. Use the bh->b_this_page linked list to
diff --git a/fs/inode.c b/fs/inode.c
index 7adfc787e934a..ec58d248a7ed9 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -16,7 +16,6 @@
#include <linux/fsnotify.h>
#include <linux/mount.h>
#include <linux/posix_acl.h>
-#include <linux/buffer_head.h> /* for inode_has_buffers */
#include <linux/ratelimit.h>
#include <linux/list_lru.h>
#include <linux/iversion.h>
@@ -366,7 +365,6 @@ struct inode *alloc_inode(struct super_block *sb)
void __destroy_inode(struct inode *inode)
{
- BUG_ON(inode_has_buffers(inode));
inode_detach_wb(inode);
security_inode_free(inode);
fsnotify_inode_delete(inode);
@@ -954,19 +952,18 @@ static enum lru_status inode_lru_isolate(struct list_head *item,
* page cache in order to free up struct inodes: lowmem might
* be under pressure before the cache inside the highmem zone.
*/
- if (inode_has_buffers(inode) || !mapping_empty(&inode->i_data)) {
+ if (!mapping_empty(&inode->i_data)) {
+ unsigned long reap;
+
inode_pin_lru_isolating(inode);
spin_unlock(&inode->i_lock);
spin_unlock(&lru->lock);
- if (remove_inode_buffers(inode)) {
- unsigned long reap;
- reap = invalidate_mapping_pages(&inode->i_data, 0, -1);
- if (current_is_kswapd())
- __count_vm_events(KSWAPD_INODESTEAL, reap);
- else
- __count_vm_events(PGINODESTEAL, reap);
- mm_account_reclaimed_pages(reap);
- }
+ reap = invalidate_mapping_pages(&inode->i_data, 0, -1);
+ if (current_is_kswapd())
+ __count_vm_events(KSWAPD_INODESTEAL, reap);
+ else
+ __count_vm_events(PGINODESTEAL, reap);
+ mm_account_reclaimed_pages(reap);
inode_unpin_lru_isolating(inode);
return LRU_RETRY;
}
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index b16b88bfbc3e7..631bf971efc04 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -517,7 +517,6 @@ void buffer_init(void);
bool try_to_free_buffers(struct folio *folio);
int inode_has_buffers(struct inode *inode);
void invalidate_inode_buffers(struct inode *inode);
-int remove_inode_buffers(struct inode *inode);
int sync_mapping_buffers(struct address_space *mapping);
void invalidate_bh_lrus(void);
void invalidate_bh_lrus_cpu(void);
@@ -528,9 +527,7 @@ extern int buffer_heads_over_limit;
static inline void buffer_init(void) {}
static inline bool try_to_free_buffers(struct folio *folio) { return true; }
-static inline int inode_has_buffers(struct inode *inode) { return 0; }
static inline void invalidate_inode_buffers(struct inode *inode) {}
-static inline int remove_inode_buffers(struct inode *inode) { return 1; }
static inline int sync_mapping_buffers(struct address_space *mapping) { return 0; }
static inline void invalidate_bh_lrus(void) {}
static inline void invalidate_bh_lrus_cpu(void) {}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 630/686] fs: rotate inodes whose page cache could not be dropped
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (628 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 629/686] fs: Ignore inode metadata buffers in inode_lru_isolate() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 631/686] mm: memcontrol: refactor mod_memcg_state() and mod_memcg_lruvec_state() Greg Kroah-Hartman
` (55 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikolaos Karaolidis, Jan Kara,
Zhihao Cheng, Christian Brauner (Amutable), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolaos Karaolidis <nick@karaolidis.com>
[ Upstream commit 8ee09f597763acfd31c62a578ba88b792fc41b24 ]
When inode_lru_isolate() drops the page cache of an unused inode, it
has to unlock the list, so it returns LRU_RETRY and the walk restarts
at the head of the list, where the inode still is. If
invalidate_mapping_pages() could not empty the mapping, the restarted
walk strips the same inode again, and so on until nr_to_walk runs out.
Every walk of that list then ends on this inode, and nothing behind it
is reclaimed for as long as its cache stays.
Before commit 2a0629834cd8 ("vfs: Don't evict inode under the inode lru
traversing context") the walker pinned the inode with a reference, and
dropping it in iput_final() set I_REFERENCED, so the restarted walk
rotated the inode to the tail. Set I_REFERENCED again when the mapping
is still populated after the invalidation, in the same i_lock section
that clears I_LRU_ISOLATING. inode_unpin_lru_isolating() now expects
i_lock to be held, like inode_pin_lru_isolating().
On CONFIG_HIGHMEM kernels this can happen to any unused inode: a folio
is left behind if it is locked, under writeback, spliced into a pipe,
or still in another CPU's LRU-add batch after being read. Without
HIGHMEM it happens to DAX inodes whose only entry is at index 0, which
mapping_shrinkable() lets onto the LRU and invalidate_mapping_pages()
never removes.
Fixes: 2a0629834cd8 ("vfs: Don't evict inode under the inode lru traversing context")
Cc: stable@vger.kernel.org
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
Link: https://patch.msgid.link/20261016102515.111285-1-nick@karaolidis.com
Reviewed-by: Jan Kara <jack@suse.cz>
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: Adjusted context for direct i_state accesses in inode_unpin_lru_isolating() where upstream uses inode state accessors. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/inode.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/inode.c b/fs/inode.c
index ec58d248a7ed9..229ac6ff72cb9 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -581,12 +581,11 @@ static void inode_pin_lru_isolating(struct inode *inode)
static void inode_unpin_lru_isolating(struct inode *inode)
{
- spin_lock(&inode->i_lock);
+ lockdep_assert_held(&inode->i_lock);
WARN_ON(!(inode->i_state & I_LRU_ISOLATING));
inode->i_state &= ~I_LRU_ISOLATING;
/* Called with inode->i_lock which ensures memory ordering. */
inode_wake_up_bit(inode, __I_LRU_ISOLATING);
- spin_unlock(&inode->i_lock);
}
static void inode_wait_for_lru_isolating(struct inode *inode)
@@ -964,7 +963,13 @@ static enum lru_status inode_lru_isolate(struct list_head *item,
else
__count_vm_events(PGINODESTEAL, reap);
mm_account_reclaimed_pages(reap);
+
+ spin_lock(&inode->i_lock);
+ /* The walk restarts here: don't retry leftovers right away */
+ if (!mapping_empty(&inode->i_data))
+ inode_state_set(inode, I_REFERENCED);
inode_unpin_lru_isolating(inode);
+ spin_unlock(&inode->i_lock);
return LRU_RETRY;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 631/686] mm: memcontrol: refactor mod_memcg_state() and mod_memcg_lruvec_state()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (629 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 630/686] fs: rotate inodes whose page cache could not be dropped Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 632/686] mm: use enum migrate_reason instead of int for migration reason parameters Greg Kroah-Hartman
` (54 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yosry Ahmed, Qi Zheng, Shakeel Butt,
Allen Pais, Axel Rasmussen, Baoquan He, Chengming Zhou,
Chen Ridong, David Hildenbrand, Hamza Mahfooz, Harry Yoo,
Hugh Dickins, Imran Khan, Johannes Weiner, Kamalesh Babulal,
Lance Yang, Liam Howlett, Lorenzo Stoakes (Oracle), Michal Hocko,
Michal Koutný, Mike Rapoport, Muchun Song, Muchun Song,
Nhat Pham, Roman Gushchin, Suren Baghdasaryan, Usama Arif,
Vlastimil Babka, Wei Xu, Yuanchu Xie, Zi Yan, Andrew Morton,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Zheng <zhengqi.arch@bytedance.com>
[ Upstream commit 5371e350fda70bbdbee364215ca37b7fea25047b ]
Refactor the memcg_reparent_objcgs() to facilitate subsequent reparenting
non-hierarchical stats.
Link: https://lore.kernel.org/7f8bd3aacec2270b9453428fc8585cca9f10751e.1772711148.git.zhengqi.arch@bytedance.com
Co-developed-by: Yosry Ahmed <yosry@kernel.org>
Signed-off-by: Yosry Ahmed <yosry@kernel.org>
Signed-off-by: Qi Zheng <zhengqi.arch@bytedance.com>
Acked-by: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Allen Pais <apais@linux.microsoft.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Baoquan He <bhe@redhat.com>
Cc: Chengming Zhou <chengming.zhou@linux.dev>
Cc: Chen Ridong <chenridong@huawei.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com>
Cc: Harry Yoo <harry.yoo@oracle.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Imran Khan <imran.f.khan@oracle.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Kamalesh Babulal <kamalesh.babulal@oracle.com>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Liam Howlett <Liam.Howlett@oracle.com>
Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Michal Koutný <mkoutny@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Muchun Song <songmuchun@bytedance.com>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Usama Arif <usamaarif642@gmail.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Wei Xu <weixugc@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Zi Yan <ziy@nvidia.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 02e0c8cc2815 ("mm/memcg: migrate per-node hugetlb lruvec stat together with hugetlb folio")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memcontrol.c | 50 ++++++++++++++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 19 deletions(-)
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index db12e61ee9852..371bbfc419170 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -678,21 +678,12 @@ static int memcg_state_val_in_pages(int idx, int val)
return max(val * unit / PAGE_SIZE, 1UL);
}
-/**
- * mod_memcg_state - update cgroup memory statistics
- * @memcg: the memory cgroup
- * @idx: the stat item - can be enum memcg_stat_item or enum node_stat_item
- * @val: delta to add to the counter, can be negative
- */
-void mod_memcg_state(struct mem_cgroup *memcg, enum memcg_stat_item idx,
- int val)
+static void __mod_memcg_state(struct mem_cgroup *memcg,
+ enum memcg_stat_item idx, int val)
{
int i = memcg_stats_index(idx);
int cpu;
- if (mem_cgroup_disabled())
- return;
-
if (WARN_ONCE(BAD_STAT_IDX(i), "%s: missing stat item %d\n", __func__, idx))
return;
@@ -706,6 +697,21 @@ void mod_memcg_state(struct mem_cgroup *memcg, enum memcg_stat_item idx,
put_cpu();
}
+/**
+ * mod_memcg_state - update cgroup memory statistics
+ * @memcg: the memory cgroup
+ * @idx: the stat item - can be enum memcg_stat_item or enum node_stat_item
+ * @val: delta to add to the counter, can be negative
+ */
+void mod_memcg_state(struct mem_cgroup *memcg, enum memcg_stat_item idx,
+ int val)
+{
+ if (mem_cgroup_disabled())
+ return;
+
+ __mod_memcg_state(memcg, idx, val);
+}
+
#ifdef CONFIG_MEMCG_V1
/* idx can be of type enum memcg_stat_item or node_stat_item. */
unsigned long memcg_page_state_local(struct mem_cgroup *memcg, int idx)
@@ -725,21 +731,16 @@ unsigned long memcg_page_state_local(struct mem_cgroup *memcg, int idx)
}
#endif
-static void mod_memcg_lruvec_state(struct lruvec *lruvec,
- enum node_stat_item idx,
- int val)
+static void __mod_memcg_lruvec_state(struct mem_cgroup_per_node *pn,
+ enum node_stat_item idx, int val)
{
- struct mem_cgroup_per_node *pn;
- struct mem_cgroup *memcg;
+ struct mem_cgroup *memcg = pn->memcg;
int i = memcg_stats_index(idx);
int cpu;
if (WARN_ONCE(BAD_STAT_IDX(i), "%s: missing stat item %d\n", __func__, idx))
return;
- pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
- memcg = pn->memcg;
-
cpu = get_cpu();
/* Update memcg */
@@ -755,6 +756,17 @@ static void mod_memcg_lruvec_state(struct lruvec *lruvec,
put_cpu();
}
+static void mod_memcg_lruvec_state(struct lruvec *lruvec,
+ enum node_stat_item idx,
+ int val)
+{
+ struct mem_cgroup_per_node *pn;
+
+ pn = container_of(lruvec, struct mem_cgroup_per_node, lruvec);
+
+ __mod_memcg_lruvec_state(pn, idx, val);
+}
+
/**
* __mod_lruvec_state - update lruvec memory statistics
* @lruvec: the lruvec
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 632/686] mm: use enum migrate_reason instead of int for migration reason parameters
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (630 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 631/686] mm: memcontrol: refactor mod_memcg_state() and mod_memcg_lruvec_state() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 633/686] mm/memcg: migrate per-node hugetlb lruvec stat together with hugetlb folio Greg Kroah-Hartman
` (53 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ye Liu, Zi Yan,
Vlastimil Babka (SUSE), Lorenzo Stoakes, David Hildenbrand (Arm),
Brendan Jackman, Johannes Weiner, Michal Hocko,
Suren Baghdasaryan, Andrew Morton, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Liu <ye.liu@linux.dev>
[ Upstream commit c95dc0a84b4c84103bd688a93b28d84e8b752568 ]
Replace all 'int reason' function parameters that carry migrate_reason
values with the proper 'enum migrate_reason' type. This makes the intent
explicit and leverages compiler type checking. The affected subsystems
are:
- page_owner: __folio_set_owner_migrate_reason(),
folio_set_owner_migrate_reason()
- migrate: migrate_pages(), migrate_pages_sync(),
migrate_pages_batch(), migrate_folios_move(),
migrate_hugetlbs(), unmap_and_move_huge_page()
- hugetlb: move_hugetlb_state(), htlb_allow_alloc_fallback()
- trace: mm_migrate_pages and mm_migrate_pages_start events
The 'short last_migrate_reason' struct field and internal helper parameter
in page_owner are intentionally left as 'short' since they store per-page
metadata where size matters.
No functional change.
Link: https://lore.kernel.org/20260714015117.78351-4-ye.liu@linux.dev
Signed-off-by: Ye Liu <ye.liu@linux.dev>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Reviewed-by: Lorenzo Stoakes <ljs@kernel.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 02e0c8cc2815 ("mm/memcg: migrate per-node hugetlb lruvec stat together with hugetlb folio")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/hugetlb.h | 9 +++++----
include/linux/migrate.h | 8 +++++---
include/linux/page_owner.h | 7 ++++---
include/trace/events/migrate.h | 8 ++++----
mm/hugetlb.c | 3 ++-
mm/migrate.c | 12 ++++++------
mm/page_owner.c | 2 +-
7 files changed, 27 insertions(+), 22 deletions(-)
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index d43965f4b6c82..f7a98fc53bafd 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -156,7 +156,8 @@ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
bool folio_isolate_hugetlb(struct folio *folio, struct list_head *list);
int get_hwpoison_hugetlb_folio(struct folio *folio, bool *hugetlb, bool unpoison);
void folio_putback_hugetlb(struct folio *folio);
-void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int reason);
+void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio,
+ enum migrate_reason reason);
void hugetlb_fix_reserve_counts(struct inode *inode);
extern struct mutex *hugetlb_fault_mutex_table;
u32 hugetlb_fault_mutex_hash(struct address_space *mapping, pgoff_t idx);
@@ -425,7 +426,7 @@ static inline void folio_putback_hugetlb(struct folio *folio)
}
static inline void move_hugetlb_state(struct folio *old_folio,
- struct folio *new_folio, int reason)
+ struct folio *new_folio, enum migrate_reason reason)
{
}
@@ -960,7 +961,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)
return modified_mask;
}
-static inline bool htlb_allow_alloc_fallback(int reason)
+static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason)
{
bool allowed_fallback = false;
@@ -1252,7 +1253,7 @@ static inline gfp_t htlb_modify_alloc_mask(struct hstate *h, gfp_t gfp_mask)
return 0;
}
-static inline bool htlb_allow_alloc_fallback(int reason)
+static inline bool htlb_allow_alloc_fallback(enum migrate_reason reason)
{
return false;
}
diff --git a/include/linux/migrate.h b/include/linux/migrate.h
index 8061efd89041e..4ce64a3e77f49 100644
--- a/include/linux/migrate.h
+++ b/include/linux/migrate.h
@@ -57,8 +57,9 @@ void putback_movable_pages(struct list_head *l);
int migrate_folio(struct address_space *mapping, struct folio *dst,
struct folio *src, enum migrate_mode mode);
int migrate_pages(struct list_head *l, new_folio_t new, free_folio_t free,
- unsigned long private, enum migrate_mode mode, int reason,
- unsigned int *ret_succeeded);
+ unsigned long private, enum migrate_mode mode,
+ enum migrate_reason reason,
+ unsigned int *ret_succeeded);
struct folio *alloc_migration_target(struct folio *src, unsigned long private);
bool isolate_movable_ops_page(struct page *page, isolate_mode_t mode);
bool isolate_folio_to_list(struct folio *folio, struct list_head *list);
@@ -77,7 +78,8 @@ int set_movable_ops(const struct movable_operations *ops, enum pagetype type);
static inline void putback_movable_pages(struct list_head *l) {}
static inline int migrate_pages(struct list_head *l, new_folio_t new,
free_folio_t free, unsigned long private,
- enum migrate_mode mode, int reason, unsigned int *ret_succeeded)
+ enum migrate_mode mode, enum migrate_reason reason,
+ unsigned int *ret_succeeded)
{ return -ENOSYS; }
static inline struct folio *alloc_migration_target(struct folio *src,
unsigned long private)
diff --git a/include/linux/page_owner.h b/include/linux/page_owner.h
index 3328357f6dba7..8188ddc5c4127 100644
--- a/include/linux/page_owner.h
+++ b/include/linux/page_owner.h
@@ -3,6 +3,7 @@
#define __LINUX_PAGE_OWNER_H
#include <linux/jump_label.h>
+#include <linux/migrate_mode.h>
#ifdef CONFIG_PAGE_OWNER
extern struct static_key_false page_owner_inited;
@@ -14,7 +15,7 @@ extern void __set_page_owner(struct page *page,
extern void __split_page_owner(struct page *page, int old_order,
int new_order);
extern void __folio_copy_owner(struct folio *newfolio, struct folio *old);
-extern void __folio_set_owner_migrate_reason(struct folio *folio, int reason);
+void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason);
extern void __dump_page_owner(const struct page *page);
extern void pagetypeinfo_showmixedcount_print(struct seq_file *m,
pg_data_t *pgdat, struct zone *zone);
@@ -43,7 +44,7 @@ static inline void folio_copy_owner(struct folio *newfolio, struct folio *old)
if (static_branch_unlikely(&page_owner_inited))
__folio_copy_owner(newfolio, old);
}
-static inline void folio_set_owner_migrate_reason(struct folio *folio, int reason)
+static inline void folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason)
{
if (static_branch_unlikely(&page_owner_inited))
__folio_set_owner_migrate_reason(folio, reason);
@@ -68,7 +69,7 @@ static inline void split_page_owner(struct page *page, int old_order,
static inline void folio_copy_owner(struct folio *newfolio, struct folio *folio)
{
}
-static inline void folio_set_owner_migrate_reason(struct folio *folio, int reason)
+static inline void folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason)
{
}
static inline void dump_page_owner(const struct page *page)
diff --git a/include/trace/events/migrate.h b/include/trace/events/migrate.h
index cd01dd7b3640d..8869f1fe3b98c 100644
--- a/include/trace/events/migrate.h
+++ b/include/trace/events/migrate.h
@@ -51,7 +51,7 @@ TRACE_EVENT(mm_migrate_pages,
TP_PROTO(unsigned long succeeded, unsigned long failed,
unsigned long thp_succeeded, unsigned long thp_failed,
unsigned long thp_split, unsigned long large_folio_split,
- enum migrate_mode mode, int reason),
+ enum migrate_mode mode, enum migrate_reason reason),
TP_ARGS(succeeded, failed, thp_succeeded, thp_failed,
thp_split, large_folio_split, mode, reason),
@@ -64,7 +64,7 @@ TRACE_EVENT(mm_migrate_pages,
__field( unsigned long, thp_split)
__field( unsigned long, large_folio_split)
__field( enum migrate_mode, mode)
- __field( int, reason)
+ __field( enum migrate_reason, reason)
),
TP_fast_assign(
@@ -91,13 +91,13 @@ TRACE_EVENT(mm_migrate_pages,
TRACE_EVENT(mm_migrate_pages_start,
- TP_PROTO(enum migrate_mode mode, int reason),
+ TP_PROTO(enum migrate_mode mode, enum migrate_reason reason),
TP_ARGS(mode, reason),
TP_STRUCT__entry(
__field(enum migrate_mode, mode)
- __field(int, reason)
+ __field(enum migrate_reason, reason)
),
TP_fast_assign(
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index 225c04d583adc..ca9f13ea3671b 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -7970,7 +7970,8 @@ void folio_putback_hugetlb(struct folio *folio)
folio_put(folio);
}
-void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio, int reason)
+void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio,
+ enum migrate_reason reason)
{
struct hstate *h = folio_hstate(old_folio);
diff --git a/mm/migrate.c b/mm/migrate.c
index 2a5846a86baf8..98d3c9c789f0c 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -1465,7 +1465,7 @@ static int migrate_folio_move(free_folio_t put_new_folio, unsigned long private,
static int unmap_and_move_huge_page(new_folio_t get_new_folio,
free_folio_t put_new_folio, unsigned long private,
struct folio *src, int force, enum migrate_mode mode,
- int reason, struct list_head *ret)
+ enum migrate_reason reason, struct list_head *ret)
{
struct folio *dst;
int rc = -EAGAIN;
@@ -1622,7 +1622,7 @@ struct migrate_pages_stats {
*/
static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,
free_folio_t put_new_folio, unsigned long private,
- enum migrate_mode mode, int reason,
+ enum migrate_mode mode, enum migrate_reason reason,
struct migrate_pages_stats *stats,
struct list_head *ret_folios)
{
@@ -1712,7 +1712,7 @@ static int migrate_hugetlbs(struct list_head *from, new_folio_t get_new_folio,
static void migrate_folios_move(struct list_head *src_folios,
struct list_head *dst_folios,
free_folio_t put_new_folio, unsigned long private,
- enum migrate_mode mode, int reason,
+ enum migrate_mode mode, enum migrate_reason reason,
struct list_head *ret_folios,
struct migrate_pages_stats *stats,
int *retry, int *thp_retry, int *nr_failed,
@@ -1795,7 +1795,7 @@ static void migrate_folios_undo(struct list_head *src_folios,
*/
static int migrate_pages_batch(struct list_head *from,
new_folio_t get_new_folio, free_folio_t put_new_folio,
- unsigned long private, enum migrate_mode mode, int reason,
+ unsigned long private, enum migrate_mode mode, enum migrate_reason reason,
struct list_head *ret_folios, struct list_head *split_folios,
struct migrate_pages_stats *stats, int nr_pass)
{
@@ -2007,7 +2007,7 @@ static int migrate_pages_batch(struct list_head *from,
static int migrate_pages_sync(struct list_head *from, new_folio_t get_new_folio,
free_folio_t put_new_folio, unsigned long private,
- enum migrate_mode mode, int reason,
+ enum migrate_mode mode, enum migrate_reason reason,
struct list_head *ret_folios, struct list_head *split_folios,
struct migrate_pages_stats *stats)
{
@@ -2084,7 +2084,7 @@ static int migrate_pages_sync(struct list_head *from, new_folio_t get_new_folio,
*/
int migrate_pages(struct list_head *from, new_folio_t get_new_folio,
free_folio_t put_new_folio, unsigned long private,
- enum migrate_mode mode, int reason, unsigned int *ret_succeeded)
+ enum migrate_mode mode, enum migrate_reason reason, unsigned int *ret_succeeded)
{
int rc, rc_gather;
int nr_pages;
diff --git a/mm/page_owner.c b/mm/page_owner.c
index 589ec37c94aab..4862fc52c5ec8 100644
--- a/mm/page_owner.c
+++ b/mm/page_owner.c
@@ -336,7 +336,7 @@ noinline void __set_page_owner(struct page *page, unsigned short order,
inc_stack_record_count(handle, gfp_mask, 1 << order);
}
-void __folio_set_owner_migrate_reason(struct folio *folio, int reason)
+void __folio_set_owner_migrate_reason(struct folio *folio, enum migrate_reason reason)
{
struct page_ext *page_ext = page_ext_get(&folio->page);
struct page_owner *page_owner;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 633/686] mm/memcg: migrate per-node hugetlb lruvec stat together with hugetlb folio
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (631 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 632/686] mm: use enum migrate_reason instead of int for migration reason parameters Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 634/686] mm/vma: dont leak the commit charge on mmap failure Greg Kroah-Hartman
` (52 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hongfu Li, Andrew Morton,
Joshua Hahn, Oscar Salvador, Muchun Song, David Hildenbrand,
Shakeel Butt, Michal Hocko, Johannes Weiner, Nhat Pham,
Michal Hocko, Roman Gushchin, Chris Down, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongfu Li <lihongfu@kylinos.cn>
[ Upstream commit 02e0c8cc2815f0082b5b5aabafe3b46688082adc ]
memory.numa_stat exposes per-node hugetlb counters from per-node lruvec
stats. These stats are accounted against folio_nid(): incremented on the
folio's node when handed to a user, decremented when the folio is returned
to the pool.
During hugetlb folio migration, mem_cgroup_migrate() moves the charge to
the new folio and drops the memcg data of the old one, so the free of the
old folio right after the migration skips the memcg per-node lruvec
decrement. The hugetlb count stays attributed to the old node for the
rest of the life of the charge, while the target folio gets no increment
on the new node; its later free decrements a counter that was never
incremented.
Migrate the per-node lruvec accounting alongside migration. Global memcg
totals remain balanced because they track resource consumption, not node
placement.
Link: https://lore.kernel.org/20260923-for-hugetlb_state3-v2-2-e8a36245bfab@kylinos.cn
Fixes: 05d4532b60e3 ("memcg/hugetlb: add hugeTLB counters to memcg")
Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Tested-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Reviewed-by: Joshua Hahn <joshua.hahnjy@gmail.com>
Reviewed-by: Oscar Salvador <osalvador@suse.de>
Acked-by: Muchun Song <muchun.song@linux.dev>
Cc: David Hildenbrand <david@kernel.org>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Chris Down <chris@chrisdown.name>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/memcontrol.h | 8 ++++++++
mm/hugetlb.c | 25 +++++++++++++++++++++++++
mm/memcontrol.c | 5 ++---
3 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index b14bfce896d20..2df30cce143de 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -953,6 +953,9 @@ unsigned long lruvec_page_state(struct lruvec *lruvec, enum node_stat_item idx);
unsigned long lruvec_page_state_local(struct lruvec *lruvec,
enum node_stat_item idx);
+void mod_memcg_lruvec_state(struct lruvec *lruvec,
+ enum node_stat_item idx, int val);
+
void mem_cgroup_flush_stats(struct mem_cgroup *memcg);
void mem_cgroup_flush_stats_ratelimited(struct mem_cgroup *memcg);
@@ -1422,6 +1425,11 @@ static inline unsigned long lruvec_page_state_local(struct lruvec *lruvec,
return node_page_state(lruvec_pgdat(lruvec), idx);
}
+static inline void mod_memcg_lruvec_state(struct lruvec *lruvec,
+ enum node_stat_item idx, int val)
+{
+}
+
static inline void mem_cgroup_flush_stats(struct mem_cgroup *memcg)
{
}
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index ca9f13ea3671b..fad8c38ab4da6 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -25,6 +25,7 @@
#include <linux/mmdebug.h>
#include <linux/sched/signal.h>
#include <linux/rmap.h>
+#include <linux/rcupdate.h>
#include <linux/string_choices.h>
#include <linux/string_helpers.h>
#include <linux/swap.h>
@@ -7970,12 +7971,36 @@ void folio_putback_hugetlb(struct folio *folio)
folio_put(folio);
}
+static void move_hugetlb_lruvec_stat(struct folio *old_folio,
+ struct folio *new_folio)
+{
+ struct mem_cgroup *memcg;
+ long nr_pages = folio_nr_pages(old_folio);
+ int old_nid = folio_nid(old_folio);
+ int new_nid = folio_nid(new_folio);
+
+ if (old_nid == new_nid)
+ return;
+
+ guard(rcu)();
+
+ memcg = folio_memcg(new_folio);
+ if (!memcg)
+ return;
+
+ mod_memcg_lruvec_state(mem_cgroup_lruvec(memcg, NODE_DATA(old_nid)),
+ NR_HUGETLB, -nr_pages);
+ mod_memcg_lruvec_state(mem_cgroup_lruvec(memcg, NODE_DATA(new_nid)),
+ NR_HUGETLB, nr_pages);
+}
+
void move_hugetlb_state(struct folio *old_folio, struct folio *new_folio,
enum migrate_reason reason)
{
struct hstate *h = folio_hstate(old_folio);
hugetlb_cgroup_migrate(old_folio, new_folio);
+ move_hugetlb_lruvec_stat(old_folio, new_folio);
folio_set_owner_migrate_reason(new_folio, reason);
/*
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 371bbfc419170..61092a05f108e 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -756,9 +756,8 @@ static void __mod_memcg_lruvec_state(struct mem_cgroup_per_node *pn,
put_cpu();
}
-static void mod_memcg_lruvec_state(struct lruvec *lruvec,
- enum node_stat_item idx,
- int val)
+void mod_memcg_lruvec_state(struct lruvec *lruvec,
+ enum node_stat_item idx, int val)
{
struct mem_cgroup_per_node *pn;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 634/686] mm/vma: dont leak the commit charge on mmap failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (632 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 633/686] mm/memcg: migrate per-node hugetlb lruvec stat together with hugetlb folio Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 635/686] mm/hugetlb: charge folios to the target mms memcg Greg Kroah-Hartman
` (51 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik, David Hildenbrand (Arm),
Andrew Morton, Lorenzo Stoakes (ARM), Pedro Falcato,
Jose A. Perez de Azpillaga, Lance Yang, Liam R. Howlett,
Vlastimil Babka, Jann Horn, Muchun Song, Oscar Salvador,
Miaohe Lin, Naoya Horiguchi, Adam Litke, Mel Gorman, Rik van Riel,
Peter Xu, Kiryl Shutsemau, Mike Rapoport, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <josef@toxicpanda.com>
[ Upstream commit aa09311c40f6d3aa6037065e17d257ffa48b9402 ]
Patch series "mm: various (urgent?) fixes", v1.
Here are various MM fixes. The majority was reported by Josef at
Anthrophic, the remainder was found while reviewing/overhauling them.
Two issues/fixes reported are not included, as we are discussing
(better) alternatives on the list already.
I left most of the original commit messages as schloppy as they are: I
don't particularly care as long as the code is in good shape and as long
as they are not actively wrong. But I (and Mike) could not be stopped
from overhauling at least some of them.
While I don't think there is anything too critical in here, I think this
is a good opportunity to see how fast we can get pre-screened/pre-reviewed
fixes upstream that might be security-related.
The majority are hugetlb + uffd issues, that are not actually that
relevant for most installations. But all things that should just get
fixed. Some uffd fixes need proper follow ups to fix some more of the
root causes of leftover UFFD PTE bits (or proof that there are none
remaining).
This patch (of 10):
When an accountable mapping replaces existing mappings (MAP_FIXED),
__mmap_setup() only charges the difference between the size of the new
mapping and the VM_ACCOUNT pages it replaces. It then zeroes
vms->nr_accounted so that unmapping the old VMAs does not return their
charge, which now backs the new mapping.
If the operation fails after that point, the error path returns
map->charged, i.e. only the difference. By then vms_clean_up_area() has
zapped the page tables and closed the old VMAs, so
vms_abort_munmap_vmas() cannot reattach them. It leaves a gap and
finishes the unmap with vms_complete_munmap_vmas(), which uncharges
vms->nr_accounted == 0 pages. The old VMAs are gone, the new one was
never created, and the charge of the old ones is never returned, not
even when the process exits.
No privilege is needed to hit this, only a file whose mmap hook fails,
for example a socket (sock_no_mmap() returns -ENODEV):
p = mmap(NULL, len, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
mmap(p, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED,
socket_fd, 0);
Every iteration adds len to Committed_AS for good. With
vm.overcommit_memory=2 this lets any user make all further accountable
allocations in the system fail with -ENOMEM.
Once the new mapping has taken over the charge of the mappings it
replaces, it owns the charge for all of its pages. Record that in
map->charged, so that the error path returns all of it.
A failure in __mmap_setup() itself is not affected: it happens before
the charge is taken over and the old VMAs are reattached with their
charge intact.
Original fix generated by an LLM and sent in private by Josef.
[david@kernel.org: call variable "uncharged" and make it const, adjust/simplify comments]
Link: https://lore.kernel.org/20261015-urgent_fixes-v1-0-42796911043b@kernel.org
Link: https://lore.kernel.org/20261015-urgent_fixes-v1-1-42796911043b@kernel.org
Fixes: 4f87153e82c4 ("mm: change failure of MAP_FIXED to restoring the gap on failure")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Jose A. Perez de Azpillaga <azpijr@gmail.com>
Reviewed-by: Lance Yang <lance.yang@linux.dev>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Jann Horn <jannh@google.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Miaohe Lin <linmiaohe@huawei.com>
Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
Cc: Adam Litke <agl@us.ibm.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Cc: Rik van Riel <riel@surriel.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: <stable@vger.kernel.org>
[ sashal: Adapted accountable_mapping(map) to the existing accountable_mapping(map->file, map->vm_flags) signature. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vma.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/mm/vma.c b/mm/vma.c
index 8669da66edc5c..3710cb70ca682 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -2462,14 +2462,17 @@ static int __mmap_setup(struct mmap_state *map, struct list_head *uf)
/* Private writable mapping: check memory availability. */
if (accountable_mapping(map->file, map->vm_flags)) {
- map->charged = map->pglen;
- map->charged -= vms->nr_accounted;
- if (map->charged) {
- error = security_vm_enough_memory_mm(map->mm, map->charged);
+ const unsigned long uncharged = map->pglen - vms->nr_accounted;
+
+ /* Charge only what's not already charged by mappings we replace. */
+ if (uncharged) {
+ error = security_vm_enough_memory_mm(map->mm, uncharged);
if (error)
return error;
}
+ /* Our new mapping owns the entire charge now. */
+ map->charged = map->pglen;
vms->nr_accounted = 0;
map->vm_flags |= VM_ACCOUNT;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 635/686] mm/hugetlb: charge folios to the target mms memcg
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (633 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 634/686] mm/vma: dont leak the commit charge on mmap failure Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 636/686] mm/memfd: fix hugetlb reservation accounting in error paths Greg Kroah-Hartman
` (50 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jinmeng Zhou, Andrew Morton,
Muchun Song, Hongfu Li, David Hildenbrand, Johannes Weiner,
Michal Hocko, Nhat Pham, Oscar Salvador, Roman Gushchin,
Shakeel Butt, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinmeng Zhou <jinmengzhou22@gmail.com>
[ Upstream commit c2deb1356d82c9d54bd2fcf1241cc97eb66fd81f ]
HugeTLB folios are currently charged to the memcg of the allocating task.
This gives the wrong result when a userfaultfd handler populates a HugeTLB
VMA that belongs to another process. The UFFDIO_COPY ioctl operates on
the userfaultfd context's mm, but get_mem_cgroup_from_current() charges
the folio to the handler's memcg instead.
This can be reproduced by placing the faulting process and its userfaultfd
handler in different memory cgroups. Have the target process register a
HugeTLB mapping with userfaultfd, trigger a missing fault, and let the
handler resolve it with UFFDIO_COPY. The hugepage usage is then reported
in the handler's memory.current instead of the target's.
The generic userfaultfd population path avoids this problem by charging
folios to dst_vma->vm_mm.
Pass the target mm through hugetlb_alloc_folio() and charge the folio by
using get_mem_cgroup_from_mm(). This preserves the existing charge timing
and error handling while making HugeTLB userfaultfd population consistent
with the generic path.
Link: https://lore.kernel.org/20260903075048.3316-1-zhoujinmeng@bytedance.com
Fixes: 8cba9576df60 ("hugetlb: memcg: account hugetlb-backed memory in memory controller")
Signed-off-by: Jinmeng Zhou <zhoujinmeng@bytedance.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reviewed-by: Muchun Song <muchun.song@linux.dev>
Reviewed-by: Hongfu Li <lihongfu@kylinos.cn>
Cc: David Hildenbrand <david@kernel.org>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Roman Gushchin <roman.gushchin@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: <stable@vger.kernel.org>
[ sashal: Passed vma->vm_mm directly to mem_cgroup_charge_hugetlb() in alloc_hugetlb_folio() because hugetlb_alloc_folio() is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/memcontrol.h | 8 +++++---
mm/hugetlb.c | 2 +-
mm/memcontrol.c | 6 ++++--
3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
index 2df30cce143de..fc13c85ea903e 100644
--- a/include/linux/memcontrol.h
+++ b/include/linux/memcontrol.h
@@ -662,7 +662,8 @@ static inline int mem_cgroup_charge(struct folio *folio, struct mm_struct *mm,
return __mem_cgroup_charge(folio, mm, gfp);
}
-int mem_cgroup_charge_hugetlb(struct folio* folio, gfp_t gfp);
+int mem_cgroup_charge_hugetlb(struct folio *folio, struct mm_struct *mm,
+ gfp_t gfp);
int mem_cgroup_swapin_charge_folio(struct folio *folio, struct mm_struct *mm,
gfp_t gfp, swp_entry_t entry);
@@ -1175,9 +1176,10 @@ static inline int mem_cgroup_charge(struct folio *folio,
return 0;
}
-static inline int mem_cgroup_charge_hugetlb(struct folio* folio, gfp_t gfp)
+static inline int mem_cgroup_charge_hugetlb(struct folio *folio,
+ struct mm_struct *mm, gfp_t gfp)
{
- return 0;
+ return 0;
}
static inline int mem_cgroup_swapin_charge_folio(struct folio *folio,
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index fad8c38ab4da6..a8da4cb7ad10f 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -3125,7 +3125,7 @@ struct folio *alloc_hugetlb_folio(struct vm_area_struct *vma,
}
}
- ret = mem_cgroup_charge_hugetlb(folio, gfp);
+ ret = mem_cgroup_charge_hugetlb(folio, vma->vm_mm, gfp);
/*
* Unconditionally increment NR_HUGETLB here. If it turns out that
* mem_cgroup_charge_hugetlb failed, then immediately free the page and
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 61092a05f108e..3ce613dab616e 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4824,6 +4824,7 @@ int __mem_cgroup_charge(struct folio *folio, struct mm_struct *mm, gfp_t gfp)
/**
* mem_cgroup_charge_hugetlb - charge the memcg for a hugetlb folio
* @folio: folio being charged
+ * @mm: mm context of the allocation target
* @gfp: reclaim mode
*
* This function is called when allocating a huge page folio, after the page has
@@ -4833,9 +4834,10 @@ int __mem_cgroup_charge(struct folio *folio, struct mm_struct *mm, gfp_t gfp)
* Returns ENOMEM if the memcg is already full.
* Returns 0 if either the charge was successful, or if we skip the charging.
*/
-int mem_cgroup_charge_hugetlb(struct folio *folio, gfp_t gfp)
+int mem_cgroup_charge_hugetlb(struct folio *folio, struct mm_struct *mm,
+ gfp_t gfp)
{
- struct mem_cgroup *memcg = get_mem_cgroup_from_current();
+ struct mem_cgroup *memcg = get_mem_cgroup_from_mm(mm);
int ret = 0;
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 636/686] mm/memfd: fix hugetlb reservation accounting in error paths
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (634 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 635/686] mm/hugetlb: charge folios to the target mms memcg Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 637/686] ASoC: hdac_hda: Allocate the private data at codec driver bind Greg Kroah-Hartman
` (49 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hongfu Li, Andrew Morton,
David Hildenbrand (Arm), Baolin Wang, Hugh Dickins, Muchun Song,
Oscar Salvador, Vivek Kasireddy, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongfu Li <lihongfu@kylinos.cn>
[ Upstream commit 50ee565c1e900e247e439e4139839b060c968343 ]
If hugetlb_add_to_page_cache() in memfd_alloc_folio() fails with -EEXIST,
a concurrent fault has already instantiated the folio in the page cache,
and the reservation now belongs to that folio. Calling
hugetlb_unreserve_pages() in that case incorrectly removes the region
backing the cached folio and releases one reservation more than it should,
leaving that folio in the page cache with no region recording it.
That leaves resv_huge_pages one page short until that folio is removed
from the page cache, so available_huge_pages() reports a page that is not
actually free and the pool can grant one reservation more than it can
back. Applications using hugetlb memfds can then fail to allocate or
fault in a page they already reserved. They see -ENOMEM or -ENOSPC from
the allocation or fault path even though the reservation and
HugePages_Free still look healthy.
So hold the hugetlb fault mutex from hugetlb_reserve_pages() until the
error-path unreserve completes to make the reserve, allocate and
instantiate steps atomic against concurrent faults. With the mutex held
from the start, a concurrent fault can no longer consume the reservation
between reserve and allocate/instantiate. If a fault completed before the
mutex was taken, it has already added the region for that index, so
hugetlb_reserve_pages() returns 0 and the error path leaves the region in
place.
Link: https://lore.kernel.org/20260927094757.31665-1-hongfu.li@linux.dev
Link: https://lore.kernel.org/20260903030134.7407-1-hongfu.li@linux.dev
Fixes: 717cf9357325 ("mm/memfd: reserve hugetlb folios before allocation")
Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Vivek Kasireddy <vivek.kasireddy@intel.com>
Cc: <stable@vger.kernel.org>
[ sashal: Used 0 instead of EMPTY_VMA_FLAGS in hugetlb_reserve_pages() to match the vm_flags_t API. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/memfd.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/mm/memfd.c b/mm/memfd.c
index aa3c948e55738..d09157cd486a2 100644
--- a/mm/memfd.c
+++ b/mm/memfd.c
@@ -82,22 +82,31 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)
struct hstate *h = hstate_file(memfd);
int err = -ENOMEM;
long nr_resv;
+ u32 hash;
gfp_mask = htlb_alloc_mask(h);
gfp_mask &= ~(__GFP_HIGHMEM | __GFP_MOVABLE);
idx >>= huge_page_order(h);
+ /*
+ * Serialize hugepage allocation and instantiation to prevent
+ * races with concurrent allocations, as required by all other
+ * callers of hugetlb_add_to_page_cache().
+ */
+ hash = hugetlb_fault_mutex_hash(memfd->f_mapping, idx);
+ mutex_lock(&hugetlb_fault_mutex_table[hash]);
+
nr_resv = hugetlb_reserve_pages(inode, idx, idx + 1, NULL, 0);
- if (nr_resv < 0)
- return ERR_PTR(nr_resv);
+ if (nr_resv < 0) {
+ err = nr_resv;
+ goto out_unlock;
+ }
folio = alloc_hugetlb_folio_reserve(h,
numa_node_id(),
NULL,
gfp_mask);
if (folio) {
- u32 hash;
-
/*
* Zero the folio to prevent information leaks to userspace.
* Use folio_zero_user() which is optimized for huge/gigantic
@@ -112,20 +121,9 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)
*/
__folio_mark_uptodate(folio);
- /*
- * Serialize hugepage allocation and instantiation to prevent
- * races with concurrent allocations, as required by all other
- * callers of hugetlb_add_to_page_cache().
- */
- hash = hugetlb_fault_mutex_hash(memfd->f_mapping, idx);
- mutex_lock(&hugetlb_fault_mutex_table[hash]);
-
err = hugetlb_add_to_page_cache(folio,
memfd->f_mapping,
idx);
-
- mutex_unlock(&hugetlb_fault_mutex_table[hash]);
-
if (err) {
folio_put(folio);
goto err_unresv;
@@ -133,11 +131,14 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)
hugetlb_set_folio_subpool(folio, subpool_inode(inode));
folio_unlock(folio);
+ mutex_unlock(&hugetlb_fault_mutex_table[hash]);
return folio;
}
err_unresv:
if (nr_resv > 0)
hugetlb_unreserve_pages(inode, idx, idx + 1, 0);
+out_unlock:
+ mutex_unlock(&hugetlb_fault_mutex_table[hash]);
return ERR_PTR(err);
}
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 637/686] ASoC: hdac_hda: Allocate the private data at codec driver bind
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (635 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 636/686] mm/memfd: fix hugetlb reservation accounting in error paths Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 638/686] ASoC: hdac_hda: Restore the codec device type on unbind Greg Kroah-Hartman
` (48 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Ujfalusi, Mark Brown,
Sasha Levin
6.18-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 ac28b3cadb69f..e63b616afa79f 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -638,10 +638,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 37674ea452d6a..2f5a1db235351 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] 687+ messages in thread
* [PATCH 6.18 638/686] ASoC: hdac_hda: Restore the codec device type on unbind
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (636 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 637/686] ASoC: hdac_hda: Allocate the private data at codec driver bind Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 639/686] fs: dont lose inodes that another LRU walker is isolating Greg Kroah-Hartman
` (47 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Ujfalusi, Mark Brown,
Sasha Levin
6.18-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 e63b616afa79f..ca2d3130cc4c5 100644
--- a/sound/soc/codecs/hdac_hda.c
+++ b/sound/soc/codecs/hdac_hda.c
@@ -636,6 +636,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;
@@ -653,6 +660,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] 687+ messages in thread
* [PATCH 6.18 639/686] fs: dont lose inodes that another LRU walker is isolating
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (637 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 638/686] ASoC: hdac_hda: Restore the codec device type on unbind Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 640/686] LoongArch: Fix one-shot limitation for perf hardware breakpoints Greg Kroah-Hartman
` (46 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikolaos Karaolidis, Zhihao Cheng,
Jan Kara, Christian Brauner (Amutable), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolaos Karaolidis <nick@karaolidis.com>
[ Upstream commit 8dc4116041e2b377e5e1b62ba98b37636f9f3968 ]
When inode_lru_isolate() finds an unused inode that still has page
cache, it sets I_LRU_ISOLATING, drops i_lock and the list_lru lock,
invalidates the page cache, clears the flag again and returns
LRU_RETRY so that the restarted walk can free the inode.
Another walker of the same list can reach the inode in that window.
It sees a non-zero i_state and takes the inode off the LRU, as it
would an inode that is in use. Page cache deletion requeues the inode
once the mapping is shrinkable, so this is harmless if it happens
before the last deletion. If it happens after, nothing puts the inode
back: it stays in memory, unused, clean and without page cache, out
of reach of the shrinker and of drop_caches, until it is looked up
again or the filesystem is unmounted.
Before commit 2a0629834cd8 ("vfs: Don't evict inode under the inode
lru traversing context") the pin was an i_count reference, and the
final iput() put the inode back on the LRU.
Skip inodes that are being isolated and leave them to the walker that
pinned them, which restarts its walk once it has unpinned them.
The window is reached by any unused inode with page cache on
CONFIG_HIGHMEM kernels, and otherwise by inodes whose page cache is a
single shadow entry at index 0. On an i386 HIGHMEM guest, eight
concurrent "echo 2 > /proc/sys/vm/drop_caches" over 2000 freshly read
one-page ext4 files leave roughly 400 of the inodes off the LRU per
round; on x86_64, with the files' pages first evicted through
memory.reclaim, 3 to 4 per round. With this patch, none in either case.
Fixes: 2a0629834cd8 ("vfs: Don't evict inode under the inode lru traversing context")
Cc: stable@vger.kernel.org
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
Link: https://patch.msgid.link/20261009142431.713875-1-nick@karaolidis.com
Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: Replaced inode_state_read(inode) with direct inode->i_state access under the existing i_lock. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/inode.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/inode.c b/fs/inode.c
index 229ac6ff72cb9..b60111fad771a 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -924,6 +924,12 @@ static enum lru_status inode_lru_isolate(struct list_head *item,
if (!spin_trylock(&inode->i_lock))
return LRU_SKIP;
+ /* Another walker is dropping its page cache, leave it to that one */
+ if (inode->i_state & I_LRU_ISOLATING) {
+ spin_unlock(&inode->i_lock);
+ return LRU_SKIP;
+ }
+
/*
* Inodes can get referenced, redirtied, or repopulated while
* they're already on the LRU, and this can make them
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 640/686] LoongArch: Fix one-shot limitation for perf hardware breakpoints
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (638 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 639/686] fs: dont lose inodes that another LRU walker is isolating Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 641/686] ocfs2: fix oob in __ocfs2_find_path Greg Kroah-Hartman
` (45 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tiezhu Yang, Huacai Chen,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang <yangtiezhu@loongson.cn>
[ Upstream commit 5e0b00fd000a53a5428fed6c96be74019bd0ad17 ]
In breakpoint_handler() and watchpoint_handler(), the code disables the
hardware slot by executing update_bp_registers(regs, 0, ...). This design
forces the active hardware breakpoint configuration to be wiped out upon
its first hit, turning standard perf hardware breakpoints into "one-shot"
events.
Furthermore, while the ptrace single-step path in do_watch() executes a
hardware single-step skip mechanism to advance the PC, the standard perf
path lacks any mechanism to bypass the original triggering instruction.
To maintain the long-term persistence of hardware breakpoints for perf
usage, eliminate the disruptive calls to update_bp_registers() within
the handler loops to keep the breakpoint configuration enabled.
Concurrently, execute a single, unified register write outside the loop
to atomize the state transition and explicitly enforce the hardware skip
mechanism once per exception return, ensuring the processor safely steps
forward without lockups.
Meanwhile, in order to prevent status contamination during single-core
context switches or cross-core thread migrations, the hardware register
skip state of the previous thread is saved first. Then, the skip state
is restored and its software skip flag is also cleared only if the next
thread has the skip flag; otherwise, 0 is written to clear the FWPS and
MWPS registers, which explicitly clears the skip bit according to the
architectural specification.
Additionally, explicitly clear hbp_break_skip and hbp_watch_skip inside
ptrace_hw_copy_thread() which is called by copy_thread() during the task
creation. This guarantees that a newly cloned child task starts with a
clean slate.
Here is a user-space reproducer to demonstrate the issue.
(1) Test program (test_perf_continuous.c):
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
static int var = 0;
int main(void)
{
size_t count = 0;
struct perf_event_attr attr = {
.type = PERF_TYPE_BREAKPOINT,
.size = sizeof(attr),
.bp_type = HW_BREAKPOINT_W,
.bp_addr = (unsigned long)&var,
.bp_len = HW_BREAKPOINT_LEN_1,
.exclude_kernel = 1,
};
int fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
asm volatile("st.b %1, %0" : "=m"(var) : "r"(11) : "memory");
asm volatile("st.b %1, %0" : "=m"(var) : "r"(22) : "memory");
asm volatile("st.b %1, %0" : "=m"(var) : "r"(33) : "memory");
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
read(fd, &count, sizeof(size_t));
printf("Watchpoint counts: expected = 3, actual = %zu\n", count);
close(fd);
return 0;
}
(2) Test steps:
$ gcc test_perf_continuous.c -o test_perf_continuous
$ ./test_perf_continuous
(3) Test results:
Without this patch:
Watchpoint counts: expected = 3, actual = 1
With this patch:
Watchpoint counts: expected = 3, actual = 3
Cc: stable@vger.kernel.org
Fixes: 3eb2a8b23598 ("LoongArch: Fix multiple hardware watchpoint issues")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
[ sashal: Adjusted context to preserve the existing __switch_to() call passing task_thread_info(next). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/loongarch/include/asm/hw_breakpoint.h | 4 +--
arch/loongarch/include/asm/loongarch.h | 3 ++
arch/loongarch/include/asm/processor.h | 1 +
arch/loongarch/include/asm/switch_to.h | 2 +-
arch/loongarch/kernel/hw_breakpoint.c | 39 +++++++++++++++++++---
5 files changed, 41 insertions(+), 8 deletions(-)
diff --git a/arch/loongarch/include/asm/hw_breakpoint.h b/arch/loongarch/include/asm/hw_breakpoint.h
index d202052df8a16..f4478936787d6 100644
--- a/arch/loongarch/include/asm/hw_breakpoint.h
+++ b/arch/loongarch/include/asm/hw_breakpoint.h
@@ -121,12 +121,12 @@ bool watchpoint_handler(struct pt_regs *regs);
#ifdef CONFIG_HAVE_HW_BREAKPOINT
extern void ptrace_hw_copy_thread(struct task_struct *task);
-extern void hw_breakpoint_thread_switch(struct task_struct *next);
+extern void hw_breakpoint_thread_switch(struct task_struct *prev, struct task_struct *next);
#else
static inline void ptrace_hw_copy_thread(struct task_struct *task)
{
}
-static inline void hw_breakpoint_thread_switch(struct task_struct *next)
+static inline void hw_breakpoint_thread_switch(struct task_struct *prev, struct task_struct *next)
{
}
#endif
diff --git a/arch/loongarch/include/asm/loongarch.h b/arch/loongarch/include/asm/loongarch.h
index 642dc9adddceb..9a85227ed84ca 100644
--- a/arch/loongarch/include/asm/loongarch.h
+++ b/arch/loongarch/include/asm/loongarch.h
@@ -1093,6 +1093,9 @@
#define CSR_FWPS_SKIP_SHIFT 16
#define CSR_FWPS_SKIP (_ULCAST_(1) << CSR_FWPS_SKIP_SHIFT)
+#define CSR_MWPS_SKIP_SHIFT 16
+#define CSR_MWPS_SKIP (_ULCAST_(1) << CSR_MWPS_SKIP_SHIFT)
+
/*
* CSR_ECFG IM
*/
diff --git a/arch/loongarch/include/asm/processor.h b/arch/loongarch/include/asm/processor.h
index c3bc44b5f5b30..81af48cbee7b9 100644
--- a/arch/loongarch/include/asm/processor.h
+++ b/arch/loongarch/include/asm/processor.h
@@ -138,6 +138,7 @@ struct thread_struct {
struct loongarch_lbt lbt; /* Also conditionally copied */
/* Hardware breakpoints pinned to this task. */
+ bool hbp_break_skip, hbp_watch_skip;
struct perf_event *hbp_break[LOONGARCH_MAX_BRP];
struct perf_event *hbp_watch[LOONGARCH_MAX_WRP];
};
diff --git a/arch/loongarch/include/asm/switch_to.h b/arch/loongarch/include/asm/switch_to.h
index 5b225aff3ba21..3b662b18e19a6 100644
--- a/arch/loongarch/include/asm/switch_to.h
+++ b/arch/loongarch/include/asm/switch_to.h
@@ -36,7 +36,7 @@ extern asmlinkage struct task_struct *__switch_to(struct task_struct *prev,
do { \
lose_fpu_inatomic(1, prev); \
lose_lbt_inatomic(1, prev); \
- hw_breakpoint_thread_switch(next); \
+ hw_breakpoint_thread_switch(prev, next); \
(last) = __switch_to(prev, next, task_thread_info(next), \
__builtin_return_address(0), __builtin_frame_address(0)); \
} while (0)
diff --git a/arch/loongarch/kernel/hw_breakpoint.c b/arch/loongarch/kernel/hw_breakpoint.c
index 1a05350159f7b..df149ff06dd50 100644
--- a/arch/loongarch/kernel/hw_breakpoint.c
+++ b/arch/loongarch/kernel/hw_breakpoint.c
@@ -156,6 +156,9 @@ static int hw_breakpoint_slot_setup(struct perf_event **slots, int max_slots,
void ptrace_hw_copy_thread(struct task_struct *tsk)
{
+ tsk->thread.hbp_break_skip = 0;
+ tsk->thread.hbp_watch_skip = 0;
+
memset(tsk->thread.hbp_break, 0, sizeof(tsk->thread.hbp_break));
memset(tsk->thread.hbp_watch, 0, sizeof(tsk->thread.hbp_watch));
}
@@ -485,6 +488,7 @@ NOKPROBE_SYMBOL(update_bp_registers);
bool breakpoint_handler(struct pt_regs *regs)
{
int i;
+ unsigned int clear_mask = 0;
bool need_sigtrap = false;
struct perf_event *bp, **slots;
@@ -500,11 +504,13 @@ bool breakpoint_handler(struct pt_regs *regs)
if (bp->attr.sigtrap)
need_sigtrap = true;
- csr_write32(0x1 << i, LOONGARCH_CSR_FWPS);
- update_bp_registers(regs, 0, 0);
+ clear_mask |= (0x1 << i);
}
}
+ if (clear_mask)
+ csr_write32(clear_mask | CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS);
+
return need_sigtrap;
}
NOKPROBE_SYMBOL(breakpoint_handler);
@@ -512,6 +518,7 @@ NOKPROBE_SYMBOL(breakpoint_handler);
bool watchpoint_handler(struct pt_regs *regs)
{
int i;
+ unsigned int clear_mask = 0;
bool need_sigtrap = false;
struct perf_event *wp, **slots;
@@ -527,11 +534,13 @@ bool watchpoint_handler(struct pt_regs *regs)
if (wp->attr.sigtrap)
need_sigtrap = true;
- csr_write32(0x1 << i, LOONGARCH_CSR_MWPS);
- update_bp_registers(regs, 0, 1);
+ clear_mask |= (0x1 << i);
}
}
+ if (clear_mask)
+ csr_write32(clear_mask | CSR_MWPS_SKIP, LOONGARCH_CSR_MWPS);
+
return need_sigtrap;
}
NOKPROBE_SYMBOL(watchpoint_handler);
@@ -555,7 +564,7 @@ static int __init arch_hw_breakpoint_init(void)
}
arch_initcall(arch_hw_breakpoint_init);
-void hw_breakpoint_thread_switch(struct task_struct *next)
+void hw_breakpoint_thread_switch(struct task_struct *prev, struct task_struct *next)
{
u64 addr, mask;
struct pt_regs *regs = task_pt_regs(next);
@@ -567,6 +576,26 @@ void hw_breakpoint_thread_switch(struct task_struct *next)
csr_write32(CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS);
regs->csr_prmd |= CSR_PRMD_PWE;
} else {
+ unsigned int fwps = csr_read32(LOONGARCH_CSR_FWPS);
+ unsigned int mwps = csr_read32(LOONGARCH_CSR_MWPS);
+
+ prev->thread.hbp_break_skip = !!(fwps & CSR_FWPS_SKIP);
+ prev->thread.hbp_watch_skip = !!(mwps & CSR_MWPS_SKIP);
+
+ if (!next->thread.hbp_break_skip)
+ csr_write32(0, LOONGARCH_CSR_FWPS);
+ else {
+ csr_write32(CSR_FWPS_SKIP, LOONGARCH_CSR_FWPS);
+ next->thread.hbp_break_skip = 0;
+ }
+
+ if (!next->thread.hbp_watch_skip)
+ csr_write32(0, LOONGARCH_CSR_MWPS);
+ else {
+ csr_write32(CSR_MWPS_SKIP, LOONGARCH_CSR_MWPS);
+ next->thread.hbp_watch_skip = 0;
+ }
+
/* Update breakpoints */
update_bp_registers(regs, 1, 0);
/* Update watchpoints */
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 641/686] ocfs2: fix oob in __ocfs2_find_path
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (639 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 640/686] LoongArch: Fix one-shot limitation for perf hardware breakpoints Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 642/686] ocfs2: fix array out of bound access in __ocfs2_find_path() Greg Kroah-Hartman
` (44 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Edward Adam Davis,
syzbot+151afab124dfbc5f15e6, Heming Zhao, Joseph Qi, Mark Fasheh,
Joel Becker, Junxiao Bi, Changwei Ge, Jun Piao, Andrew Morton,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <eadavis@qq.com>
[ Upstream commit e0b0f2834c9bec51b1068de5cf5e10c7519143eb ]
syzbot constructed a corrupted image, which resulted in el->l_count from
the b-tree extent block being 0. Since the length of the l_recs array
depends on l_count, reading its member e_blkno triggered the out-of-bounds
access reported by syzbot in [1].
The loop terminates when l_count is 0, similar to when next_free is 0.
[1]
UBSAN: array-index-out-of-bounds in fs/ocfs2/alloc.c:1838:11
index 0 is out of range for type 'struct ocfs2_extent_rec[] __counted_by(l_count)' (aka 'struct ocfs2_extent_rec[]')
Call Trace:
__ocfs2_find_path+0x606/0xa40 fs/ocfs2/alloc.c:1838
ocfs2_find_leaf+0xab/0x1c0 fs/ocfs2/alloc.c:1946
ocfs2_get_clusters_nocache+0x172/0xc60 fs/ocfs2/extent_map.c:418
ocfs2_get_clusters+0x505/0xa70 fs/ocfs2/extent_map.c:631
ocfs2_extent_map_get_blocks+0x202/0x6a0 fs/ocfs2/extent_map.c:678
ocfs2_read_virt_blocks+0x286/0x930 fs/ocfs2/extent_map.c:1001
ocfs2_read_dir_block fs/ocfs2/dir.c:521 [inline]
ocfs2_find_entry_el fs/ocfs2/dir.c:728 [inline]
ocfs2_find_entry+0x3e4/0x2090 fs/ocfs2/dir.c:1120
ocfs2_find_files_on_disk+0xdf/0x310 fs/ocfs2/dir.c:2023
ocfs2_lookup_ino_from_name+0x52/0x100 fs/ocfs2/dir.c:2045
_ocfs2_get_system_file_inode fs/ocfs2/sysfile.c:136 [inline]
ocfs2_get_system_file_inode+0x326/0x770 fs/ocfs2/sysfile.c:112
ocfs2_init_global_system_inodes+0x319/0x660 fs/ocfs2/super.c:461
ocfs2_initialize_super fs/ocfs2/super.c:2196 [inline]
ocfs2_fill_super+0x4432/0x65b0 fs/ocfs2/super.c:993
get_tree_bdev_flags+0x40e/0x4d0 fs/super.c:1691
vfs_get_tree+0x92/0x2a0 fs/super.c:1751
fc_mount fs/namespace.c:1199 [inline]
Link: https://lkml.kernel.org/r/tencent_4D99464FA28D9225BE0DBA923F5DF6DD8C07@qq.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Reported-by: syzbot+151afab124dfbc5f15e6@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=151afab124dfbc5f15e6
Reviewed-by: Heming Zhao <heming.zhao@suse.com>
Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 6193ce7896af ("ocfs2: fix array out of bound access in __ocfs2_find_path()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/alloc.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index d22ad99c9ebee..58f92a02ed68a 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1811,14 +1811,15 @@ static int __ocfs2_find_path(struct ocfs2_caching_info *ci,
ret = -EROFS;
goto out;
}
- if (le16_to_cpu(el->l_next_free_rec) == 0) {
+ if (!el->l_next_free_rec || !el->l_count) {
ocfs2_error(ocfs2_metadata_cache_get_super(ci),
- "Owner %llu has empty extent list at depth %u\n",
+ "Owner %llu has empty extent list at depth %u\n"
+ "(next free=%u count=%u)\n",
(unsigned long long)ocfs2_metadata_cache_owner(ci),
- le16_to_cpu(el->l_tree_depth));
+ le16_to_cpu(el->l_tree_depth),
+ le16_to_cpu(el->l_next_free_rec), le16_to_cpu(el->l_count));
ret = -EROFS;
goto out;
-
}
for(i = 0; i < le16_to_cpu(el->l_next_free_rec) - 1; i++) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 642/686] ocfs2: fix array out of bound access in __ocfs2_find_path()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (640 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 641/686] ocfs2: fix oob in __ocfs2_find_path Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 643/686] arm64/gcs: release GCS on failed fork Greg Kroah-Hartman
` (43 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Giorgi Kobakhia, Andrew Morton,
Xiang Mei, Joseph Qi, Mark Fasheh, Joel Becker, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giorgi Kobakhia <gkobakhi@asu.edu>
[ Upstream commit 6193ce7896afb52a321a0063c8b6a45e477a84e2 ]
__ocfs2_find_path() walks down the extent tree and records path by calling
find_path_ins(), which appends entry to path->p_node[]. It only has 5
spots.
A corrupted ocfs2 image whose extent block is pointing to itself causes
__ocfs2_find_path() descent endlessly, writing past the end of
path->p_node[] array.
UBSAN: array-index-out-of-bounds in fs/ocfs2/alloc.c:677:14
index 5 is out of range for type 'ocfs2_path_item [5]'
Call Trace:
<TASK>
find_path_ins (fs/ocfs2/alloc.c:677 fs/ocfs2/alloc.c:1914)
__ocfs2_find_path.constprop.0 (fs/ocfs2/alloc.c:1882)
ocfs2_commit_truncate (fs/ocfs2/alloc.c:1924 fs/ocfs2/alloc.c:7286)
ocfs2_truncate_file (fs/ocfs2/file.c:515)
ocfs2_setattr (fs/ocfs2/file.c:1224)
notify_change (fs/attr.c:556)
do_truncate (fs/open.c:68)
do_ftruncate (fs/open.c:194 (discriminator 1))
ksys_ftruncate (fs/open.c:206)
__x64_sys_ftruncate (fs/open.c:211 fs/open.c:209 fs/open.c:209)
Commit a406aff8c051 ("ocfs2: validate l_tree_depth to avoid out-of-bounds
access") already restricts el->l_tree_depth to be less than
OCFS2_MAX_PATH_DEPTH, which is equal to 5. However, does not handle the
infinite descent case.
Check if the el->l_tree_depth decreases on each descent. Maximum descents
are restricted to 4 and the path->p_node[] array does not overflow.
Link: https://lore.kernel.org/20260922202159.2421642-1-gkobakhi@asu.edu
Fixes: dcd0538ff4e8 ("ocfs2: sparse b-tree support")
Signed-off-by: Giorgi Kobakhia <gkobakhi@asu.edu>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Tested-by: Xiang Mei <xmei5@asu.edu>
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: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ocfs2/alloc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 58f92a02ed68a..c12154014b892 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -1796,6 +1796,7 @@ static int __ocfs2_find_path(struct ocfs2_caching_info *ci,
int i, ret = 0;
u32 range;
u64 blkno;
+ u32 prev_depth = OCFS2_MAX_PATH_DEPTH;
struct buffer_head *bh = NULL;
struct ocfs2_extent_block *eb;
struct ocfs2_extent_list *el;
@@ -1803,14 +1804,16 @@ static int __ocfs2_find_path(struct ocfs2_caching_info *ci,
el = root_el;
while (el->l_tree_depth) {
- if (unlikely(le16_to_cpu(el->l_tree_depth) >= OCFS2_MAX_PATH_DEPTH)) {
+ if (unlikely(le16_to_cpu(el->l_tree_depth) >= prev_depth)) {
ocfs2_error(ocfs2_metadata_cache_get_super(ci),
- "Owner %llu has invalid tree depth %u in extent list\n",
+ "Owner %llu has invalid tree depth %u in extent list (max %u)\n",
(unsigned long long)ocfs2_metadata_cache_owner(ci),
- le16_to_cpu(el->l_tree_depth));
+ le16_to_cpu(el->l_tree_depth), prev_depth - 1);
ret = -EROFS;
goto out;
}
+ prev_depth = le16_to_cpu(el->l_tree_depth);
+
if (!el->l_next_free_rec || !el->l_count) {
ocfs2_error(ocfs2_metadata_cache_get_super(ci),
"Owner %llu has empty extent list at depth %u\n"
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 643/686] arm64/gcs: release GCS on failed fork
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (641 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 642/686] ocfs2: fix array out of bound access in __ocfs2_find_path() Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 644/686] PCI: cadence: Store the core controller in platform drvdata Greg Kroah-Hartman
` (42 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mark Brown,
Iván Ezequiel Rodriguez, Catalin Marinas, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
[ Upstream commit 078e122f3bf000dd45965997b66deac10ee580fa ]
copy_thread() can map a CLONE_VM GCS and still return 0. A later
copy_process() failure calls exit_thread(), but arm64 did not
implement it, so the VMA stayed in the parent's mm. Wire
HAVE_EXIT_THREAD to gcs_free().
Kernel threads created with CLONE_VM (io_uring and vhost workers)
inherit the parent's gcs_base/gcs_size from arch_dup_task_struct()
without allocating their own GCS. When such a thread exits,
exit_mm() -> mm_release() -> deactivate_mm() -> gcs_free() unmaps the
parent's GCS. With the new exit_thread(), a failed copy_process() for
one of these threads would do the same. Clear these fields in
copy_thread().
Fixes: 506496bcbb42 ("arm64/gcs: Ensure that new threads have a GCS")
Cc: stable@vger.kernel.org
Cc: Mark Brown <broonie@kernel.org>
Assisted-by: LLM
Signed-off-by: Iván Ezequiel Rodriguez <ivanrwcm25@gmail.com>
Reviewed-by: Mark Brown <broonie@kernel.org>
Tested-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
[ sashal: Placed exit_thread() before the existing erratum helper conditional block. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/process.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 2e567a7d89c9b..66b7284ce751d 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -222,6 +222,7 @@ config ARM64
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
select HAVE_BUILDTIME_MCOUNT_SORT
select HAVE_EFFICIENT_UNALIGNED_ACCESS
+ select HAVE_EXIT_THREAD
select HAVE_GUP_FAST
select HAVE_FTRACE_GRAPH_FUNC
select HAVE_FUNCTION_TRACER
diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
index 4c328b7c79ba3..b3cde5f60b00f 100644
--- a/arch/arm64/kernel/process.c
+++ b/arch/arm64/kernel/process.c
@@ -319,9 +319,18 @@ static int copy_thread_gcs(struct task_struct *p,
return 0;
}
+static void gcs_reset_thread(struct task_struct *task)
+{
+ task->thread.gcs_base = 0;
+ task->thread.gcs_size = 0;
+ task->thread.gcspr_el0 = 0;
+}
+
#else
static void flush_gcs(void) { }
+static void gcs_reset_thread(struct task_struct *task) { }
+
static int copy_thread_gcs(struct task_struct *p,
const struct kernel_clone_args *args)
{
@@ -340,6 +349,12 @@ void flush_thread(void)
flush_gcs();
}
+void exit_thread(struct task_struct *tsk)
+{
+ /* Failed fork after copy_thread(); deactivate_mm() does not run. */
+ gcs_free(tsk);
+}
+
#ifdef CONFIG_ARM64_ERRATUM_4193714
static void arch_dup_tlbbatch_mask(struct task_struct *dst)
@@ -537,6 +552,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.cpu_context.x19 = (unsigned long)args->fn;
p->thread.cpu_context.x20 = (unsigned long)args->fn_arg;
+ /* Kernel threads sharing the parent's mm must not free its GCS. */
+ gcs_reset_thread(p);
if (system_supports_poe())
p->thread.por_el0 = POR_EL0_INIT;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 644/686] PCI: cadence: Store the core controller in platform drvdata
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (642 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 643/686] arm64/gcs: release GCS on failed fork Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 645/686] iomap: dont mark unwritten parts of a folio uptodate Greg Kroah-Hartman
` (41 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linmao Li, Manivannan Sadhasivam,
Bjorn Helgaas, Aksh Garg, Sasha Levin
6.18-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
[ sashal: adapted the retained PHY-link cleanup loop to use pcie directly instead of the removed wrapper ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../controller/cadence/pcie-cadence-plat.c | 33 +++++++------------
1 file changed, 11 insertions(+), 22 deletions(-)
diff --git a/drivers/pci/controller/cadence/pcie-cadence-plat.c b/drivers/pci/controller/cadence/pcie-cadence-plat.c
index 0456845dabb96..c1ec619ab0a4e 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;
-};
-
struct cdns_plat_pcie_of_data {
bool is_rc;
};
@@ -40,9 +32,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;
int phy_count;
@@ -56,11 +48,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;
@@ -72,9 +59,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;
@@ -99,9 +86,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;
@@ -119,18 +106,20 @@ 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);
- phy_count = cdns_plat_pcie->pcie->phy_count;
+ cdns_pcie_disable_phy(pcie);
+ phy_count = pcie->phy_count;
while (phy_count--)
- device_link_del(cdns_plat_pcie->pcie->link[phy_count]);
+ device_link_del(pcie->link[phy_count]);
- return 0;
+ return ret;
}
static void cdns_plat_pcie_shutdown(struct platform_device *pdev)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 645/686] iomap: dont mark unwritten parts of a folio uptodate
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (643 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 644/686] PCI: cadence: Store the core controller in platform drvdata Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 646/686] mm/shmem: dont release a swapin-error marker as a swap entry Greg Kroah-Hartman
` (40 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Josef Bacik,
Christian Brauner (Amutable), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Brauner <brauner@kernel.org>
[ Upstream commit a4193b4af359db84b2cdf3a040752861984c636b ]
For a buffered write into a hole, an unwritten or new extent, or past
EOF __iomap_write_begin() zeroes the parts of the blocks outside of the
write and then marks the blocks uptodate. That includes the range of the
write itself which still holds whatever was in the folio before. It only
becomes valid once the copy from userspace has filled it in.
But the copy can come up short and __iomap_write_end() only rejects a
short copy if the folio isn't uptodate. If the zeroed blocks were all
that was missing the folio is uptodate by then, the short copy is
accepted, and the rest of the range is exposed to readers and can end up
on disk. A source buffer that ends in an unmapped page is enough:
ftruncate(fd, 4096);
pwrite(fd, p, 3000, 100); /* 16 bytes at p, then PROT_NONE */
pread(fd, buf, 4096, 0);
The write returns 16 and the read returns 2984 bytes of whatever was in
that page before. If other blocks of the folio aren't uptodate the short
copy is rejected but the zeroed blocks keep their uptodate bits and the
retry with the copied length leaves the same bytes behind.
Only mark blocks uptodate in __iomap_write_begin() after reading them.
__iomap_write_end() marks the zeroed blocks uptodate once the copy has
succeeded and rejects a short copy.
Willy reported this back in 2024 (cf. [1]) and Zhang Yi posted the same
fix (cf. [2]) but it never got merged.
[1]: https://lore.kernel.org/all/ZqsN5ouQTEc1KAzV@casper.infradead.org
[2]: https://lore.kernel.org/all/20240812121159.3775074-6-yi.zhang@huaweicloud.com
Fixes: 9dc55f1389f9 ("iomap: add support for sub-pagesize buffered I/O without buffer heads")
Reported-by: Josef Bacik <josef@toxicpanda.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261029-work-iomap-ai-fixes-v1-1-7eda63bc1b13@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
[ sashal: placed iomap_set_range_uptodate() after the read-error check because IOMAP_F_ZERO_TAIL handling is absent ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/iomap/buffered-io.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
index c9ece378687b9..cbd729ef50ab7 100644
--- a/fs/iomap/buffered-io.c
+++ b/fs/iomap/buffered-io.c
@@ -766,6 +766,7 @@ static int __iomap_write_begin(const struct iomap_iter *iter,
if (iomap_block_needs_zeroing(iter, block_start)) {
if (WARN_ON_ONCE(iter->flags & IOMAP_UNSHARE))
return -EIO;
+ /* uptodate once copied, see __iomap_write_end() */
folio_zero_segments(folio, poff, from, to, poff + plen);
} else {
int status;
@@ -781,8 +782,8 @@ static int __iomap_write_begin(const struct iomap_iter *iter,
folio, block_start, plen);
if (status)
return status;
+ iomap_set_range_uptodate(folio, poff, plen);
}
- iomap_set_range_uptodate(folio, poff, plen);
} while ((block_start += plen) < block_end);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 646/686] mm/shmem: dont release a swapin-error marker as a swap entry
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (644 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 645/686] iomap: dont mark unwritten parts of a folio uptodate Greg Kroah-Hartman
@ 2026-11-13 15:52 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 647/686] f2fs: fix to invalidate curseg if change_curseg() fails Greg Kroah-Hartman
` (39 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:52 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Carlier, Andrew Morton,
syzbot+23b25ba3c6bf971f9c57, Baolin Wang, Baoquan he, Barry Song,
Hugh Dickens, Kairui Song, Kemeng Shi, Nhat Pham, Sasha Levin,
Chis Li
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <devnexen@gmail.com>
[ Upstream commit e4b92891aaca0d37b5973362dd14747a65406650 ]
A failed shmem swapin (eg, EIO) frees the swap slot and leaves a
PTE_MARKER_POISONED entry in the page cache. On truncate or eviction
shmem_free_swap() passes that marker to swap_put_entries_direct(), which
warns because it is not a swap entry. There is nothing left to release
either way.
Skip the release for non-swap entries, as every other caller already does.
Link: https://lore.kernel.org/20260920155002.1030454-1-devnexen@gmail.com
Fixes: ac2d3268284b ("mm/swapfile.c: remove the unneeded checking")
Signed-off-by: David Carlier <devnexen@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: syzbot+23b25ba3c6bf971f9c57@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=23b25ba3c6bf971f9c57
Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Baoquan he <bhe@redhat.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Chis Li <chrisl@kernel.org> (Google)
Cc: Hugh Dickens <hughd@google.com>
Cc: Kairui Song <kasong@tencent.com>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: <stable@vger.kernel.org>
[ sashal: adapted newer softleaf and swap-release APIs to the existing swp_entry_t-based swap helpers ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/shmem.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/mm/shmem.c b/mm/shmem.c
index 6f4c85a3f6410..5ce1c0ddf8cde 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -948,6 +948,7 @@ static long shmem_free_swap(struct address_space *mapping,
pgoff_t index, pgoff_t end, void *radswap)
{
XA_STATE(xas, &mapping->i_pages, index);
+ const swp_entry_t swp = radix_to_swp_entry(radswap);
unsigned int nr_pages = 0;
pgoff_t base;
void *entry;
@@ -964,8 +965,9 @@ static long shmem_free_swap(struct address_space *mapping,
}
xas_unlock_irq(&xas);
- if (nr_pages)
- free_swap_and_cache_nr(radix_to_swp_entry(radswap), nr_pages);
+ /* A swapin-error marker holds no swap slot, so just drop it. */
+ if (nr_pages && !non_swap_entry(swp))
+ free_swap_and_cache_nr(swp, nr_pages);
return nr_pages;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 647/686] f2fs: fix to invalidate curseg if change_curseg() fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (645 preceding siblings ...)
2026-11-13 15:52 ` [PATCH 6.18 646/686] mm/shmem: dont release a swapin-error marker as a swap entry Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 648/686] LoongArch: Dont init & online empty nodes Greg Kroah-Hartman
` (38 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 error-path context to use PTR_ERR(sum_folio) instead of PTR_ERR(entry) ]
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 c0ec2715408e8..1097e688d165f 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3067,6 +3067,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] 687+ messages in thread
* [PATCH 6.18 648/686] LoongArch: Dont init & online empty nodes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (646 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 647/686] 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 6.18 649/686] Documentation/kernel-parameters: Move the kernel build options Greg Kroah-Hartman
` (37 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Huacai Chen, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen <chenhuacai@loongson.cn>
[ Upstream commit 87c6d144bc7bbed0c4573848b9c92006edca7848 ]
Don't init & online empty nodes without any CPU cores (and memory), in
this way "lscpu" will not display confusing empty nodes.
Modify fake_numa_init() to make sure at least Node-0 isn't empty for the
FDT booting case.
Cc: stable@vger.kernel.org
Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
[ sashal: adjusted context in fake_numa_init(), which still sets node 0 in numa_nodes_parsed ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/loongarch/kernel/numa.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/loongarch/kernel/numa.c b/arch/loongarch/kernel/numa.c
index 8b89898e20df1..69ea85c4f232e 100644
--- a/arch/loongarch/kernel/numa.c
+++ b/arch/loongarch/kernel/numa.c
@@ -216,6 +216,8 @@ static int __init fake_numa_init(void)
phys_addr_t start = memblock_start_of_DRAM();
phys_addr_t end = memblock_end_of_DRAM() - 1;
+ set_cpuid_to_node(0, 0);
+ early_numa_add_cpu(0, 0);
node_set(0, numa_nodes_parsed);
pr_info("Faking a node at [mem %pap-%pap]\n", &start, &end);
@@ -245,8 +247,10 @@ int __init init_numa_memory(void)
return -EINVAL;
for_each_node_mask(node, node_possible_map) {
- node_mem_init(node);
- node_set_online(node);
+ if (!cpumask_empty(&cpus_on_node[node])) {
+ node_mem_init(node);
+ node_set_online(node);
+ }
}
max_pfn = PFN_DOWN(memblock_end_of_DRAM());
max_low_pfn = min(PFN_DOWN(HIGHMEM_START), max_pfn);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 649/686] Documentation/kernel-parameters: Move the kernel build options
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (647 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 648/686] LoongArch: Dont init & online empty nodes Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 650/686] nvmet-tcp: validate the TLS handshake timeout Greg Kroah-Hartman
` (36 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Borislav Petkov (AMD), Randy Dunlap,
Jonathan Corbet, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Borislav Petkov (AMD) <bp@alien8.de>
[ Upstream commit f690e07859e67505e7106ef5b4fae5e8b71b2109 ]
Move the kernel build options abbreviations to the .txt file so that
they are together instead of one having to go hunt them in the .rst
file.
Tweak the formatting so that the inclusion of kernel-parameters.txt
still keeps the whole thing somewhat presentable in the html output too.
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Message-ID: <20251112114641.8230-1-bp@kernel.org>
Stable-dep-of: 799203afd298 ("nvme-tcp: validate the TLS handshake timeout")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../admin-guide/kernel-parameters.rst | 97 +-----------------
.../admin-guide/kernel-parameters.txt | 98 +++++++++++++++++++
2 files changed, 99 insertions(+), 96 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.rst b/Documentation/admin-guide/kernel-parameters.rst
index 7bf8cc7df6b54..02a725536cc50 100644
--- a/Documentation/admin-guide/kernel-parameters.rst
+++ b/Documentation/admin-guide/kernel-parameters.rst
@@ -110,102 +110,7 @@ The parameters listed below are only valid if certain kernel build options
were enabled and if respective hardware is present. This list should be kept
in alphabetical order. The text in square brackets at the beginning
of each description states the restrictions within which a parameter
-is applicable::
-
- ACPI ACPI support is enabled.
- AGP AGP (Accelerated Graphics Port) is enabled.
- ALSA ALSA sound support is enabled.
- APIC APIC support is enabled.
- APM Advanced Power Management support is enabled.
- APPARMOR AppArmor support is enabled.
- ARM ARM architecture is enabled.
- ARM64 ARM64 architecture is enabled.
- AX25 Appropriate AX.25 support is enabled.
- CLK Common clock infrastructure is enabled.
- CMA Contiguous Memory Area support is enabled.
- DRM Direct Rendering Management support is enabled.
- DYNAMIC_DEBUG Build in debug messages and enable them at runtime
- EARLY Parameter processed too early to be embedded in initrd.
- EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
- EFI EFI Partitioning (GPT) is enabled
- EVM Extended Verification Module
- FB The frame buffer device is enabled.
- FTRACE Function tracing enabled.
- GCOV GCOV profiling is enabled.
- HIBERNATION HIBERNATION is enabled.
- HW Appropriate hardware is enabled.
- HYPER_V HYPERV support is enabled.
- IMA Integrity measurement architecture is enabled.
- IP_PNP IP DHCP, BOOTP, or RARP is enabled.
- IPV6 IPv6 support is enabled.
- ISAPNP ISA PnP code is enabled.
- ISDN Appropriate ISDN support is enabled.
- ISOL CPU Isolation is enabled.
- JOY Appropriate joystick support is enabled.
- KGDB Kernel debugger support is enabled.
- KVM Kernel Virtual Machine support is enabled.
- LIBATA Libata driver is enabled
- LOONGARCH LoongArch architecture is enabled.
- LOOP Loopback device support is enabled.
- LP Printer support is enabled.
- M68k M68k architecture is enabled.
- These options have more detailed description inside of
- Documentation/arch/m68k/kernel-options.rst.
- MDA MDA console support is enabled.
- MIPS MIPS architecture is enabled.
- MOUSE Appropriate mouse support is enabled.
- MSI Message Signaled Interrupts (PCI).
- MTD MTD (Memory Technology Device) support is enabled.
- NET Appropriate network support is enabled.
- NFS Appropriate NFS support is enabled.
- NUMA NUMA support is enabled.
- OF Devicetree is enabled.
- PARISC The PA-RISC architecture is enabled.
- PCI PCI bus support is enabled.
- PCIE PCI Express support is enabled.
- PCMCIA The PCMCIA subsystem is enabled.
- PNP Plug & Play support is enabled.
- PPC PowerPC architecture is enabled.
- PPT Parallel port support is enabled.
- PS2 Appropriate PS/2 support is enabled.
- PV_OPS A paravirtualized kernel is enabled.
- RAM RAM disk support is enabled.
- RDT Intel Resource Director Technology.
- RISCV RISCV architecture is enabled.
- S390 S390 architecture is enabled.
- SCSI Appropriate SCSI support is enabled.
- A lot of drivers have their options described inside
- the Documentation/scsi/ sub-directory.
- SDW SoundWire support is enabled.
- SECURITY Different security models are enabled.
- SELINUX SELinux support is enabled.
- SERIAL Serial support is enabled.
- SH SuperH architecture is enabled.
- SMP The kernel is an SMP kernel.
- SPARC Sparc architecture is enabled.
- SUSPEND System suspend states are enabled.
- SWSUSP Software suspend (hibernation) is enabled.
- TPM TPM drivers are enabled.
- UMS USB Mass Storage support is enabled.
- USB USB support is enabled.
- USBHID USB Human Interface Device support is enabled.
- V4L Video For Linux support is enabled.
- VGA The VGA console has been enabled.
- VMMIO Driver for memory mapped virtio devices is enabled.
- VT Virtual terminal support is enabled.
- WDT Watchdog support is enabled.
- X86-32 X86-32, aka i386 architecture is enabled.
- X86-64 X86-64 architecture is enabled.
- X86 Either 32-bit or 64-bit x86 (same as X86-32+X86-64)
- X86_UV SGI UV support is enabled.
- XEN Xen support is enabled
- XTENSA xtensa architecture is enabled.
-
-In addition, the following text indicates that the option::
-
- BOOT Is a boot loader parameter.
- BUGS= Relates to possible processor bugs on the said processor.
- KNL Is a kernel start-up parameter.
+is applicable.
Parameters denoted with BOOT are actually interpreted by the boot
loader, and have no meaning to the kernel directly.
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 362ff32252209..5bf1df91607eb 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -1,3 +1,101 @@
+ ACPI ACPI support is enabled.
+ AGP AGP (Accelerated Graphics Port) is enabled.
+ ALSA ALSA sound support is enabled.
+ APIC APIC support is enabled.
+ APM Advanced Power Management support is enabled.
+ APPARMOR AppArmor support is enabled.
+ ARM ARM architecture is enabled.
+ ARM64 ARM64 architecture is enabled.
+ AX25 Appropriate AX.25 support is enabled.
+ CLK Common clock infrastructure is enabled.
+ CMA Contiguous Memory Area support is enabled.
+ DRM Direct Rendering Management support is enabled.
+ DYNAMIC_DEBUG Build in debug messages and enable them at runtime
+ EARLY Parameter processed too early to be embedded in initrd.
+ EDD BIOS Enhanced Disk Drive Services (EDD) is enabled
+ EFI EFI Partitioning (GPT) is enabled
+ EVM Extended Verification Module
+ FB The frame buffer device is enabled.
+ FTRACE Function tracing enabled.
+ GCOV GCOV profiling is enabled.
+ HIBERNATION HIBERNATION is enabled.
+ HW Appropriate hardware is enabled.
+ HYPER_V HYPERV support is enabled.
+ IMA Integrity measurement architecture is enabled.
+ IP_PNP IP DHCP, BOOTP, or RARP is enabled.
+ IPV6 IPv6 support is enabled.
+ ISAPNP ISA PnP code is enabled.
+ ISDN Appropriate ISDN support is enabled.
+ ISOL CPU Isolation is enabled.
+ JOY Appropriate joystick support is enabled.
+ KGDB Kernel debugger support is enabled.
+ KVM Kernel Virtual Machine support is enabled.
+ LIBATA Libata driver is enabled
+ LOONGARCH LoongArch architecture is enabled.
+ LOOP Loopback device support is enabled.
+ LP Printer support is enabled.
+ M68k M68k architecture is enabled.
+ These options have more detailed description inside of
+ Documentation/arch/m68k/kernel-options.rst.
+ MDA MDA console support is enabled.
+ MIPS MIPS architecture is enabled.
+ MOUSE Appropriate mouse support is enabled.
+ MSI Message Signaled Interrupts (PCI).
+ MTD MTD (Memory Technology Device) support is enabled.
+ NET Appropriate network support is enabled.
+ NFS Appropriate NFS support is enabled.
+ NUMA NUMA support is enabled.
+ OF Devicetree is enabled.
+ PARISC The PA-RISC architecture is enabled.
+ PCI PCI bus support is enabled.
+ PCIE PCI Express support is enabled.
+ PCMCIA The PCMCIA subsystem is enabled.
+ PNP Plug & Play support is enabled.
+ PPC PowerPC architecture is enabled.
+ PPT Parallel port support is enabled.
+ PS2 Appropriate PS/2 support is enabled.
+ PV_OPS A paravirtualized kernel is enabled.
+ RAM RAM disk support is enabled.
+ RDT Intel Resource Director Technology.
+ RISCV RISCV architecture is enabled.
+ S390 S390 architecture is enabled.
+ SCSI Appropriate SCSI support is enabled.
+ A lot of drivers have their options described inside
+ the Documentation/scsi/ sub-directory.
+ SDW SoundWire support is enabled.
+ SECURITY Different security models are enabled.
+ SELINUX SELinux support is enabled.
+ SERIAL Serial support is enabled.
+ SH SuperH architecture is enabled.
+ SMP The kernel is an SMP kernel.
+ SPARC Sparc architecture is enabled.
+ SUSPEND System suspend states are enabled.
+ SWSUSP Software suspend (hibernation) is enabled.
+ TPM TPM drivers are enabled.
+ UMS USB Mass Storage support is enabled.
+ USB USB support is enabled.
+ USBHID USB Human Interface Device support is enabled.
+ V4L Video For Linux support is enabled.
+ VGA The VGA console has been enabled.
+ VMMIO Driver for memory mapped virtio devices is enabled.
+ VT Virtual terminal support is enabled.
+ WDT Watchdog support is enabled.
+ X86-32 X86-32, aka i386 architecture is enabled.
+ X86-64 X86-64 architecture is enabled.
+ X86 Either 32-bit or 64-bit x86 (same as X86-32+X86-64)
+ X86_UV SGI UV support is enabled.
+ XEN Xen support is enabled
+ XTENSA xtensa architecture is enabled.
+
+In addition, the following text indicates that the option
+
+ BOOT Is a boot loader parameter.
+ BUGS= Relates to possible processor bugs on the said processor.
+ KNL Is a kernel start-up parameter.
+
+
+Kernel parameters
+
accept_memory= [MM]
Format: { eager | lazy }
default: lazy
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 650/686] nvmet-tcp: validate the TLS handshake timeout
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (648 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 649/686] Documentation/kernel-parameters: Move the kernel build options Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 651/686] nvme-tcp: " Greg Kroah-Hartman
` (35 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Christoph Hellwig,
Yingjie Wang, Keith Busch, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingjie Wang <1075151112@qq.com>
[ Upstream commit e3e7a85730a4b17efa1e2ff4088443c4753be683 ]
tls_handshake_timeout is writable but stored as a signed int. Multiplying
the value by MSEC_PER_SEC and HZ therefore uses signed arithmetic.
With HZ=1000, setting it to 2147484 overflows both multiplications. If
the handshake request is accepted and remains pending, the timer wheel
treats the jiffies delay as already expired and queues the timeout work
on its next advance, while the handshake agent was given about 24.9
days. Negative values such as -1 cause the same immediate kernel-side
timeout.
Store the parameter as an unsigned int and reject values that cannot be
represented both by tls_handshake_args::ta_timeout_ms and by a safe
jiffies delay. Take one snapshot so a concurrent parameter update cannot
give the handshake agent and delayed work different timeouts. Document
the accepted range for built-in use.
Negative and oversized values now fail with -EINVAL. Keep zero valid,
preserving the existing immediate-timeout behavior.
Fixes: 675b453e0241 ("nvmet-tcp: enable TLS handshake upcall")
Cc: stable@vger.kernel.org
Reviewed-by: Hannes Reinecke <hare@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>
Backport notes: Route timeout validation through the existing parameter
setter, preserving the validation of the other parameters and avoiding a
new function. Omit the unrelated dynamic-quirks documentation and retain
its blank separator so the host timeout fix merges cleanly.
Stable-dep-of: 799203afd298 ("nvme-tcp: validate the TLS handshake timeout")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../admin-guide/kernel-parameters.txt | 6 +++++
drivers/nvme/target/tcp.c | 26 ++++++++++++++++---
2 files changed, 28 insertions(+), 4 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 5bf1df91607eb..1b53bc0671249 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4651,6 +4651,12 @@ Kernel parameters
This can be set from sysctl after boot.
See Documentation/admin-guide/sysctl/vm.rst for details.
+
+ nvmet_tcp.tls_handshake_timeout=
+ [NVME] NVMe/TCP target TLS handshake timeout in seconds.
+ Valid values range from 0 to the smaller of
+ UINT_MAX / 1000 and MAX_JIFFY_OFFSET / HZ. Default: 10
+
ohci1394_dma=early [HW,EARLY] enable debugging via the ohci1394 driver.
See Documentation/core-api/debugging-via-ohci1394.rst for more
info.
diff --git a/drivers/nvme/target/tcp.c b/drivers/nvme/target/tcp.c
index b9a904f184892..f478f226e29fd 100644
--- a/drivers/nvme/target/tcp.c
+++ b/drivers/nvme/target/tcp.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/crc32c.h>
#include <linux/err.h>
@@ -41,8 +42,18 @@ static int param_store_val(const char *str, int *val, int min, int max)
return 0;
}
+#ifdef CONFIG_NVME_TARGET_TCP_TLS
+static unsigned int tls_handshake_timeout = 10;
+#endif
+
static int set_params(const char *str, const struct kernel_param *kp)
{
+#ifdef CONFIG_NVME_TARGET_TCP_TLS
+ if (kp->arg == &tls_handshake_timeout)
+ return param_set_uint_minmax(str, kp, 0,
+ min_t(unsigned long, UINT_MAX / MSEC_PER_SEC,
+ MAX_JIFFY_OFFSET / HZ));
+#endif
return param_store_val(str, kp->arg, 0, INT_MAX);
}
@@ -76,8 +87,14 @@ MODULE_PARM_DESC(idle_poll_period_usecs,
/*
* TLS handshake timeout
*/
-static int tls_handshake_timeout = 10;
-module_param(tls_handshake_timeout, int, 0644);
+static const struct kernel_param_ops tls_handshake_timeout_ops = {
+ .set = set_params,
+ .get = param_get_uint,
+};
+
+module_param_cb(tls_handshake_timeout, &tls_handshake_timeout_ops,
+ &tls_handshake_timeout, 0644);
+__MODULE_PARM_TYPE(tls_handshake_timeout, "uint");
MODULE_PARM_DESC(tls_handshake_timeout,
"nvme TLS handshake timeout in seconds (default 10)");
#endif
@@ -1926,6 +1943,7 @@ static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue)
{
int ret = -EOPNOTSUPP;
struct tls_handshake_args args;
+ unsigned int timeout = READ_ONCE(tls_handshake_timeout);
if (queue->state != NVMET_TCP_Q_TLS_HANDSHAKE) {
pr_warn("cannot start TLS in state %d\n", queue->state);
@@ -1939,7 +1957,7 @@ static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue)
args.ta_done = nvmet_tcp_tls_handshake_done;
args.ta_data = queue;
args.ta_keyring = key_serial(queue->port->nport->keyring);
- args.ta_timeout_ms = tls_handshake_timeout * 1000;
+ args.ta_timeout_ms = timeout * MSEC_PER_SEC;
ret = tls_server_hello_psk(&args, GFP_KERNEL);
if (ret) {
@@ -1947,7 +1965,7 @@ static int nvmet_tcp_tls_handshake(struct nvmet_tcp_queue *queue)
pr_err("failed to start TLS, err=%d\n", ret);
} else {
queue_delayed_work(nvmet_wq, &queue->tls_handshake_tmo_work,
- tls_handshake_timeout * HZ);
+ (unsigned long)timeout * HZ);
}
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 651/686] nvme-tcp: validate the TLS handshake timeout
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (649 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 650/686] nvmet-tcp: validate the TLS handshake timeout Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 652/686] watchdog/hpwdt: Refine hpwdt message for UV platform Greg Kroah-Hartman
` (34 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Christoph Hellwig,
Yingjie Wang, Keith Busch, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yingjie Wang <1075151112@qq.com>
[ Upstream commit 799203afd298b1f8e9ee49815eb38f775f211299 ]
tls_handshake_timeout is writable but stored as a signed int. Multiplying
the value by MSEC_PER_SEC and HZ therefore uses signed arithmetic.
With HZ=1000, setting it to 2147484 overflows both multiplications. If
the handshake request is accepted and its completion remains pending,
schedule_timeout() reports a wrong timeout value with a stack dump and
returns zero. The handshake then fails immediately with -ETIMEDOUT,
while the handshake agent was given about 24.9 days. Negative values
such as -1 have the same kernel-side effect.
Store the parameter as an unsigned int and reject values that cannot be
represented both by tls_handshake_args::ta_timeout_ms and by a safe
jiffies delay. Take one snapshot so a concurrent parameter update cannot
give the handshake agent and completion wait different timeouts.
Document the accepted range for built-in use.
wait_for_completion_interruptible_timeout() returns the remaining
jiffies as a long after a successful completion. Keep that result in a
long because an accepted timeout can exceed INT_MAX jiffies on 64-bit
systems.
Negative and oversized values now fail with -EINVAL. Keep zero valid,
preserving the existing immediate-timeout behavior.
Fixes: be8e82caa685 ("nvme-tcp: enable TLS handshake upcall")
Cc: stable@vger.kernel.org
Reviewed-by: Hannes Reinecke <hare@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>
---
.../admin-guide/kernel-parameters.txt | 5 +++
drivers/nvme/host/tcp.c | 34 ++++++++++++++-----
2 files changed, 31 insertions(+), 8 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 1b53bc0671249..e9ffe9c877b1a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4652,6 +4652,11 @@ Kernel parameters
See Documentation/admin-guide/sysctl/vm.rst for details.
+ nvme_tcp.tls_handshake_timeout=
+ [NVME] NVMe/TCP host TLS handshake timeout in seconds.
+ Valid values range from 0 to the smaller of
+ UINT_MAX / 1000 and MAX_JIFFY_OFFSET / HZ. Default: 10
+
nvmet_tcp.tls_handshake_timeout=
[NVME] NVMe/TCP target TLS handshake timeout in seconds.
Valid values range from 0 to the smaller of
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index 190eac661e7da..fad2f2f969a08 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -6,6 +6,7 @@
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/jiffies.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/crc32.h>
@@ -46,9 +47,24 @@ MODULE_PARM_DESC(wq_unbound, "Use unbound workqueue for nvme-tcp IO context (def
/*
* TLS handshake timeout
*/
-static int tls_handshake_timeout = 10;
+static unsigned int tls_handshake_timeout = 10;
#ifdef CONFIG_NVME_TCP_TLS
-module_param(tls_handshake_timeout, int, 0644);
+static int tls_handshake_timeout_set(const char *val,
+ const struct kernel_param *kp)
+{
+ return param_set_uint_minmax(val, kp, 0,
+ min_t(unsigned long, UINT_MAX / MSEC_PER_SEC,
+ MAX_JIFFY_OFFSET / HZ));
+}
+
+static const struct kernel_param_ops tls_handshake_timeout_ops = {
+ .set = tls_handshake_timeout_set,
+ .get = param_get_uint,
+};
+
+module_param_cb(tls_handshake_timeout, &tls_handshake_timeout_ops,
+ &tls_handshake_timeout, 0644);
+__MODULE_PARM_TYPE(tls_handshake_timeout, "uint");
MODULE_PARM_DESC(tls_handshake_timeout,
"nvme TLS handshake timeout in seconds (default 10)");
#endif
@@ -1912,8 +1928,10 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl,
{
int qid = nvme_tcp_queue_id(queue);
int ret;
+ long wait_ret;
struct tls_handshake_args args;
- unsigned long tmo = tls_handshake_timeout * HZ;
+ unsigned int timeout = READ_ONCE(tls_handshake_timeout);
+ unsigned long tmo = (unsigned long)timeout * HZ;
key_serial_t keyring = nvme_keyring_id();
dev_dbg(nctrl->device, "queue %d: start TLS with key %x\n",
@@ -1927,7 +1945,7 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl,
if (nctrl->opts->keyring)
keyring = key_serial(nctrl->opts->keyring);
args.ta_keyring = keyring;
- args.ta_timeout_ms = tls_handshake_timeout * 1000;
+ args.ta_timeout_ms = timeout * MSEC_PER_SEC;
queue->tls_err = -EOPNOTSUPP;
init_completion(&queue->tls_complete);
ret = tls_client_hello_psk(&args, GFP_KERNEL);
@@ -1936,10 +1954,10 @@ static int nvme_tcp_start_tls(struct nvme_ctrl *nctrl,
qid, ret);
return ret;
}
- ret = wait_for_completion_interruptible_timeout(&queue->tls_complete, tmo);
- if (ret <= 0) {
- if (ret == 0)
- ret = -ETIMEDOUT;
+ wait_ret = wait_for_completion_interruptible_timeout(&queue->tls_complete,
+ tmo);
+ if (wait_ret <= 0) {
+ ret = wait_ret < 0 ? -ERESTARTSYS : -ETIMEDOUT;
dev_err(nctrl->device,
"queue %d: TLS handshake failed, error %d\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 652/686] watchdog/hpwdt: Refine hpwdt message for UV platform
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (650 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 651/686] nvme-tcp: " Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 653/686] panic: restore variable arguments to nmi_panic() Greg Kroah-Hartman
` (33 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Steve Wahl, Guenter Roeck,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steve Wahl <steve.wahl@hpe.com>
[ Upstream commit d8207d1e9a36b1a8a461581b2d4073ea28335603 ]
The watchdog hardware the hpwdt driver uses was added to the UV
platform for UV_5, but the logging mentioned by this driver was not
added to the BIOS. When the watchdog fires, the printed message had
the administrators and developers looking for non-existent log files,
and confused about whether a watchdog actually tripped.
Change the message that prints on UV platforms so it doesn't send the
user looking for non-existent logs.
To aid in any future debugging, include all 8 bits of the NMISTAT
register in the output, not just the two bits being used to determine
this was "mynmi". And provide names to the bits in NMISTAT so the
code is easier to understand.
Signed-off-by: Steve Wahl <steve.wahl@hpe.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20260318155005.90271-1-steve.wahl@hpe.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Stable-dep-of: ed9e4c1ff15d ("panic: restore variable arguments to nmi_panic()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/hpwdt.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index ae30e394d176e..ba08189937ec6 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -22,6 +22,7 @@
#include <linux/watchdog.h>
#ifdef CONFIG_HPWDT_NMI_DECODING
#include <asm/nmi.h>
+#include <asm/uv/uv.h>
#endif
#include <linux/crash_dump.h>
@@ -158,24 +159,31 @@ static int hpwdt_set_pretimeout(struct watchdog_device *wdd, unsigned int req)
return 0;
}
-static int hpwdt_my_nmi(void)
-{
- return ioread8(hpwdt_nmistat) & 0x6;
-}
+#define NMISTAT_EASR BIT(0)
+#define NMISTAT_EWDOG BIT(1)
+#define NMISTAT_RTRAP BIT(2)
+#define NMISTAT_DBELL BIT(3)
+#define NMISTAT_EMSWDG BIT(4)
+#define NMISTAT_GPI BIT(5)
+#define NMISTAT_NMIOUT BIT(7)
/*
* NMI Handler
*/
static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
{
- unsigned int mynmi = hpwdt_my_nmi();
- static char panic_msg[] =
+ u8 nmistat = ioread8(hpwdt_nmistat);
+ bool mynmi = (nmistat & (NMISTAT_EWDOG | NMISTAT_RTRAP)) != 0;
+ static char panic_msg_default[] =
"00: An NMI occurred. Depending on your system the reason "
"for the NMI is logged in any one of the following resources:\n"
"1. Integrated Management Log (IML)\n"
"2. OA Syslog\n"
"3. OA Forward Progress Log\n"
"4. iLO Event Log";
+ static char panic_msg_uv[] =
+ "00: A watchdog NMI occurred.";
+ char *panic_msg = is_uv_system() ? panic_msg_uv : panic_msg_default;
if (ulReason == NMI_UNKNOWN && !mynmi)
return NMI_DONE;
@@ -189,7 +197,7 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
hpwdt_ping_ticks(SECS_TO_TICKS(val));
}
- hex_byte_pack(panic_msg, mynmi);
+ hex_byte_pack(panic_msg, nmistat);
nmi_panic(regs, panic_msg);
return NMI_HANDLED;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 653/686] panic: restore variable arguments to nmi_panic()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (651 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 652/686] watchdog/hpwdt: Refine hpwdt message for UV platform Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 654/686] ALSA: hda/realtek: Enable all four speaker amps on Lenovo ThinkBook X G2 IAH Greg Kroah-Hartman
` (32 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bradley Morgan, Andrew Morton,
Petr Mladek, Guenetr Roeck, Sashiko, Wang Jinchao,
Wim Van Sebroeck, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bradley Morgan <brads@mainlining.org>
[ Upstream commit ed9e4c1ff15d5b935f467811541ca0aa6e49c5d0 ]
nmi_panic() used to accept variable arguments until commit ebc41f20d77f
("panic: change nmi_panic from macro to function") flattened it to a final
message string. vpanic() did not exist back then, so the function had to
format through panic("%s", msg).
Bring the variable arguments back and format with vpanic() directly.
The next patch makes nmi_panic() try the panic_force_cpu= redirect
before claiming panic_cpu. panic_try_force_cpu() needs to print the
message but it is used also by panic() which accepts variable argument
list. The string could be formatted only when a CPU gets assigned to
process the redirection. Otherwise, there might be a race when writing
to the `panic_force_buf`.
No current caller passes a string with format specifiers. The closest one
is hpwdt_pretimeout(), which builds panic_msg with hex_byte_pack() and has
only two variants, both plain strings. But the new __printf() annotation
on nmi_panic() would warn with -Wformat-security there because the buffer
is passed directly as the format argument, so switch it to nmi_panic(regs,
"%s", panic_msg).
[pmladek@suse.com: changelog fix]
Link: https://lore.kernel.org/arJxFybmtD7OBIcL@pathway.suse.cz
Link: https://lore.kernel.org/20260916182957.7788-5-brads@mainlining.org
Signed-off-by: Bradley Morgan <brads@mainlining.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Suggested-by: Petr Mladek <pmladek@suse.com>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Cc: Guenetr Roeck <linux@roeck-us.net>
Cc: Sashiko <sashiko-bot@kernel.org>
Cc: Wang Jinchao <wangjinchao600@gmail.com>
Cc: Wim Van Sebroeck <wim@linux-watchdog.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/hpwdt.c | 2 +-
include/linux/panic.h | 3 ++-
kernel/panic.c | 10 ++++++++--
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index ba08189937ec6..32e9ac24e0d5f 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -198,7 +198,7 @@ static int hpwdt_pretimeout(unsigned int ulReason, struct pt_regs *regs)
}
hex_byte_pack(panic_msg, nmistat);
- nmi_panic(regs, panic_msg);
+ nmi_panic(regs, "%s", panic_msg);
return NMI_HANDLED;
}
diff --git a/include/linux/panic.h b/include/linux/panic.h
index 6f972a66c13ee..2ccea58bea810 100644
--- a/include/linux/panic.h
+++ b/include/linux/panic.h
@@ -13,7 +13,8 @@ __printf(1, 2)
void panic(const char *fmt, ...) __noreturn __cold;
__printf(1, 0)
void vpanic(const char *fmt, va_list args) __noreturn __cold;
-void nmi_panic(struct pt_regs *regs, const char *msg);
+__printf(2, 3)
+void nmi_panic(struct pt_regs *regs, const char *fmt, ...);
void check_panic_on_warn(const char *origin);
extern void oops_enter(void);
extern void oops_exit(void);
diff --git a/kernel/panic.c b/kernel/panic.c
index 7f8725f2154b8..e1d0c16fc5266 100644
--- a/kernel/panic.c
+++ b/kernel/panic.c
@@ -360,13 +360,19 @@ EXPORT_SYMBOL(panic_on_other_cpu);
* nmi_panic_self_stop() which can provide architecture dependent code such
* as saving register state for crash dump.
*/
-void nmi_panic(struct pt_regs *regs, const char *msg)
+void nmi_panic(struct pt_regs *regs, const char *fmt, ...)
{
+ va_list args;
+
+ va_start(args, fmt);
+
if (panic_try_start())
- panic("%s", msg);
+ vpanic(fmt, args);
if (panic_on_other_cpu())
nmi_panic_self_stop(regs);
+
+ va_end(args);
}
EXPORT_SYMBOL(nmi_panic);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 654/686] ALSA: hda/realtek: Enable all four speaker amps on Lenovo ThinkBook X G2 IAH
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (652 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 653/686] panic: restore variable arguments to nmi_panic() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 655/686] posix-timers: Handle the timer_[re]arm() return value Greg Kroah-Hartman
` (31 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Evgeny Akhtimirov, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Evgeny Akhtimirov <evgeny@devduty.com>
[ Upstream commit f2293e7b2ddd803b1461e0490f9b2f32089c1dd0 ]
The Lenovo ThinkBook X G2 IAH (MTM 21TU) has an ALC287 codec with four
CS35L41 amplifiers on I2C (CSC3551). It reports codec SSID 17aa:3929,
which it shares with the ThinkBook 13x Gen 5, and PCI SSID 17aa:3842.
Since PCI SSID 17aa:3842 has no quirk entry, the codec SSID matches
ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD. That fixup binds only
two amps (cs35l41-hda.0 and .1), while the CS35L41 configuration table
describes four for 17AA3929. Amps .2 and .3 probe and load firmware,
but they are never bound to the codec, so half of the speakers stay
silent.
Add a ThinkPad-style fixup chain that binds four I2C amps, and match the
laptop by its PCI SSID so the ThinkBook 13x Gen 5 is not affected.
Tested with hda_model=1028:0c4d (alias to ALC287_FIXUP_CS35L41_I2C_4):
all four amps bind, apply their calibration and are runtime-active
during playback.
Cc: stable@vger.kernel.org
Signed-off-by: Evgeny Akhtimirov <evgeny@devduty.com>
Link: https://patch.msgid.link/20261009-thinkbook-x-g2-iah-v1-1-56012188aee0@devduty.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
[ sashal: Replaced the unavailable alc287_fixup_tb_vmaster_led() callback with alc287_fixup_bind_dacs(). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index 68b5648d51119..fabe56399f015 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -3979,6 +3979,8 @@ enum {
ALC245_FIXUP_HP_X360_MUTE_LEDS,
ALC287_FIXUP_THINKPAD_I2S_SPK,
ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_THINKPAD,
+ ALC287_FIXUP_CS35L41_I2C_4_THINKPAD_ACPI,
+ ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_4_THINKPAD,
ALC2XX_FIXUP_HEADSET_MIC,
ALC289_FIXUP_DELL_CS35L41_SPI_2,
ALC294_FIXUP_CS35L41_I2C_2,
@@ -6441,6 +6443,18 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC287_FIXUP_CS35L41_I2C_2_THINKPAD_ACPI,
},
+ [ALC287_FIXUP_CS35L41_I2C_4_THINKPAD_ACPI] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs35l41_fixup_i2c_four,
+ .chained = true,
+ .chain_id = ALC285_FIXUP_THINKPAD_NO_BASS_SPK_HEADSET_JACK,
+ },
+ [ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_4_THINKPAD] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc287_fixup_bind_dacs,
+ .chained = true,
+ .chain_id = ALC287_FIXUP_CS35L41_I2C_4_THINKPAD_ACPI,
+ },
[ALC2XX_FIXUP_HEADSET_MIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc2xx_fixup_headset_mic,
@@ -7579,6 +7593,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x17aa, 0x3827, "Ideapad S740", ALC285_FIXUP_IDEAPAD_S740_COEF),
SND_PCI_QUIRK(0x17aa, 0x3834, "Lenovo IdeaPad Slim 9i 14ITL5", ALC287_FIXUP_YOGA7_14ITL_SPEAKERS),
SND_PCI_QUIRK(0x17aa, 0x383d, "Legion Y9000X 2019", ALC285_FIXUP_LEGION_Y9000X_SPEAKERS),
+ SND_PCI_QUIRK(0x17aa, 0x3842, "ThinkBook X G2 IAH", ALC287_FIXUP_MG_RTKC_CSAMP_CS35L41_I2C_4_THINKPAD),
SND_PCI_QUIRK(0x17aa, 0x3843, "Lenovo Yoga 9i / Yoga Book 9i", ALC287_FIXUP_LENOVO_YOGA_BOOK_9I),
/* Yoga Pro 7 14IMH9 shares PCI SSID 17aa:3847 with Legion 7 16ACHG6;
* use codec SSID to distinguish them
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 655/686] posix-timers: Handle the timer_[re]arm() return value
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (653 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 654/686] ALSA: hda/realtek: Enable all four speaker amps on Lenovo ThinkBook X G2 IAH Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 656/686] posix-timers: Report zero remaining time for disarmed SIGEV_NONE timers Greg Kroah-Hartman
` (30 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Gleixner, Frederic Weisbecker,
Peter Zijlstra (Intel), Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@kernel.org>
[ Upstream commit cfb7fe3fdd4ca1d37da1ed15a1897d4a27c47a8a ]
The [re]arm callbacks will return true when the timer was queued and false
if it was already expired at enqueue time.
In both cases the call sites can trivially queue the signal right there,
when the timer was already expired. That avoids a full round trip through
the hrtimer interrupt.
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Frederic Weisbecker <frederic@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260408114952.198028466@kernel.org
Stable-dep-of: 141a27750ec3 ("posix-timers: Report zero remaining time for disarmed SIGEV_NONE timers")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/time/posix-timers.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 3082129d836c2..3d39f77423afb 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -306,6 +306,8 @@ static bool common_hrtimer_rearm(struct k_itimer *timr)
static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struct k_itimer *timr)
{
+ bool queued;
+
guard(spinlock)(&timr->it_lock);
/*
@@ -319,12 +321,18 @@ static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struct k_it
if (!timr->it_interval || WARN_ON_ONCE(timr->it_status != POSIX_TIMER_REQUEUE_PENDING))
return true;
- timr->kclock->timer_rearm(timr);
- timr->it_status = POSIX_TIMER_ARMED;
+ /* timer_rearm() updates timr::it_overrun */
+ queued = timr->kclock->timer_rearm(timr);
+
timr->it_overrun_last = timr->it_overrun;
timr->it_overrun = -1LL;
++timr->it_signal_seq;
info->si_overrun = timer_overrun_to_int(timr);
+
+ if (queued)
+ timr->it_status = POSIX_TIMER_ARMED;
+ else
+ posix_timer_queue_signal(timr);
return true;
}
@@ -912,9 +920,13 @@ int common_timer_set(struct k_itimer *timr, int flags,
expires = timens_ktime_to_host(timr->it_clock, expires);
sigev_none = timr->it_sigev_notify == SIGEV_NONE;
- kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none);
- if (!sigev_none)
- timr->it_status = POSIX_TIMER_ARMED;
+ if (kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none)) {
+ if (!sigev_none)
+ timr->it_status = POSIX_TIMER_ARMED;
+ } else {
+ /* Timer was already expired, queue the signal */
+ posix_timer_queue_signal(timr);
+ }
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 656/686] posix-timers: Report zero remaining time for disarmed SIGEV_NONE timers
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (654 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 655/686] posix-timers: Handle the timer_[re]arm() return value Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 657/686] PCI: imx6: Avoid dereferencing a NULL clock name Greg Kroah-Hartman
` (29 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hung-Jui Lin, Thomas Gleixner,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hung-Jui Lin <alex.lin.programmer@gmail.com>
[ Upstream commit 141a27750ec3d91ad9d1ad1764ebb5e51b963478 ]
SIGEV_NONE timers are never queued. common_timer_get() emulates their
expiry by computing the remaining time from the stored expiry value.
Because an armed SIGEV_NONE oneshot timer is not queued, its it_status
stays POSIX_TIMER_DISARMED. So common_timer_get() cannot use it_status to
skip a disarmed SIGEV_NONE timer and evaluates the stored expiry value for
all SIGEV_NONE timers.
Disarming a timer with timer_settime() and a zero it_value cancels the
timer and sets it_status to POSIX_TIMER_DISARMED, but leaves the expiry
value unchanged. As a consequence, timer_gettime() on a disarmed SIGEV_NONE
timer reports the remaining time of the previous arming until that time has
passed, instead of zero as POSIX requires for a disarmed timer. Example
with a CLOCK_MONOTONIC timer armed with it_value = 10ms and it_interval =
100ms, then disarmed with an all-zero itimerspec:
armed: it_value = 0.009999000 it_interval = 0.100000000
disarmed: it_value = 0.008700792 it_interval = 0.000000000
SIGEV_SIGNAL timers and SIGEV_NONE CPU timers report zero in the same
situation. All clocks which use common_timer_get() are affected, including
the alarm timer clocks.
Mark SIGEV_NONE timers as POSIX_TIMER_ARMED when they are armed, so that
common_timer_get() returns early for every disarmed timer. Forward
SIGEV_NONE interval timers in common_timer_get() regardless of it_status,
as they are never queued and therefore never forwarded by the expiry code.
After the change the disarmed timer above reports zero. Armed SIGEV_NONE
oneshot and interval timers on CLOCK_MONOTONIC, CLOCK_REALTIME,
CLOCK_BOOTTIME and CLOCK_BOOTTIME_ALARM still report their remaining time,
and the posix_timers selftest passes.
Fixes: becf8b5d00f4 ("[PATCH] hrtimer: convert posix timers completely")
Signed-off-by: Hung-Jui Lin <alex.lin.programmer@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261023151411.28685-1-alex.lin.programmer@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/time/posix-timers.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c
index 3d39f77423afb..03bf012fae539 100644
--- a/kernel/time/posix-timers.c
+++ b/kernel/time/posix-timers.c
@@ -702,16 +702,8 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
if (iv) {
cur_setting->it_interval = ktime_to_timespec64(iv);
} else if (timr->it_status == POSIX_TIMER_DISARMED) {
- /*
- * SIGEV_NONE oneshot timers are never queued and therefore
- * timr->it_status is always DISARMED. The check below
- * vs. remaining time will handle this case.
- *
- * For all other timers there is nothing to update here, so
- * return.
- */
- if (!sig_none)
- return;
+ /* Nothing to update for a disarmed timer */
+ return;
}
now = kc->clock_get_ktime(timr->it_clock);
@@ -721,7 +713,7 @@ void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_setting)
* is a SIGEV_NONE timer move the expiry time forward by intervals,
* so expiry is > now.
*/
- if (iv && timr->it_status != POSIX_TIMER_ARMED)
+ if (iv && (sig_none || timr->it_status != POSIX_TIMER_ARMED))
timr->it_overrun += kc->timer_forward(timr, now);
remaining = kc->timer_remaining(timr, now);
@@ -921,8 +913,15 @@ int common_timer_set(struct k_itimer *timr, int flags,
sigev_none = timr->it_sigev_notify == SIGEV_NONE;
if (kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none)) {
- if (!sigev_none)
- timr->it_status = POSIX_TIMER_ARMED;
+ /*
+ * SIGEV_NONE timers are not queued, but mark them armed
+ * so that common_timer_get() can tell them apart from
+ * disarmed timers. An expired SIGEV_NONE timer stays
+ * armed, which is harmless: common_timer_get() reports
+ * zero remaining time for it and it never reaches the
+ * signal delivery code.
+ */
+ timr->it_status = POSIX_TIMER_ARMED;
} else {
/* Timer was already expired, queue the signal */
posix_timer_queue_signal(timr);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 657/686] PCI: imx6: Avoid dereferencing a NULL clock name
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (655 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 656/686] posix-timers: Report zero remaining time for disarmed SIGEV_NONE timers Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 658/686] mm/huge_memory: split huge PUDs when adjusting VMA boundaries Greg Kroah-Hartman
` (28 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rudi Heitbaum, Manivannan Sadhasivam,
Richard Zhu, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rudi Heitbaum <rudi@heitbaum.com>
[ Upstream commit e60d0d4dfddfac3058753a1c2255251401c92dad ]
of_clk_bulk_get() leaves 'clk_bulk_data->id' as NULL for every clock that
has no matching entry in "clock-names", which is legal: a node may list
more "clocks" phandles than it names. Both scans of the bulk array
dereference that id unconditionally, so such a node oopses during probe.
The loop in imx_pcie_probe() has been wrong since it was written. The
loop in imx_setup_phy_mpll() was not: it read a fixed clks[] whose ids
came from the driver's own clk_names[] and were never NULL, and only
became wrong when the driver moved to the bulk array.
Check 'clk_bulk_data->id' before dereferencing it in both.
Fixes: f6a1fdfc78e2 ("PCI: imx6: Use devm_clk_bulk_get_all() to fetch clocks")
Fixes: d8574ce57d76 ("PCI: imx6: Add external reference clock input mode support")
Signed-off-by: Rudi Heitbaum <rudi@heitbaum.com>
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com>
Acked-by: Richard Zhu <hongxing.zhu@nxp.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/am8iBwJSEhYhWTqk@6cfee64030a6/
Link: https://patch.msgid.link/aqfqE4OLhnN4a1lW@b65e9c1eb12f
[ sashal: Omitted the extref clock-name guard because the corresponding scan is absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/pci/controller/dwc/pci-imx6.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index de09cc2a63112..4235f1fb7b337 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -540,7 +540,7 @@ static int imx_setup_phy_mpll(struct imx_pcie *imx_pcie)
return 0;
for (i = 0; i < imx_pcie->num_clks; i++)
- if (strncmp(clks[i].id, "pcie_phy", 8) == 0)
+ if (clks[i].id && strncmp(clks[i].id, "pcie_phy", 8) == 0)
phy_rate = clk_get_rate(clks[i].clk);
switch (phy_rate) {
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 658/686] mm/huge_memory: split huge PUDs when adjusting VMA boundaries
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (656 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 657/686] PCI: imx6: Avoid dereferencing a NULL clock name Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 659/686] PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register Greg Kroah-Hartman
` (27 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Muhammad Usama Anjum,
Kiryl Shutsemau (Meta), David Hildenbrand (Arm), Sasha Levin
6.18-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>
[ sashal: Replaced vma_test_any() with a direct vma->vm_flags & (VM_PFNMAP | VM_MIXEDMAP) test. ]
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 78fecc3ad5700..24f5887eb48ee 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -3210,16 +3210,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->vm_flags & (VM_PFNMAP | VM_MIXEDMAP)))
+ 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,
@@ -3228,14 +3278,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] 687+ messages in thread
* [PATCH 6.18 659/686] PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (657 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 658/686] mm/huge_memory: split huge PUDs when adjusting VMA boundaries Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 660/686] clk: nuvoton: ma35d1: Keep the clock count in the driver Greg Kroah-Hartman
` (26 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 a77d7cde4524b..f2e2dbae050b2 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -568,6 +568,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 aa27211b68dd1..c01634c0211fd 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -173,6 +173,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] 687+ messages in thread
* [PATCH 6.18 660/686] clk: nuvoton: ma35d1: Keep the clock count in the driver
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (658 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 659/686] 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 6.18 661/686] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Greg Kroah-Hartman
` (25 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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] 687+ messages in thread
* [PATCH 6.18 661/686] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (659 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 660/686] 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 6.18 662/686] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Greg Kroah-Hartman
` (24 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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] 687+ messages in thread
* [PATCH 6.18 662/686] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (660 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 661/686] 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 6.18 663/686] clk: nuvoton: " Greg Kroah-Hartman
` (23 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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] 687+ messages in thread
* [PATCH 6.18 663/686] clk: nuvoton: ma35d1: Add missing WDT/WWDT parent clocks
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (661 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 662/686] 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 6.18 664/686] f2fs: release a removed xattr node in roll-forward recovery Greg Kroah-Hartman
` (22 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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] 687+ messages in thread
* [PATCH 6.18 664/686] f2fs: release a removed xattr node in roll-forward recovery
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (662 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 663/686] clk: nuvoton: " Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 665/686] media: ipu6: Rename pointer to firmware context Greg Kroah-Hartman
` (21 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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: adapted cached-block operations to the existing folio and page-cache APIs ]
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 010f94963ea7d..ad59d52f17aeb 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2851,6 +2851,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] 687+ messages in thread
* [PATCH 6.18 665/686] media: ipu6: Rename pointer to firmware context
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (663 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 664/686] 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 6.18 666/686] media: ipu6: Fix firmware config leak on stream start Greg Kroah-Hartman
` (20 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 b96ae563b82f0..d9b67502dbd26 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys-video.c
@@ -1116,7 +1116,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.
@@ -1149,7 +1149,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 9a9e245edc1a2..a0f209b8141de 100644
--- a/drivers/media/pci/intel/ipu6/ipu6-isys.c
+++ b/drivers/media/pci/intel/ipu6/ipu6-isys.c
@@ -1227,10 +1227,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;
@@ -1339,7 +1339,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 0e2c8b71edfc9..ed38decdd525b 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] 687+ messages in thread
* [PATCH 6.18 666/686] media: ipu6: Fix firmware config leak on stream start
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (664 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 665/686] media: ipu6: Rename pointer to firmware context Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 667/686] mm/vma: avoid broken uffd merge on mremap Greg Kroah-Hartman
` (19 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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] 687+ messages in thread
* [PATCH 6.18 667/686] mm/vma: avoid broken uffd merge on mremap
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (665 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 666/686] 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 6.18 668/686] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA Greg Kroah-Hartman
` (18 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM), Andrew Morton,
shaos, Kiryl Shutsemau (Meta), Gregory Price (Meta), Xueyuan Chen,
Liam R. Howlett, Vlastimil Babka, Jann Horn, Pedro Falcato,
Mike Rapoport, Peter Xu, David Hildenbrand, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 68cb098eadda190783f8f8bdf9fe764df59f7d32 ]
Userfaultfd often causes unexpected interactions within mm, and does so at
the intersection of uffd, mremap() and VMA merging.
When an mremap of a VMA occurs, copy_vma_and_data() calls
mremap_userfaultfd_prep() to notify uffd of this.
However, mremap_userfaultfd_prep() simply drops the UFFD context for the
VMA if the user did not register it for remap, i.e. didn't specify the
UFFD_FEATURE_EVENT_REMAP flag.
This is OK for the VMA itself, as upon page table move, move_ptes() clears
UFFD page table flags, using vma_has_uffd_without_event_remap() to
determine whether to do so.
However, this doesn't account for merging with adjacent VMAs, whose page
tables won't have received this treatment, and thus latent UFFD markers
will be left around.
Worse, it'll break UFFD for any VMAs it is merged with. This is very
surprising behaviour for a user, who will then simply not receive UFFD
events for VMAs they ought to.
Resolve the issue by explicitly checking for this case via
vma_has_uffd_without_event_remap() in vma_merge_copied_range(), the merge
function explicitly designated for mremap() operations.
Also update the userland VMA tests accordingly.
Link: https://lore.kernel.org/20261020-uffd-remap-fix-v1-1-0f34fc181f0a@kernel.org
Fixes: 3cfd22be0ad6 ("userfaultfd: clear flag if remap event not enabled")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: shaos <shawnq1@163.com>
Closes: https://lore.kernel.org/all/20261020110748.959870-1-shawnq1@163.com/
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: Gregory Price (Meta) <gourry@gourry.net>
Reviewed-by: Xueyuan Chen <xueyuan.chen21@gmail.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: Mike Rapoport <rppt@linux.vnet.ibm.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: David Hildenbrand <david@kernel.org>
Cc: <stable@vger.kernel.org>
[ sashal: replaced the inline test stub with a constant-false macro in the existing test harness header ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
mm/vma.c | 5 +++++
tools/testing/vma/vma_internal.h | 2 ++
2 files changed, 7 insertions(+)
diff --git a/mm/vma.c b/mm/vma.c
index 3710cb70ca682..0d4f344956642 100644
--- a/mm/vma.c
+++ b/mm/vma.c
@@ -1145,6 +1145,11 @@ static struct vm_area_struct *vma_merge_copied_range(struct vma_merge_struct *vm
vmg->copied_from = vmg->middle;
vmg->middle = NULL;
+
+ /* If not registered for remap, uffd context will be cleared. */
+ if (vma_has_uffd_without_event_remap(vmg->copied_from))
+ return NULL;
+
return vma_merge_new_range(vmg);
}
diff --git a/tools/testing/vma/vma_internal.h b/tools/testing/vma/vma_internal.h
index f64064ee48587..b736528815bd8 100644
--- a/tools/testing/vma/vma_internal.h
+++ b/tools/testing/vma/vma_internal.h
@@ -802,6 +802,8 @@ static inline bool is_mergeable_vm_userfaultfd_ctx(struct vm_area_struct *vma,
return true;
}
+#define vma_has_uffd_without_event_remap(vma) false
+
static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1,
struct anon_vma_name *anon_name2)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 668/686] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (666 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 667/686] mm/vma: avoid broken uffd merge on mremap Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 669/686] hwmon: (coretemp) Return -ENODATA for invalid temperature readings Greg Kroah-Hartman
` (17 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-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 support for recording bitmap errors and propagating them through the iterator to the ioctl caller. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/iommufd/io_pagetable.c | 2 +-
drivers/iommu/iommufd/iova_bitmap.c | 18 +++++++++++++++++-
include/uapi/linux/iommufd.h | 6 ++++++
3 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/iommufd/io_pagetable.c b/drivers/iommu/iommufd/io_pagetable.c
index 77891d4d65fb1..a6face8a46f58 100644
--- a/drivers/iommu/iommufd/io_pagetable.c
+++ b/drivers/iommu/iommufd/io_pagetable.c
@@ -552,7 +552,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 b5b67a9d3fb35..3a7eca3c7d989 100644
--- a/drivers/iommu/iommufd/iova_bitmap.c
+++ b/drivers/iommu/iommufd/iova_bitmap.c
@@ -116,6 +116,8 @@ struct iova_bitmap {
/* length of the IOVA range for the whole bitmap */
size_t length;
+
+ int err;
};
/*
@@ -384,7 +386,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 +408,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 bdd20666d1eb1..65e564965e98a 100644
--- a/include/uapi/linux/iommufd.h
+++ b/include/uapi/linux/iommufd.h
@@ -775,6 +775,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] 687+ messages in thread
* [PATCH 6.18 669/686] hwmon: (coretemp) Return -ENODATA for invalid temperature readings
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (667 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 668/686] 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 6.18 670/686] crypto: omap - add omap_sham_unregister_algs helper Greg Kroah-Hartman
` (16 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Ricardo Neri,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
[ Upstream commit f63aaa529cbc73146ff0d52235e5479042285cae ]
IA32_THERM_STATUS and IA32_PACKAGE_THERM_STATUS have a valid bit, bit 31.
The Intel SDM documents it only for the former, but the package register
implements it too: x86_pkg_temp_thermal has required it since commit
f1a18a105660 ("Thermal: CPU Package temperature thermal").
This driver checked the bit for both registers as well, until
commit bf6ea084ebb5 ("hwmon: (coretemp) Do not return -EAGAIN for low
temperatures") made it ignore the bit because some CPUs clear it while
the temperature is too low to be measured. Since then, temp%d_input
reports such a reading as a real temperature. Userspace cannot tell it
apart from a genuinely low one.
Fail the read with -ENODATA while the CPU reports the reading as invalid.
On a CPU that clears the bit, reading temp%d_input now fails where it
used to return a low value. sensors(1) shows N/A in its place.
Cc: stable@vger.kernel.org
Suggested-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/all/46f9f319-de71-412f-a424-6cb801478456@roeck-us.net/
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Link: https://patch.msgid.link/20261006-coretemp-enodata-v2-1-64e788acc7dc@linux.intel.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
[ sashal: Adapted the MSR validity check from val.l to eax to use the existing rdmsr_on_cpu() interface. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/hwmon/coretemp.rst | 3 +++
drivers/hwmon/coretemp.c | 21 +++++++++++++++------
2 files changed, 18 insertions(+), 6 deletions(-)
diff --git a/Documentation/hwmon/coretemp.rst b/Documentation/hwmon/coretemp.rst
index c609329e3bc45..6089bee1159f1 100644
--- a/Documentation/hwmon/coretemp.rst
+++ b/Documentation/hwmon/coretemp.rst
@@ -47,6 +47,9 @@ All Sysfs entries are named with their core_id (represented here by 'X').
================= ========================================================
tempX_input Core temperature (in millidegrees Celsius).
+ Reading fails with -ENODATA while the CPU reports the
+ temperature as invalid. Some CPUs do this when the
+ temperature is too low to be measured.
tempX_max All cooling devices should be turned on (on Core2).
tempX_crit Maximum junction temperature (in millidegrees Celsius).
tempX_crit_alarm Set when Out-of-spec bit is set, never clears.
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index ac56319ff90cf..25a9cf8feb311 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -61,6 +61,8 @@ enum coretemp_attr_index {
/*
* Per-Core Temperature Data
+ * @temp_valid: Whether the CPU reported @temp as valid. @temp is not
+ * reported when this is false.
* @tjmax: The static tjmax value when tjmax cannot be retrieved from
* IA32_TEMPERATURE_TARGET MSR.
* @last_updated: The time when the current temperature value was updated
@@ -73,6 +75,7 @@ enum coretemp_attr_index {
*/
struct temp_data {
int temp;
+ bool temp_valid;
int tjmax;
unsigned long last_updated;
unsigned int cpu;
@@ -391,7 +394,8 @@ static ssize_t show_temp(struct device *dev,
{
u32 eax, edx;
struct temp_data *tdata = container_of(devattr, struct temp_data, sd_attrs[ATTR_TEMP]);
- int tjmax;
+ int tjmax, temp;
+ bool valid;
mutex_lock(&tdata->update_lock);
@@ -400,17 +404,22 @@ static ssize_t show_temp(struct device *dev,
if (time_after(jiffies, tdata->last_updated + HZ)) {
rdmsr_on_cpu(tdata->cpu, tdata->status_reg, &eax, &edx);
/*
- * Ignore the valid bit. In all observed cases the register
- * value is either low or zero if the valid bit is 0.
- * Return it instead of reporting an error which doesn't
- * really help at all.
+ * Bit 31 indicates whether the reading is valid. Some CPUs
+ * clear it while the temperature is too low to be measured.
+ * Such a reading is not a temperature. Do not report it.
*/
+ tdata->temp_valid = (eax >> 31) & 1;
tdata->temp = tjmax - ((eax >> 16) & 0xff) * 1000;
tdata->last_updated = jiffies;
}
+ valid = tdata->temp_valid;
+ temp = tdata->temp;
mutex_unlock(&tdata->update_lock);
- return sprintf(buf, "%d\n", tdata->temp);
+
+ if (!valid)
+ return -ENODATA;
+ return sprintf(buf, "%d\n", temp);
}
static int create_core_attrs(struct temp_data *tdata, struct device *dev)
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 670/686] crypto: omap - add omap_sham_unregister_algs helper
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (668 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 669/686] hwmon: (coretemp) Return -ENODATA for invalid temperature readings Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 671/686] crypto: omap-sham - fix crypto engine cleanup Greg Kroah-Hartman
` (15 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Herbert Xu,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <thorsten.blum@linux.dev>
[ Upstream commit c3494e6fbb35579a131de11369b658a59b1323e5 ]
Add a new helper omap_sham_unregister_algs() and replace two for loops
in omap_sham_probe() and omap_sham_remove(), which also ensure
->registered is reset to 0.
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Stable-dep-of: be51ea091c65 ("crypto: omap-sham - fix crypto engine cleanup")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/crypto/omap-sham.c | 27 ++++++++++++++++-----------
1 file changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index ff8aac02994a4..7b3612d097700 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -2041,6 +2041,20 @@ static struct attribute *omap_sham_attrs[] = {
};
ATTRIBUTE_GROUPS(omap_sham);
+static void omap_sham_unregister_algs(const struct omap_sham_pdata *pdata)
+{
+ struct omap_sham_algs_info *alg_info;
+ int i;
+
+ for (i = pdata->algs_info_size - 1; i >= 0; i--) {
+ alg_info = &pdata->algs_info[i];
+
+ crypto_engine_unregister_ahashes(alg_info->algs_list,
+ alg_info->registered);
+ alg_info->registered = 0;
+ }
+}
+
static int omap_sham_probe(struct platform_device *pdev)
{
struct omap_sham_dev *dd;
@@ -2158,10 +2172,7 @@ static int omap_sham_probe(struct platform_device *pdev)
return 0;
err_algs:
- for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
- for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--)
- crypto_engine_unregister_ahash(
- &dd->pdata->algs_info[i].algs_list[j]);
+ omap_sham_unregister_algs(dd->pdata);
err_engine_start:
crypto_engine_exit(dd->engine);
err_engine:
@@ -2182,19 +2193,13 @@ static int omap_sham_probe(struct platform_device *pdev)
static void omap_sham_remove(struct platform_device *pdev)
{
struct omap_sham_dev *dd;
- int i, j;
dd = platform_get_drvdata(pdev);
spin_lock_bh(&sham.lock);
list_del(&dd->list);
spin_unlock_bh(&sham.lock);
- for (i = dd->pdata->algs_info_size - 1; i >= 0; i--)
- for (j = dd->pdata->algs_info[i].registered - 1; j >= 0; j--) {
- crypto_engine_unregister_ahash(
- &dd->pdata->algs_info[i].algs_list[j]);
- dd->pdata->algs_info[i].registered--;
- }
+ omap_sham_unregister_algs(dd->pdata);
cancel_work_sync(&dd->done_task);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 671/686] crypto: omap-sham - fix crypto engine cleanup
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (669 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 670/686] crypto: omap - add omap_sham_unregister_algs helper Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 672/686] irqchip/renesas-rzv2h: Preserve TIEN state in rzv2h_tint_set_type() Greg Kroah-Hartman
` (14 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guangshuo Li, Herbert Xu,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <lgs201920130244@gmail.com>
[ Upstream commit be51ea091c6563158531e8c74e040552fdb1e28c ]
omap_sham_probe() allocates and starts a crypto engine, but the remove
path does not call the matching crypto_engine_exit(). The probe failure
path already performs this cleanup.
crypto_engine_alloc_init() creates a kthread worker for processing
requests. Without crypto_engine_exit() during driver removal, the
worker is left running after the device is removed.
Call crypto_engine_exit() after unregistering the algorithms and before
tearing down the remaining request handling resources. This stops the
engine and destroys its worker.
This issue was found by manual code inspection.
Fixes: 133c3d434d91 ("crypto: omap-sham - convert to use crypto engine")
Cc: stable@vger.kernel.org
Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/crypto/omap-sham.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c
index 7b3612d097700..2cda2e05ab42c 100644
--- a/drivers/crypto/omap-sham.c
+++ b/drivers/crypto/omap-sham.c
@@ -2200,6 +2200,7 @@ static void omap_sham_remove(struct platform_device *pdev)
list_del(&dd->list);
spin_unlock_bh(&sham.lock);
omap_sham_unregister_algs(dd->pdata);
+ crypto_engine_exit(dd->engine);
cancel_work_sync(&dd->done_task);
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_disable(&pdev->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 672/686] irqchip/renesas-rzv2h: Preserve TIEN state in rzv2h_tint_set_type()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (670 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 671/686] crypto: omap-sham - fix crypto engine cleanup Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 673/686] power: supply: ltc2941: Fix of_node reference leak in ltc294x_i2c_probe() Greg Kroah-Hartman
` (13 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Au Dang, Tommaso Merciai,
Thomas Gleixner, Biju Das, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Au Dang <au.dang.jx@renesas.com>
[ Upstream commit 42bedd4af8cd50c32a1560d8744bd22d25be79cc ]
rzv2h_tint_set_type() clears TIEN while switching the TINT source and
then unconditionally sets it again, enabling the interrupt even if it
was disabled before the call.
Restore the previous TIEN state instead of forcing it on.
Fixes: 0d7605e75ac2 ("irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver")
Signed-off-by: Au Dang <au.dang.jx@renesas.com>
Signed-off-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Biju Das <biju.das.jz@bp.renesas.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20261014095927.635132-1-tommaso.merciai.xr@bp.renesas.com
[ sashal: Adjusted context and indentation to fit the existing shared interrupt-chip dispatcher structure. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/irqchip/irq-renesas-rzv2h.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c
index c9f9099a51294..927b5ffa0c7cb 100644
--- a/drivers/irqchip/irq-renesas-rzv2h.c
+++ b/drivers/irqchip/irq-renesas-rzv2h.c
@@ -328,9 +328,9 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq
static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
{
u32 titsr, titsr_k, titsel_n, tien;
+ u32 titsr_cur, tssr_cur, tien_cur;
struct rzv2h_icu_priv *priv;
u32 tssr, tssr_k, tssel_n;
- u32 titsr_cur, tssr_cur;
unsigned int hwirq;
u32 tint, sense;
int tint_nr;
@@ -386,6 +386,8 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
if (tssr_cur == tint && titsr_cur == sense)
return 0;
+ tien_cur = tssr & tien;
+
tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n, priv->info->field_width) | tien);
tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n, priv->info->field_width);
@@ -398,7 +400,7 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
rzv2h_clear_tint_int(priv, hwirq);
- writel_relaxed(tssr | tien, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
+ writel_relaxed(tssr | tien_cur, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 673/686] power: supply: ltc2941: Fix of_node reference leak in ltc294x_i2c_probe()
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (671 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 672/686] irqchip/renesas-rzv2h: Preserve TIEN state in rzv2h_tint_set_type() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 674/686] fbdev: nvidia: Convert to managed PCI and ioremap API Greg Kroah-Hartman
` (12 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wentao Liang, Sebastian Reichel,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <vulab@iscas.ac.cn>
[ Upstream commit 09a29213bf15630e85a375478832b074b2cfc5c8 ]
ltc294x_i2c_probe() takes a reference on the device node with
of_node_get(), but never drops it, so the reference leaks on every
return path, including the success path.
The node is only used to read the battery properties and to set
info->supply_desc.name, so release it after its last use and also on
the lltc,resistor-sense error path.
Fixes: 085bc24d1553 ("Add LTC2941/LTC2943 Battery Gauge Driver")
Cc: stable@vger.kernel.org
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Link: https://patch.msgid.link/20260917142127.2156568-1-vulab@iscas.ac.cn
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
[ sashal: adjusted context to preserve of_property_read_u32() instead of upstream's of_property_read_s32() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/power/supply/ltc2941-battery-gauge.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/power/supply/ltc2941-battery-gauge.c b/drivers/power/supply/ltc2941-battery-gauge.c
index a1ddc4b060ce4..bf0b268b10bfb 100644
--- a/drivers/power/supply/ltc2941-battery-gauge.c
+++ b/drivers/power/supply/ltc2941-battery-gauge.c
@@ -464,9 +464,11 @@ static int ltc294x_i2c_probe(struct i2c_client *client)
/* r_sense can be negative, when sense+ is connected to the battery
* instead of the sense-. This results in reversed measurements. */
ret = of_property_read_u32(np, "lltc,resistor-sense", &r_sense);
- if (ret < 0)
+ if (ret < 0) {
+ of_node_put(np);
return dev_err_probe(&client->dev, ret,
"Could not find lltc,resistor-sense in devicetree\n");
+ }
info->r_sense = r_sense;
ret = of_property_read_u32(np, "lltc,prescaler-exponent",
@@ -477,6 +479,8 @@ static int ltc294x_i2c_probe(struct i2c_client *client)
prescaler_exp = LTC2941_MAX_PRESCALER_EXP;
}
+ of_node_put(np);
+
if (info->id == LTC2943_ID) {
if (prescaler_exp > LTC2943_MAX_PRESCALER_EXP)
prescaler_exp = LTC2943_MAX_PRESCALER_EXP;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 674/686] fbdev: nvidia: Convert to managed PCI and ioremap API
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (672 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 673/686] power: supply: ltc2941: Fix of_node reference leak in ltc294x_i2c_probe() Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 675/686] fbdev: nvidia: Release write-combining handle on probe failure Greg Kroah-Hartman
` (11 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Shixiong Ou, Helge Deller,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shixiong Ou <oushixiong@kylinos.cn>
[ Upstream commit a41961f364bc7aee1611796e7ab5bd687708d770 ]
Fix missing pci_disable_device() in probe and remove.
Use pcim_enable_device(), pcim_request_all_regions(),
devm_ioremap() and devm_ioremap_wc() to replace manual resource
management. Remove all pci_release_regions() and iounmap() calls.
Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
Signed-off-by: Helge Deller <deller@gmx.de>
Stable-dep-of: 8710af6a3520 ("fbdev: nvidia: Release write-combining handle on probe failure")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/video/fbdev/nvidia/nvidia.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
index c9dcc9e899487..f917d569bdbd5 100644
--- a/drivers/video/fbdev/nvidia/nvidia.c
+++ b/drivers/video/fbdev/nvidia/nvidia.c
@@ -1289,7 +1289,7 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
NVTRACE_ENTER();
assert(pd != NULL);
- if (pci_enable_device(pd)) {
+ if (pcim_enable_device(pd)) {
printk(KERN_ERR PFX "cannot enable PCI device\n");
return -ENODEV;
}
@@ -1302,7 +1302,7 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
nvidiafb_fix.mmio_start = pci_resource_start(pd, 0);
nvidiafb_fix.mmio_len = pci_resource_len(pd, 0);
- REGS = ioremap(nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
+ REGS = devm_ioremap(&pd->dev, nvidiafb_fix.mmio_start, nvidiafb_fix.mmio_len);
if (!REGS) {
printk(KERN_ERR PFX "cannot ioremap MMIO base\n");
return -ENODEV;
@@ -1330,7 +1330,7 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
if (info->pixmap.addr == NULL)
goto err_out_kfree;
- if (pci_request_regions(pd, "nvidiafb")) {
+ if (pcim_request_all_regions(pd, "nvidiafb")) {
printk(KERN_ERR PFX "cannot request PCI regions\n");
goto err_out_enable;
}
@@ -1355,7 +1355,7 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
sprintf(nvidiafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);
if (NVCommonSetup(info))
- goto err_out_free_base0;
+ goto err_out_enable;
par->FbAddress = nvidiafb_fix.smem_start;
par->FbMapSize = par->RamAmountKBytes * 1024;
@@ -1375,8 +1375,8 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
par->ScratchBufferStart = par->FbUsableSize - par->ScratchBufferSize;
par->CursorStart = par->FbUsableSize + (32 * 1024);
- info->screen_base = ioremap_wc(nvidiafb_fix.smem_start,
- par->FbMapSize);
+ info->screen_base = devm_ioremap_wc(&pd->dev, nvidiafb_fix.smem_start,
+ par->FbMapSize);
info->screen_size = par->FbUsableSize;
nvidiafb_fix.smem_len = par->RamAmountKBytes * 1024;
@@ -1420,19 +1420,15 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
return 0;
err_out_iounmap_fb:
- iounmap(info->screen_base);
fb_destroy_modelist(&info->modelist);
err_out_free_base1:
fb_destroy_modedb(info->monspecs.modedb);
nvidia_delete_i2c_busses(par);
-err_out_free_base0:
- pci_release_regions(pd);
err_out_enable:
kfree(info->pixmap.addr);
err_out_kfree:
framebuffer_release(info);
err_out:
- iounmap(REGS);
return -ENODEV;
}
@@ -1447,11 +1443,8 @@ static void nvidiafb_remove(struct pci_dev *pd)
unregister_framebuffer(info);
arch_phys_wc_del(par->wc_cookie);
- iounmap(info->screen_base);
fb_destroy_modedb(info->monspecs.modedb);
nvidia_delete_i2c_busses(par);
- iounmap(par->REGS);
- pci_release_regions(pd);
kfree(info->pixmap.addr);
framebuffer_release(info);
NVTRACE_LEAVE();
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 675/686] fbdev: nvidia: Release write-combining handle on probe failure
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (673 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 674/686] fbdev: nvidia: Convert to managed PCI and ioremap API Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 676/686] platform/x86/amd/pmf: Add AMDI0112 ACPI ID Greg Kroah-Hartman
` (10 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
Helge Deller, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
[ Upstream commit 8710af6a35201a6d01b5af8f7e4bad29cc40467f ]
Failures in nvidia_set_fbinfo() or register_framebuffer() leave the handle
from arch_phys_wc_add() allocated. Release it in the shared error path,
as nvidiafb_remove() already does on normal removal.
The missing cleanup was already present in the initial Git import,
when the driver used mtrr_add() directly.
This issue was identified during our ongoing static-analysis research
while reviewing kernel code.
Cc: stable@vger.kernel.org
Assisted-by: LLM
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/video/fbdev/nvidia/nvidia.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/video/fbdev/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
index f917d569bdbd5..aebb81f9ac585 100644
--- a/drivers/video/fbdev/nvidia/nvidia.c
+++ b/drivers/video/fbdev/nvidia/nvidia.c
@@ -1420,6 +1420,7 @@ static int nvidiafb_probe(struct pci_dev *pd, const struct pci_device_id *ent)
return 0;
err_out_iounmap_fb:
+ arch_phys_wc_del(par->wc_cookie);
fb_destroy_modelist(&info->modelist);
err_out_free_base1:
fb_destroy_modedb(info->monspecs.modedb);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 676/686] platform/x86/amd/pmf: Add AMDI0112 ACPI ID
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (674 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 675/686] fbdev: nvidia: Release write-combining handle on probe failure Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 677/686] fb: Add dev_of_fbinfo() helper for optional sysfs support Greg Kroah-Hartman
` (9 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello,
Ilpo Järvinen, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <mario.limonciello@amd.com>
[ Upstream commit 325bcc126cf7a512a0e2da0efddad665f69badac ]
The AMDI0112 ID is used to bind the PMF driver to some platforms.
It doesn't have any Linux side code changes relative to the most
similar AMDI0105.
Cc: stable@vger.kernel.org
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20260826163611.2268377-1-mario.limonciello@amd.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
[ sashal: Adjusted ACPI table context to account for the missing AMDI0109 entry. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/amd/pmf/core.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/platform/x86/amd/pmf/core.c b/drivers/platform/x86/amd/pmf/core.c
index e787480f4df26..c1b369fdf801e 100644
--- a/drivers/platform/x86/amd/pmf/core.c
+++ b/drivers/platform/x86/amd/pmf/core.c
@@ -464,6 +464,7 @@ static const struct acpi_device_id amd_pmf_acpi_ids[] = {
{"AMDI0105", 0},
{"AMDI0107", 0},
{"AMDI0108", 0},
+ {"AMDI0112", 0},
{ }
};
MODULE_DEVICE_TABLE(acpi, amd_pmf_acpi_ids);
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 677/686] fb: Add dev_of_fbinfo() helper for optional sysfs support
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (675 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 676/686] platform/x86/amd/pmf: Add AMDI0112 ACPI ID Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 678/686] fbdev: sh_mobile_lcdc: Make FB_DEVICE dependency optional Greg Kroah-Hartman
` (8 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Helge Deller, Andy Shevchenko,
Chintan Patel, Thomas Zimmermann, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chintan Patel <chintanlike@gmail.com>
[ Upstream commit 39b65316fe9d6d3f730632408ace28d49c5845a4 ]
Add dev_of_fbinfo() to return the framebuffer struct device when
CONFIG_FB_DEVICE is enabled, or NULL otherwise.
This allows fbdev drivers to use sysfs interfaces via runtime checks
instead of CONFIG_FB_DEVICE ifdefs, keeping the code clean while
remaining fully buildable.
Suggested-by: Helge Deller <deller@gmx.de>
Reviewed-by: Helge Deller <deller@gmx.de>
Reviewed-by: Andy Shevchenko <andy@kernel.org>
Signed-off-by: Chintan Patel <chintanlike@gmail.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>
Stable-dep-of: 317a8be73091 ("fbdev: sh_mobile_lcdcfb: Restore the per-overlay sysfs attributes")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/fb.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index f622f5f520cf0..e50fc8f0801e6 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -631,6 +631,15 @@ static inline void unlock_fb_info(struct fb_info *info)
mutex_unlock(&info->lock);
}
+static inline struct device *dev_of_fbinfo(const struct fb_info *info)
+{
+#ifdef CONFIG_FB_DEVICE
+ return info->dev;
+#else
+ return NULL;
+#endif
+}
+
static inline void __fb_pad_aligned_buffer(u8 *dst, u32 d_pitch,
u8 *src, u32 s_pitch, u32 height)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 678/686] fbdev: sh_mobile_lcdc: Make FB_DEVICE dependency optional
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (676 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 677/686] fb: Add dev_of_fbinfo() helper for optional sysfs support Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 679/686] fbdev: sh_mobile_lcdcfb: Restore the per-overlay sysfs attributes Greg Kroah-Hartman
` (7 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Helge Deller, Chintan Patel,
Thomas Zimmermann, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chintan Patel <chintanlike@gmail.com>
[ Upstream commit c2925992232fdc4e90f030b77e7867921db071b5 ]
The sh_mobile_lcdc driver exposes overlay configuration via sysfs, but the
core driver does not require CONFIG_FB_DEVICE.
Make overlay sysfs optional so that the driver can build and operate
even when FB_DEVICE is disabled. The kernel naturally ignores the
missing attribute group, preserving buildability and type safety.
Suggested-by: Helge Deller <deller@gmx.de>
Signed-off-by: Chintan Patel <chintanlike@gmail.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Helge Deller <deller@gmx.de>
Stable-dep-of: 317a8be73091 ("fbdev: sh_mobile_lcdcfb: Restore the per-overlay sysfs attributes")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/video/fbdev/sh_mobile_lcdcfb.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index c6da5a62f8c5f..1b7b9dd19b623 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
@@ -1346,14 +1346,17 @@ static DEVICE_ATTR_RW(overlay_mode);
static DEVICE_ATTR_RW(overlay_position);
static DEVICE_ATTR_RW(overlay_rop3);
-static struct attribute *overlay_sysfs_attrs[] = {
+static struct attribute *overlay_sysfs_attrs[] __maybe_unused = {
&dev_attr_overlay_alpha.attr,
&dev_attr_overlay_mode.attr,
&dev_attr_overlay_position.attr,
&dev_attr_overlay_rop3.attr,
NULL,
};
+
+#ifdef CONFIG_FB_DEVICE
ATTRIBUTE_GROUPS(overlay_sysfs);
+#endif
static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix = {
.id = "SH Mobile LCDC",
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 679/686] fbdev: sh_mobile_lcdcfb: Restore the per-overlay sysfs attributes
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (677 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 678/686] fbdev: sh_mobile_lcdc: Make FB_DEVICE dependency optional Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 680/686] perf python: Free the parse error entries when parsing fails Greg Kroah-Hartman
` (6 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Helge Deller,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 317a8be730919177956be32422ebe00cf7e46710 ]
The ovl_* files documented in
Documentation/ABI/testing/sysfs-devices-platform-sh_mobile_lcdc_fb no
longer exist.
Commit a979182a2453 ("fbdev: lcdcfb: Register sysfs groups through driver
core") moved the attributes from each overlay's framebuffer device to
the platform driver's dev_groups and renamed them overlay_*. There is
now only one set of attributes for the whole LCDC. The callbacks still
expect dev_get_drvdata() to return a struct fb_info, but the platform
device holds struct sh_mobile_lcdc_priv, so they access the wrong
structure.
Restore the documented names and register the group on each overlay's
framebuffer device with device_add_groups(). Remove it with
device_remove_groups() before unregistering the framebuffer. Skip
creation when dev_of_fbinfo(info) is NULL, as the old device_create_file()
calls did.
Drop the CONFIG_FB_DEVICE guard, since the driver already depends on it.
Fixes: a979182a2453 ("fbdev: lcdcfb: Register sysfs groups through driver core")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/video/fbdev/sh_mobile_lcdcfb.c | 39 +++++++++++++++++---------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/drivers/video/fbdev/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index 1b7b9dd19b623..07e1dbcec3afb 100644
--- a/drivers/video/fbdev/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
@@ -1341,22 +1341,24 @@ overlay_rop3_store(struct device *dev, struct device_attribute *attr,
return count;
}
-static DEVICE_ATTR_RW(overlay_alpha);
-static DEVICE_ATTR_RW(overlay_mode);
-static DEVICE_ATTR_RW(overlay_position);
-static DEVICE_ATTR_RW(overlay_rop3);
-
-static struct attribute *overlay_sysfs_attrs[] __maybe_unused = {
- &dev_attr_overlay_alpha.attr,
- &dev_attr_overlay_mode.attr,
- &dev_attr_overlay_position.attr,
- &dev_attr_overlay_rop3.attr,
+static struct device_attribute dev_attr_ovl_alpha =
+ __ATTR(ovl_alpha, 0644, overlay_alpha_show, overlay_alpha_store);
+static struct device_attribute dev_attr_ovl_mode =
+ __ATTR(ovl_mode, 0644, overlay_mode_show, overlay_mode_store);
+static struct device_attribute dev_attr_ovl_position =
+ __ATTR(ovl_position, 0644, overlay_position_show, overlay_position_store);
+static struct device_attribute dev_attr_ovl_rop3 =
+ __ATTR(ovl_rop3, 0644, overlay_rop3_show, overlay_rop3_store);
+
+static struct attribute *overlay_sysfs_attrs[] = {
+ &dev_attr_ovl_alpha.attr,
+ &dev_attr_ovl_mode.attr,
+ &dev_attr_ovl_position.attr,
+ &dev_attr_ovl_rop3.attr,
NULL,
};
-#ifdef CONFIG_FB_DEVICE
ATTRIBUTE_GROUPS(overlay_sysfs);
-#endif
static const struct fb_fix_screeninfo sh_mobile_lcdc_overlay_fix = {
.id = "SH Mobile LCDC",
@@ -1514,9 +1516,10 @@ sh_mobile_lcdc_overlay_fb_unregister(struct sh_mobile_lcdc_overlay *ovl)
{
struct fb_info *info = ovl->info;
- if (info == NULL || info->dev == NULL)
+ if (!info || !dev_of_fbinfo(info))
return;
+ device_remove_groups(dev_of_fbinfo(info), overlay_sysfs_groups);
unregister_framebuffer(ovl->info);
}
@@ -1534,6 +1537,15 @@ sh_mobile_lcdc_overlay_fb_register(struct sh_mobile_lcdc_overlay *ovl)
if (ret < 0)
return ret;
+ /* The framebuffer device is optional, see fb_device_create(). */
+ if (dev_of_fbinfo(info)) {
+ ret = device_add_groups(dev_of_fbinfo(info), overlay_sysfs_groups);
+ if (ret < 0) {
+ unregister_framebuffer(info);
+ return ret;
+ }
+ }
+
dev_info(lcdc->dev, "registered %s/overlay %u as %dx%d %dbpp.\n",
dev_name(lcdc->dev), ovl->index, info->var.xres,
info->var.yres, info->var.bits_per_pixel);
@@ -2641,7 +2653,6 @@ static int sh_mobile_lcdc_probe(struct platform_device *pdev)
static struct platform_driver sh_mobile_lcdc_driver = {
.driver = {
.name = "sh_mobile_lcdc_fb",
- .dev_groups = overlay_sysfs_groups,
.pm = &sh_mobile_lcdc_dev_pm_ops,
},
.probe = sh_mobile_lcdc_probe,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 680/686] perf python: Free the parse error entries when parsing fails
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (678 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 679/686] fbdev: sh_mobile_lcdcfb: Restore the per-overlay sysfs attributes Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 681/686] selftests/landlock: Fix snprintf truncation checks in test files Greg Kroah-Hartman
` (5 subsequent siblings)
685 siblings, 0 replies; 687+ 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
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <acme@redhat.com>
[ Upstream commit 39e0022c89abcdc1a811dfc0aeec2a2b9010b660 ]
pyrf__parse_events() prints the entries parse_events_error__print()
receives with the details of a failed parse, but returns without freeing
them, leaking whatever parse_events_error__handle() allocated, so call
parse_events_error__exit() on both paths, as the other parse_events()
callers do.
The perf test attr core PMU probe takes this failure path on machines
without a core PMU, where the leak then happens on every test run.
Fixes: f081defccd93 ("perf python: Add parse_events function")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/r/sashiko-outbox-173525@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>
[ sashal: adjusted context for a stack-allocated event list using evlist__exit() instead of evlist__put() ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/util/python.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index a65a4d9f8cc83..2fa9670bc51f0 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -2075,9 +2075,11 @@ static PyObject *pyrf__parse_events(PyObject *self, PyObject *args)
evlist__init(&evlist, cpus, threads);
if (parse_events(&evlist, input, &err)) {
parse_events_error__print(&err, input);
+ parse_events_error__exit(&err);
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
+ parse_events_error__exit(&err);
result = pyrf_evlist__from_evlist(&evlist);
evlist__exit(&evlist);
return result;
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 681/686] selftests/landlock: Fix snprintf truncation checks in test files
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (679 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 680/686] perf python: Free the parse error entries when parsing fails Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 682/686] lib/tests: extend cmdline KUnit with next_arg() tests Greg Kroah-Hartman
` (4 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Haofeng Li, Wang Yan,
Günther Noack, Mickaël Salaün, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Yan <wangyan01@kylinos.cn>
[ Upstream commit 8e4c736cffdd6b133f6498e0d40ba60dc6819d43 ]
Commit b566f7a4f0e4 ("selftests/landlock: Fix snprintf truncation checks
in audit helpers") fixed the truncation detection in audit.h by changing
the comparison from ">" to ">=" to correctly handle the edge case where
snprintf returns a value equal to the buffer size.
However, the same pattern exists in ptrace_test.c, audit_test.c, and
net_test.c and was not fixed. snprintf() returns the number of
characters that would have been written, excluding the terminating NUL
byte. When the output is truncated, this return value equals or exceeds
the buffer size. The existing ">" check therefore fails to detect
truncation when the return value equals the buffer size.
Fix these remaining instances to use ">=" for truncation detection,
matching the fix in audit.h.
Fixes: 6a500b22971c ("selftests/landlock: Add tests for audit flags and domain IDs")
Signed-off-by: Haofeng Li <lihaofeng@kylinos.cn>
Signed-off-by: Wang Yan <wangyan01@kylinos.cn>
Reviewed-by: Günther Noack <gnoack@google.com>
Link: https://patch.msgid.link/20260626070016.61049-1-wangyan01@kylinos.cn
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>
[ sashal: Adjusted context for the earlier TCP-specific audit helpers with their existing names and formatting. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/landlock/audit_test.c | 2 +-
tools/testing/selftests/landlock/net_test.c | 4 ++--
tools/testing/selftests/landlock/ptrace_test.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/landlock/audit_test.c b/tools/testing/selftests/landlock/audit_test.c
index dcf63b2f822e9..aa6df1b4d42e6 100644
--- a/tools/testing/selftests/landlock/audit_test.c
+++ b/tools/testing/selftests/landlock/audit_test.c
@@ -31,7 +31,7 @@ static int matches_log_signal(struct __test_metadata *const _metadata,
log_match_len =
snprintf(log_match, sizeof(log_match), log_template, opid);
- if (log_match_len > sizeof(log_match))
+ if (log_match_len >= sizeof(log_match))
return -E2BIG;
return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c
index 8f3a780d354b7..822c23425d15a 100644
--- a/tools/testing/selftests/landlock/net_test.c
+++ b/tools/testing/selftests/landlock/net_test.c
@@ -2067,7 +2067,7 @@ static int matches_log_tcp(const int audit_fd, const char *const blockers,
log_match_len = snprintf(log_match, sizeof(log_match), log_template,
blockers, dir_addr, addr, dir_port);
- if (log_match_len > sizeof(log_match))
+ if (log_match_len >= sizeof(log_match))
return -E2BIG;
return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
@@ -2192,7 +2192,7 @@ static int matches_log_tcp_bound(int audit_fd, const char *const addr,
log_match_len = snprintf(log_match, sizeof(log_match), log_template,
addr, lport, addr, dport);
- if (log_match_len > sizeof(log_match))
+ if (log_match_len >= sizeof(log_match))
return -E2BIG;
return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
diff --git a/tools/testing/selftests/landlock/ptrace_test.c b/tools/testing/selftests/landlock/ptrace_test.c
index 4e356334ecb74..22133c5ae6c56 100644
--- a/tools/testing/selftests/landlock/ptrace_test.c
+++ b/tools/testing/selftests/landlock/ptrace_test.c
@@ -446,7 +446,7 @@ static int matches_log_ptrace(struct __test_metadata *const _metadata,
log_match_len =
snprintf(log_match, sizeof(log_match), log_template, opid);
- if (log_match_len > sizeof(log_match))
+ if (log_match_len >= sizeof(log_match))
return -E2BIG;
return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 682/686] lib/tests: extend cmdline KUnit with next_arg() tests
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (680 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 681/686] selftests/landlock: Fix snprintf truncation checks in test files Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 683/686] lib/cmdline: fix get_options() count and overflow with large ranges Greg Kroah-Hartman
` (3 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shuvam Pandey, Andy Shevchenko,
Neel Natu, Dmitry Antipov, Darrick J. Wong, Kees Cook,
Andrew Morton, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuvam Pandey <shuvampandey1@gmail.com>
[ Upstream commit dcc8a57815534e3844f342b28ecfb6e626a816a0 ]
The cmdline KUnit suite covers get_option() and get_options(), but it
does not exercise next_arg().
Extend the suite with one test for a quoted value containing spaces and
one regression test for a bare quote token after a normal parameter.
The regression test covers the bare quote token path fixed by commit
9847f21225c4 ("lib/cmdline: avoid page fault in next_arg").
[shuvampandey1@gmail.com: extend cmdline next_arg() coverage with mixed tokens]
Link: https://lore.kernel.org/20260316211249.88601-1-shuvampandey1@gmail.com
Link: https://lore.kernel.org/20260316101227.15807-1-shuvampandey1@gmail.com
Signed-off-by: Shuvam Pandey <shuvampandey1@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: Neel Natu <neelnatu@google.com>
Cc: Dmitry Antipov <dmantipov@yandex.ru>
Cc: "Darrick J. Wong" <djwong@kernel.org>
Cc: Kees Cook <kees@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Stable-dep-of: 5d72266218b1 ("lib/cmdline: fix get_options() count and overflow with large ranges")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/tests/cmdline_kunit.c | 62 +++++++++++++++++++++++++++++++++++++++
1 file changed, 62 insertions(+)
diff --git a/lib/tests/cmdline_kunit.c b/lib/tests/cmdline_kunit.c
index c1602f797637b..af44ae9e92c3e 100644
--- a/lib/tests/cmdline_kunit.c
+++ b/lib/tests/cmdline_kunit.c
@@ -139,11 +139,73 @@ static void cmdline_test_range(struct kunit *test)
} while (++i < ARRAY_SIZE(cmdline_test_range_strings));
}
+static void cmdline_test_next_arg_quoted_value(struct kunit *test)
+{
+ char in[] = "foo=\"bar baz\" qux=1";
+ char *next, *param, *val;
+
+ next = next_arg(in, ¶m, &val);
+ KUNIT_EXPECT_STREQ(test, param, "foo");
+ KUNIT_ASSERT_NOT_NULL(test, val);
+ KUNIT_EXPECT_STREQ(test, val, "bar baz");
+ KUNIT_EXPECT_STREQ(test, next, "qux=1");
+
+ next = next_arg(next, ¶m, &val);
+ KUNIT_EXPECT_STREQ(test, param, "qux");
+ KUNIT_ASSERT_NOT_NULL(test, val);
+ KUNIT_EXPECT_STREQ(test, val, "1");
+ KUNIT_EXPECT_STREQ(test, next, "");
+}
+
+static void cmdline_test_next_arg_bare_quote_regression(struct kunit *test)
+{
+ char in[] = "foo=bar \"";
+ char *next, *param, *val;
+
+ next = next_arg(in, ¶m, &val);
+ KUNIT_EXPECT_STREQ(test, param, "foo");
+ KUNIT_ASSERT_NOT_NULL(test, val);
+ KUNIT_EXPECT_STREQ(test, val, "bar");
+ KUNIT_EXPECT_STREQ(test, next, "\"");
+
+ /* This hits the i == 0 quoted-token case fixed by 9847f21225c4. */
+ next = next_arg(next, ¶m, &val);
+ KUNIT_EXPECT_STREQ(test, param, "");
+ KUNIT_EXPECT_PTR_EQ(test, val, NULL);
+ KUNIT_EXPECT_STREQ(test, next, "");
+}
+
+static void cmdline_test_next_arg_mixed_tokens(struct kunit *test)
+{
+ char in[] = "bbb= jjj kkk=\"a=b\"";
+ char *next, *param, *val;
+
+ next = next_arg(in, ¶m, &val);
+ KUNIT_EXPECT_STREQ(test, param, "bbb");
+ KUNIT_ASSERT_NOT_NULL(test, val);
+ KUNIT_EXPECT_STREQ(test, val, "");
+ KUNIT_EXPECT_STREQ(test, next, "jjj kkk=\"a=b\"");
+
+ next = next_arg(next, ¶m, &val);
+ KUNIT_EXPECT_STREQ(test, param, "jjj");
+ KUNIT_EXPECT_NULL(test, val);
+ KUNIT_EXPECT_STREQ(test, next, "kkk=\"a=b\"");
+
+ next = next_arg(next, ¶m, &val);
+ KUNIT_EXPECT_STREQ(test, param, "kkk");
+ KUNIT_ASSERT_NOT_NULL(test, val);
+ KUNIT_EXPECT_STREQ(test, val, "a=b");
+ KUNIT_EXPECT_STREQ(test, next, "");
+}
+
static struct kunit_case cmdline_test_cases[] = {
KUNIT_CASE(cmdline_test_noint),
KUNIT_CASE(cmdline_test_lead_int),
KUNIT_CASE(cmdline_test_tail_int),
KUNIT_CASE(cmdline_test_range),
+ KUNIT_CASE(cmdline_test_next_arg_quoted_value),
+ KUNIT_CASE(cmdline_test_next_arg_bare_quote_regression),
+ KUNIT_CASE(cmdline_test_next_arg_mixed_tokens),
{}
};
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 683/686] lib/cmdline: fix get_options() count and overflow with large ranges
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (681 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 682/686] lib/tests: extend cmdline KUnit with next_arg() tests Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 684/686] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx Greg Kroah-Hartman
` (2 subsequent siblings)
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Armaan Sandhu, Andrew Morton,
Leizhen Zhang, Andy Shevchenko, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armaan Sandhu <armaan.sandhu0504@gmail.com>
[ Upstream commit 5d72266218b1c4dd2917f1df2b86f3b0e0a605c9 ]
get_range() stops writing once the array is full, but get_options() still
advances its index by the whole range. So "1-100" parsed into four ints
reports 99 numbers, and a range like "0-2147483647" wraps the index
negative and writes outside the array.
Stop once a range fills the array, bail out in validation mode before the
count overflows, and saturate the range length in get_range(). Add KUnit
cases; without the fix "0-2147483647" panics the test kernel.
Only root can supply this input, so this is a robustness fix.
[akpm@linux-foundation.org: add additional test case from Leizhen]
Link: https://lore.kernel.org/20261005213945.359905-1-armaan.sandhu0504@gmail.com
Fixes: 22f2e2801799 ("[PATCH] get_options to allow a hypenated range for isolcpus")
Signed-off-by: Armaan Sandhu <armaan.sandhu0504@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Reported-by: Leizhen Zhang <lzsx618@gmail.com>
Reviewed-by: Leizhen Zhang <lzsx618@gmail.com>
Cc: Andy Shevchenko <andriy.shevchenko@intel.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/cmdline.c | 13 ++++++++++++-
lib/tests/cmdline_kunit.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/lib/cmdline.c b/lib/cmdline.c
index 90ed997d95701..f5dc59b3548e9 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -11,6 +11,7 @@
#include <linux/export.h>
#include <linux/kernel.h>
+#include <linux/overflow.h>
#include <linux/string.h>
#include <linux/ctype.h>
@@ -26,7 +27,9 @@ static int get_range(char **str, int *pint, int n)
(*str)++;
upper_range = simple_strtol((*str), NULL, 0);
- inc_counter = upper_range - *pint;
+ /* Keep the sign of the result when the difference doesn't fit */
+ if (check_sub_overflow(upper_range, *pint, &inc_counter))
+ inc_counter = upper_range < *pint ? -1 : INT_MAX;
for (x = *pint; n && x < upper_range; x++, n--)
*pint++ = x;
return inc_counter;
@@ -122,6 +125,14 @@ char *get_options(const char *str, int nints, int *ints)
range_nums = get_range((char **)&str, pint, n);
if (range_nums < 0)
break;
+ /* The range didn't fit, so the array is full */
+ if (!validate && range_nums > n) {
+ i = nints;
+ break;
+ }
+ /* Leave room for the upper number of the range */
+ if (range_nums >= INT_MAX - i)
+ break;
/*
* Decrement the result by one to leave out the
* last number in the range. The next iteration
diff --git a/lib/tests/cmdline_kunit.c b/lib/tests/cmdline_kunit.c
index af44ae9e92c3e..74c4b5ea32250 100644
--- a/lib/tests/cmdline_kunit.c
+++ b/lib/tests/cmdline_kunit.c
@@ -139,6 +139,44 @@ static void cmdline_test_range(struct kunit *test)
} while (++i < ARRAY_SIZE(cmdline_test_range_strings));
}
+static const struct {
+ const char *in;
+ int parsed[4];
+ int validated;
+} cmdline_test_range_overflow_cases[] = {
+ { "1-100", { 3, 1, 2, 3, }, 100, },
+ { "1,5-100,7", { 3, 1, 5, 6, }, 98, },
+ { "1-2147483646", { 3, 1, 2, 3, }, 2147483646, },
+ { "0-2147483647", { 3, 0, 1, 2, }, 0, },
+ { "-5-2147483647", { 3, -5, -4, -3, }, 0, },
+ { "2147483647--5", { 0, 2147483647, }, 0, },
+ { "1,0-2147483647", { 3, 1, 0, 1, }, 1, },
+};
+
+static void cmdline_test_range_overflow(struct kunit *test)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(cmdline_test_range_overflow_cases); i++) {
+ const char *in = cmdline_test_range_overflow_cases[i].in;
+ const int *e = cmdline_test_range_overflow_cases[i].parsed;
+ /* Two guard elements past the array handed to get_options() */
+ int r[ARRAY_SIZE(cmdline_test_range_overflow_cases[0].parsed) + 2];
+ int n;
+
+ memset(r, 0, sizeof(r));
+ get_options(in, ARRAY_SIZE(r) - 2, r);
+ for (j = 0; j < ARRAY_SIZE(r) - 2; j++)
+ KUNIT_EXPECT_EQ_MSG(test, r[j], e[j], "Pattern: %s at %u", in, j);
+ for (; j < ARRAY_SIZE(r); j++)
+ KUNIT_EXPECT_EQ_MSG(test, r[j], 0, "Pattern: %s out of bound at %u", in, j);
+
+ get_options(in, 0, &n);
+ KUNIT_EXPECT_EQ_MSG(test, n, cmdline_test_range_overflow_cases[i].validated,
+ "Pattern: %s (validated)", in);
+ }
+}
+
static void cmdline_test_next_arg_quoted_value(struct kunit *test)
{
char in[] = "foo=\"bar baz\" qux=1";
@@ -203,6 +241,7 @@ static struct kunit_case cmdline_test_cases[] = {
KUNIT_CASE(cmdline_test_lead_int),
KUNIT_CASE(cmdline_test_tail_int),
KUNIT_CASE(cmdline_test_range),
+ KUNIT_CASE(cmdline_test_range_overflow),
KUNIT_CASE(cmdline_test_next_arg_quoted_value),
KUNIT_CASE(cmdline_test_next_arg_bare_quote_regression),
KUNIT_CASE(cmdline_test_next_arg_mixed_tokens),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 684/686] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (682 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 683/686] lib/cmdline: fix get_options() count and overflow with large ranges Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 685/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook 7 17-dc0xxx Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 686/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook X Flip 14-fm0xxx Greg Kroah-Hartman
685 siblings, 0 replies; 687+ 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
6.18-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 insertion context to follow the 8BD6 board entry instead of 8DC2 ]
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 209ac43f9e31e..f7507446494b1 100644
--- a/sound/soc/amd/yc/acp6x-mach.c
+++ b/sound/soc/amd/yc/acp6x-mach.c
@@ -682,6 +682,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] 687+ messages in thread
* [PATCH 6.18 685/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook 7 17-dc0xxx
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (683 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 684/686] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 686/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook X Flip 14-fm0xxx Greg Kroah-Hartman
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jaeho Cho, Takashi Iwai, Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaeho Cho <jaeho2025@gmail.com>
[ Upstream commit 1c4f6202876a74e752a8cfd3696955f761671c7a ]
The HP OmniBook 7 Laptop 17-dc0xxx (SSID 103c:8d9c) has mute and
mic-mute LEDs on its F6 and F9 keys, but neither lights up. Its quirk
entry only sets up the two CS35L41 amplifiers, so no LED control is
registered for either key.
Writing to the ALC245 by hand with hda-verb, the mute LED responds to
COEF 0x0b bits 2-3 and the mic-mute LED to GPIO 0x04, lit when the pin
is low. That appears to match what ALC245_FIXUP_HP_X360_MUTE_LEDS
already does, so add a fixup that chains the two-amp I2C setup to it
and use it for this model.
Tested on 7.2.4 with the patched module: hda::mute and hda::micmute
are registered, and both LEDs follow the speaker and microphone mute
state, including from the F6 and F9 keys.
Signed-off-by: Jaeho Cho <jaeho2025@gmail.com>
Link: https://patch.msgid.link/20260914142445.3476212-1-jaeho2025@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Stable-dep-of: c80286aaa4ac ("ALSA: hda/realtek: Enable mute LEDs on HP OmniBook X Flip 14-fm0xxx")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/codecs/realtek/alc269.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c
index fabe56399f015..ebeb6297f4715 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -3952,6 +3952,7 @@ enum {
ALC287_FIXUP_LEGION_16ACHG6,
ALC287_FIXUP_CS35L41_I2C_2,
ALC287_FIXUP_CS35L41_I2C_2_HP_GPIO_LED,
+ ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS,
ALC287_FIXUP_CS35L41_I2C_4,
ALC245_FIXUP_CS35L41_SPI_1,
ALC245_FIXUP_CS35L41_SPI_2,
@@ -6234,6 +6235,12 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true,
.chain_id = ALC285_FIXUP_HP_MUTE_LED,
},
+ [ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS] = {
+ .type = HDA_FIXUP_FUNC,
+ .v.func = cs35l41_fixup_i2c_two,
+ .chained = true,
+ .chain_id = ALC245_FIXUP_HP_X360_MUTE_LEDS,
+ },
[ALC287_FIXUP_CS35L41_I2C_4] = {
.type = HDA_FIXUP_FUNC,
.v.func = cs35l41_fixup_i2c_four,
@@ -7143,7 +7150,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8d92, "HP ZBook Firefly 16 G12", ALC285_FIXUP_HP_GPIO_LED),
SND_PCI_QUIRK(0x103c, 0x8dcd, "HP Victus 15-fa2xxx", ALC245_FIXUP_HP_MUTE_LED_COEFBIT),
SND_PCI_QUIRK(0x103c, 0x8d9b, "HP 17 Turbine OmniBook 7 UMA", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x103c, 0x8d9c, "HP 17 Turbine OmniBook 7 DIS", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8d9c, "HP 17 Turbine OmniBook 7 DIS", ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS),
SND_PCI_QUIRK(0x103c, 0x8d9d, "HP 17 Turbine OmniBook X UMA", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8d9e, "HP 17 Turbine OmniBook X DIS", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8d9f, "HP 14 Cadet (x360)", ALC287_FIXUP_CS35L41_I2C_2),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
* [PATCH 6.18 686/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook X Flip 14-fm0xxx
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
` (684 preceding siblings ...)
2026-11-13 15:53 ` [PATCH 6.18 685/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook 7 17-dc0xxx Greg Kroah-Hartman
@ 2026-11-13 15:53 ` Greg Kroah-Hartman
685 siblings, 0 replies; 687+ messages in thread
From: Greg Kroah-Hartman @ 2026-11-13 15:53 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches,
José Miguel Castellanos Valladolid, Takashi Iwai,
Sasha Levin
6.18-stable review patch. If anyone has any objections, please let me know.
------------------
From: José Miguel Castellanos Valladolid <josstamy@gmail.com>
[ Upstream commit c80286aaa4acd52f9bd0b0d4914d2069fe6ba3a8 ]
The HP OmniBook X Flip Laptop 14-fm0xxx (subsystem ID 0x103c8d9f, ALC245
with two CS35L41 amplifiers over I2C) is currently handled by
ALC287_FIXUP_CS35L41_I2C_2. That binds the amplifiers but does not set up
the mute LEDs, so neither the speaker mute key LED nor the microphone mute
key LED lights up under Linux. With that fixup the codec GPIOs stay
disabled (IO[0..2] enable=0).
Switch the entry to ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS, which chains
cs35l41_fixup_i2c_two with ALC245_FIXUP_HP_X360_MUTE_LEDS. This keeps the
amplifier setup and adds the speaker mute LED through the ALC245 COEF
register and the mic mute LED through codec GPIO2. It is the same fixup
already used for the 17 Turbine OmniBook 7 DIS (0x103c8d9c).
Tested on the affected laptop with v7.2.11 using the equivalent
ALC245_FIXUP_HP_ENVY_X360_15_FH0XXX fixup, which has the identical
cs35l41_fixup_i2c_two + ALC245_FIXUP_HP_X360_MUTE_LEDS chain: hda::mute
and hda::micmute LED class devices appear and both key LEDs light up
when muting.
Fixes: 29951021367f ("ALSA: hda/realtek: Add support for various HP Laptops using CS35L41 HDA")
Cc: stable@vger.kernel.org
Signed-off-by: José Miguel Castellanos Valladolid <josstamy@gmail.com>
Link: https://patch.msgid.link/20261017050615.14481-1-josstamy@gmail.com
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 ebeb6297f4715..7c89b3796e1b9 100644
--- a/sound/hda/codecs/realtek/alc269.c
+++ b/sound/hda/codecs/realtek/alc269.c
@@ -7153,7 +7153,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x8d9c, "HP 17 Turbine OmniBook 7 DIS", ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS),
SND_PCI_QUIRK(0x103c, 0x8d9d, "HP 17 Turbine OmniBook X UMA", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8d9e, "HP 17 Turbine OmniBook X DIS", ALC287_FIXUP_CS35L41_I2C_2),
- SND_PCI_QUIRK(0x103c, 0x8d9f, "HP 14 Cadet (x360)", ALC287_FIXUP_CS35L41_I2C_2),
+ SND_PCI_QUIRK(0x103c, 0x8d9f, "HP 14 Cadet (x360)", ALC287_FIXUP_CS35L41_I2C_2_HP_MUTE_LEDS),
SND_PCI_QUIRK(0x103c, 0x8da0, "HP 16 Clipper OmniBook 7(X360)", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8da1, "HP 16 Clipper OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
SND_PCI_QUIRK(0x103c, 0x8da7, "HP 14 Enstrom OmniBook X", ALC287_FIXUP_CS35L41_I2C_2),
--
2.53.0
^ permalink raw reply related [flat|nested] 687+ messages in thread
end of thread, other threads:[~2026-11-13 17:26 UTC | newest]
Thread overview: 687+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-13 15:42 [PATCH 6.18 000/686] 6.18.64-rc1 review Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 001/686] smb: client: validate the data area in SMB2_read() Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 002/686] ALSA: x86: hdmi: fix chmap array missing terminator entry Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 003/686] cxl/features: Ensure that count is set before access to ent[] __counted_by() Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 004/686] backing-file: always end a queued write Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 005/686] nvmet-rdma: fix out-of-bounds write in nvmet_rdma_map_sgl_inline() Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 006/686] crypto: sa2ul - Fix HMAC key preparation Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 007/686] fsverity: Tell LSMs about signature only after verity is enabled Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 008/686] Bluetooth: L2CAP: Reject signalling responses in invalid states Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 009/686] Bluetooth: L2CAP: Only accept connection responses to outstanding requests Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 010/686] Bluetooth: L2CAP: Ignore connection responses with wrong ident Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 011/686] smb: client: Avoid leaking sensitive data to the heap in connect.c Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 012/686] smb: client: hold server info until cifsd exits Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 013/686] smb: move smb_sockaddr_in and smb_sockaddr_in6 to common/smb2pdu.h Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 014/686] smb: move create_durable_req_v2 " Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 015/686] smb: move create_durable_handle_reconnect_v2 " Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 016/686] smb: move create_durable_rsp_v2 " Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 017/686] smb: move some duplicate definitions " Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 018/686] smb: move list of FileSystemAttributes to common/fscc.h Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 019/686] smb: move some duplicate struct definitions " Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 020/686] smb: client: fix OOB read of the resume name sent in TRANS2_FIND_NEXT2 Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 021/686] smb: client: fix OOB read in the SMB_FIND_FILE_UNIX name scan Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 022/686] smb: client: reject short SESSION_SETUP responses Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 023/686] smb: client: require stable pages for SMB compression Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 024/686] mm: remove !root_reclaim checking in should_abort_scan() Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 025/686] smb: client: validate SMB1 EA list bounds before parsing Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 026/686] xfs: break out xattr entry checks into separate functions Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 027/686] xfs: check for buffer overruns when examining local/remote xattr entries Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 028/686] xfs: refactor directory data block walking loops in scrub Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 029/686] xfs: improve dirent bounds checking in scrub and repair Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 030/686] NFSv4/pnfs: bound the CB_NOTIFY_DEVICEID array count before allocating Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 031/686] smb: client: bound POSIX lock data area by response length Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 032/686] smb: align durable reconnect v2 context to 8 byte boundary Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 033/686] NFSD: Replace nfsd_write()s "stable" argument with "iocb_flags" Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 034/686] NFSD: Move version-specific ACCESS maps into per-version code Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 035/686] NFSD: map fh_verify() status codes for NFS_ACLv2 replies Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 036/686] NFSD/blocklayout: Extract extent mapping from proc_layoutget Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 037/686] exportfs: Complete kernel-doc for struct export_operations Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 038/686] exportfs: split out the ops for layout-based block device access Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 039/686] exportfs,nfsd: rework checking for layout-based block device access support Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 040/686] nfsd: dont offer flexfiles layouts when NFSv3 isnt being served Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 041/686] NFSD: report listener creation failures through extack Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 042/686] SUNRPC: report local rpcbind calls that get no answer Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 043/686] NFSD: stop registering with rpcbind after a failure in listener_set Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 044/686] NFS/localio: detect a short read or write before the iterator has moved Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 045/686] NFSD: Count the delegations held by each client Greg Kroah-Hartman
2026-11-13 15:42 ` [PATCH 6.18 046/686] NFSD: Send a meaningful CB_RECALL_ANY keep count Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 047/686] NFSD: Move the cld upcall message out of the callers stack frame Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 048/686] NFSD: Complete a cld upcall when the daemon closes the pipe Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 049/686] NFSD: Complete a cld upcall when copying its reply fails Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 050/686] KVM: nSVM: Reject KVM_SET_NESTED_STATE if L1 has EFER.LMA=1 && EFER.LME=0 Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 051/686] KVM: Harden and prepare for modifying existing guest_memfd memslots Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 052/686] KVM: Only bind memslot to guest_memfd instance for CREATE operations Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 053/686] KVM: guest_memfd: take the invalidate lock when unbinding a dying file Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 054/686] KVM: TDX: Stuff exit_reason with UNDEFINED on wait_for_sept_zap return Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 055/686] KVM: TDX: Set bits 31:16 to 0 and use UNDEFINED when synthesizing exit reason Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 056/686] KVM: TDX: Dont assume exit_reason[31:16] is all-0 in tdx_to_vmx_exit_reason() Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 057/686] ksmbd: look up stream size by exact xattr name Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 058/686] wifi: brcmfmac: cfg80211: Report port_authorized for 4-way HS offload Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 059/686] mlxsw: Initialize register query payloads Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 060/686] io_uring/cancel: drop sqd->lock while SQPOLL waits Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 061/686] io_uring/sqpoll: dont attach to a thread that is canceling Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 062/686] io_uring/sqpoll: dont set IO_SQ_THREAD_SHOULD_STOP on thread exit Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 063/686] io_uring/sqpoll: do the return-to-userspace work in the SQPOLL thread Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 064/686] io_uring/cancel: count all requests that a CANCEL_ALL cancels Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 065/686] io_uring/poll: cancel all matching requests in one pass Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 066/686] io_uring/poll: dont poll a writer for a read side hangup Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 067/686] io_uring/poll: dont poll a writer for urgent data Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 068/686] io_uring/rsrc: hold uring_lock across index-alloc put_user Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 069/686] fsverity: Explicitly require FMODE_READ to retrieve hashes Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 070/686] xor: add missing vzeroupper to AVX code Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 071/686] raid6: add missing vzeroupper to AVX-512 code Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 072/686] mm/damon/core: skip applying scheme if region split for quota fails Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 073/686] mm/damon/core: handle uninitialized damos_quota_goal->last_psi_total Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 074/686] mm/damon/core: remove unreachable damos charge_{target,addr}_from Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 075/686] mm/damon/core: filter out damos address filter-split failed region Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 076/686] rust: bug: pass TAINT_WARN to warn_slowpath_fmt() on UML Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 077/686] rust: bug: update the SAFETY comment for " Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 078/686] wifi: rtw88: TX report with long timeout for non-PCIE devices Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 079/686] ACPI: CPPC: Validate FFH register fields before hardware access Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 080/686] ACPI: CPPC: Propagate errors from cross-CPU FFH calls Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 081/686] ACPI: CPPC: Accept requests to retain immutable autonomous selection Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 082/686] writeback: keep cleanup_offline_cgwb()s scan out of syncs Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 083/686] pppoe: delete session hash entries by pointer match Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 084/686] xfs: reinitialize dquot block if non-first dquot cant load Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 085/686] xfs: forcibly reset quota timers when upgrading to bigtime during repair Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 086/686] smb: client: reclaim credits for decrypted reads with no matching mid Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 087/686] smb: client: reject FIND data areas that run past the received response Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 088/686] raid6: add missing vzeroupper to AVX2 code Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 089/686] mtd: rawnand: ndfc: use ioread32be/iowrite32be and allow COMPILE_TEST Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 090/686] mtd: rawnand: ndfc: add CONFIG_OF dependency Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 091/686] mtd: rawnand: ndfc: fix gcc uninitialized var Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 092/686] mtd: rawnand: ndfc: use devm_platform_ioremap_resource() Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 093/686] net: bgmac: enable interrupts only after NAPI is ready Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 094/686] ksmbd: fix tree connection use-after-free in smb2_tree_connect() Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 095/686] nfsd: shorten extack string returned with dodgy listener Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 096/686] s390/vmcp: Initialize full session info to zero Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 097/686] PCI: rcar-gen4: Limit Max_Read_Request_Size to 256 Bytes Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 098/686] wifi: mt76: mt792x: fix negative errno truncation in offload capability Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 099/686] hwmon: (nct6775) Add ASUS ROG STRIX X870E-H GAMING WIFI7 Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 100/686] hwmon: (nct6775) Add ASUS X870/W480 to WMI monitoring list Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 101/686] wifi: mac80211: queue frames while off-channel Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 102/686] media: uvcvideo: Add autosuspend quirk for AVerMedia Live Gamer HD 2 Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 103/686] media: uvcvideo: Force UVC version for Avermedia GC515 Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 104/686] mkiss: size the frame buffers for worst-case KISS escaping Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 105/686] mkiss: dont use a tty write error as a byte count Greg Kroah-Hartman
2026-11-13 15:43 ` [PATCH 6.18 106/686] bpqether: leave the Ethernet devices queue and counters alone Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 107/686] bpqether: fix truncated /proc/net/bpqether on partial reads Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 108/686] rose: arm the neighbour timers with mod_timer() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 109/686] netrom: ignore a BPQ transport timeout below the sysctl minimum Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 110/686] rose: dont give the same LCI to two calls placed at the same time Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 111/686] ax25: dont create a second connection for a link on an incoming SABM Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 112/686] ax25: free a closed socket when its device goes down Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 113/686] mkiss: restart the transmit queue when the interface is opened Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 114/686] 6pack: " Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 115/686] ax25: dont build a frame header from an uninitialised digipeater list Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 116/686] ax25: dont take a reference on a gone device in ax25_accept() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 117/686] ax25: dont copy an uninitialised address to recvmsg()s caller Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 118/686] ax25: free the old digipeater path of a listed socket under ax25_list_lock Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 119/686] ax25: put an incoming connection on the listeners queue once it is set up Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 120/686] ax25: dont test the socket flags of a connection that has no socket Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 121/686] ax25: free the copy of an IP packet that ax25_send_frame() turned down Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 122/686] ax25: dont leave half a message on a connection when fragmenting fails Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 123/686] ax25: make 16 the smallest maximum_packet_length of a port Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 124/686] ax25: keep the window below 8 when a socket goes back to modulo 8 Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 125/686] ax25: let a socket connect again after a failed or ended connection Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 126/686] ax25: dont let connect() find its own socket when calling the same station Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 127/686] netrom: dont convert the maximum number of tries to jiffies Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 128/686] netrom: dont leak frames in nr_route_frame() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 129/686] netrom: use the more flag of each frame taken from the resequencing queue Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 130/686] netrom: give a frame back intact when it cannot be delivered Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 131/686] netrom: dont give the same circuit ID to two sockets Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 132/686] netrom: return the peer node in the address given by recvmsg() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 133/686] netrom: keep the selected route when a route of a node is removed Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 134/686] netrom: drop a frame received with a TTL of 0 Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 135/686] netrom: check the window size given by the peer Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 136/686] netrom: dont send part of a message that cannot be fragmented whole Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 137/686] netrom: disconnect sockets under their lock when a device goes down Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 138/686] netrom: only update the BPQ extension flag on circuit set-up frames Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 139/686] rose: hold the listener while a Call Request is queued on it Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 140/686] rose: hold the socket a received frame is delivered to Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 141/686] rose: report a timed out call to connect() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 142/686] rose: drop the neighbour reference once when a cleared socket is closed Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 143/686] rose: swap the AX.25 connection of a neighbour under a lock Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 144/686] rose: give the sysctl timer limits in milliseconds Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 145/686] mm: page_alloc: make defrag_mode retries follow the promoted order Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 146/686] devtmpfs: make devtmpfs_context_ops static Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 147/686] devtmpfs: restore mount option reconfiguration on get_tree Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 148/686] mm/damon/sysfs-schemes: read sysfs_filter->sz_range only once Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 149/686] media: microchip-isc: fix WB offset and gain register field masking Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 150/686] media: require two-byte Cypress type 04 records Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 151/686] media: adv748x: Fix endpoint reference leaks on probe failure Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 152/686] hwmon: (lm70) Fix rounding of negative temperatures Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 153/686] iio: pressure: dps310: fix CFG_REG bit definitions Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 154/686] media: mediatek: jpeg: Avoid context access after job finish Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 155/686] PCI/AER: Fix memory leak in aer_recover_work_func() when pci_dev is missing Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 156/686] mm/memcontrol: fix data-race on reading jiffies_64 Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 157/686] KVM: arm64: timers: Compute an offset-applied CVAL from the current count Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 158/686] wifi: mt76: take rcu_read_lock in the USB/SDIO tx completion path Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 159/686] mm/page_counter: avoid integer overflow in effective_protection() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 160/686] ACPI: APEI: accumulate the queued flag across error sections Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 161/686] fbdev: core: Initialize modelist in framebuffer_alloc() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 162/686] mfd: ab8500: Fix child device leaks on probe failure Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 163/686] Bluetooth: selftest: Pin module for selftest debugfs file operations Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 164/686] cxl/events: Test CME counter expiry with equality, not bitwise AND Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 165/686] tracing: Add the bucket size to expr_field_str() Greg Kroah-Hartman
2026-11-13 15:44 ` [PATCH 6.18 166/686] net: erspan: set lltx to avoid sch_direct_xmit deadlock Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 167/686] rds: fix out-of-bounds conn_path walks via handshake exthdrs Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 168/686] gpio: pca953x: Preserve wakeup accounting on parent IRQ failure Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 169/686] f2fs: dont use truncate_inode_pages_final() on live inodes Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 170/686] scsi: ufs: bsg: Validate request_len before accessing request Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 171/686] scsi: ufs: bsg: Reject UIC commands with a non-zero result byte Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 172/686] scsi: handle out-of-range SG_SET_TIMEOUT values Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 173/686] posix-timers: Accept NULL clock_getres() output in stubs Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 174/686] tick/nohz: Reevaluate the tick for kicks flushed outside hardirq Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 175/686] ipmr, ip6mr: validate packets injected into the register vif on xmit Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 176/686] ipmr: drop packets with unknown ingress VIF Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 177/686] tg3: Invert restart quirk logic to restrict SNP power-down bypass Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 178/686] ns: dont add init_ipc_ns and init_net without namespace support Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 179/686] net/9p/usbg: fix prefix matching in device lookup Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 180/686] xfrm: retry inexact policy lookup after node reinsertion Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 181/686] net/9p/usbg: clear stale request context after abort Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 182/686] 9p/trans_virtio: reject mount tags longer than NAME_MAX at probe Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 183/686] 9p/xen: fix refcount leak in p9_xen_response() on wrong tag Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 184/686] 9p: fix caches_show() out-of-bounds write Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 185/686] net/9p/usbg: Fix use-after-free in disable_usb9pfs() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 186/686] net/9p/usbg: also disable endpoints on p9_usbg_close Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 187/686] net/9p/usbg: set client to Disconnected on usb9pfs_disable Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 188/686] net/9p/usbg: always reset completion when disconnecting Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 189/686] net/9p/usbg: call disable_usb9pfs() from usb9pfs_disable() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 190/686] net/9p/usbg: fix out_req buffer leak in disable_usb9pfs Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 191/686] net/9p/usbg: remove bogus context initialization in alloc_requests Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 192/686] net/9p/usbg: clear stale client pointer on close Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 193/686] xfrm: interface: validate the IP header on xmit Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 194/686] xfrm: espintcp: reorder operations within espintcp_init_sk Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 195/686] drm/panic: Fix kmsg screen hang on a long log line Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 196/686] drm/drm_crtc: ensure dma_fence_ops remain valid during device unbind Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 197/686] wifi: mac80211: reload TDLS header pointer after skb_linearize() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 198/686] wifi: brcmfmac: map msgbuf RX packet IDs bidirectional Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 199/686] wifi: rsi: Skip TX aggregation setup for non-QoS frames Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 200/686] wifi: cfg80211: fix out-of-bounds read in valid_rule() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 201/686] drm/vc4: Publish the output fence outside of job_lock Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 202/686] drm/vc4: Drop the BO reservations " Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 203/686] wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 204/686] xfrm4: use a full socket for local errors Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 205/686] scsi: aic7xxx: Use default settings on the SGI O2 onboard controllers Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 206/686] scsi: aic79xx: Fix NULL pointer dereference in device reset Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 207/686] scsi: target: Fix demo-mode dynamic ACL dev-entry UAF vs LUN teardown Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 208/686] 9p/xen: validate the response size from the backend Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 209/686] 9p: dont decrement a server-owned zero nlink Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 210/686] batman-adv: Close OGM aggregation before transmission Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 211/686] batman-adv: mcast: validate tracker padding before forwarding Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 212/686] batman-adv: dat: initialize orig_node of unfilled candidate slots Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 213/686] batman-adv: fix skb leak when hard_iface is being released Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 214/686] batman-adv: stop originator purge worker before freeing TT Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 215/686] net: jme: keep RX MAC clock enabled for WoL Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 216/686] ipv6: raw: fix use-after-free in rawv6_send_hdrinc() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 217/686] drm/vc4: hdmi: power down the BCM2712 PHY when the output is disabled Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 218/686] drm/vc4: hdmi: always cancel the scrambling work synchronously Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 219/686] drm/vc4: hdmi: enable scrambling before the TMDS clock starts Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 220/686] sctp: account for chunk padding in sctp_init_cause() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 221/686] btrfs: sysfs: restore NOFS context on early return in btrfs_sysfs_add_block_group_type() Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 222/686] ptp: fix use-after-free in extts_fifo_show() reading tsevqs unlocked Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 223/686] scsi: bsg: Report synchronous data copyback failures Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 224/686] scsi: target: Verify the iSCSI ISID is null-terminated Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 225/686] scsi: target: tcmu: Fix divide-by-zero in data_pages_per_blk store Greg Kroah-Hartman
2026-11-13 15:45 ` [PATCH 6.18 226/686] drm/loongson: Fix framebuffer selection in async cursor updates Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 227/686] drm/loongson: Fix double free on BO initialization failure Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 228/686] drm/loongson: Handle buffer mapping failures when clearing a BO Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 229/686] ALSA: us122l: Add missing NULL check in usb_stream_hwdep_mmap() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 230/686] ALSA: us122l: Fix NULL dereference at hwdep open and release Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 231/686] ALSA: usx2y: Initialize idle URBs before submitting streams Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 232/686] ALSA: hwdep: Serialize DSP load requests Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 233/686] bpf: Fix skb_pull() BUG in __bpf_redirect_neigh() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 234/686] ksmbd: require DELETE access for delete-on-close opens Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 235/686] rust: cpufreq: fix `undocumented_unsafe_blocks` in `PolicyCpu::from_cpu()` Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 236/686] x86/bugs: Select the BHI mitigation based on the attack vector properly Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 237/686] drm/i915/psr: Clear selective fetch area when duplicating plane state Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 238/686] drm/i915/display: Add enabled pipe planes into state for selective fetch Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 239/686] drm/i915/psr: Disable linked plane sel fetch as well Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 240/686] drm/i915/psr: Fix SFF and CFF CTL register bit definitions Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 241/686] drm/i915/psr: Dont clip plane state destination rectangle Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 242/686] drm/i915/gem: Reset err for each fence entry Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 243/686] drm/i915/display: Single scaler per pipe on WCL Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 244/686] net: atl1c: drop oversized RX frames instead of panicking Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 245/686] ksmbd: grant a POSIX ACL group entry only to the groups members Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 246/686] mm/mempolicy: charge shared policy nodes Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 247/686] tmpfs: keep the quota soft limits of an unused id Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 248/686] tmpfs: preserve explicitly disabled quota limits Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 249/686] mm/shmem: stop retrying folios that cannot be split Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 250/686] mm/shmem: preserve data in clean folios when splitting fails Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 251/686] mm/shmem: discard whole new large folios on fallocate rollback Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 252/686] mm/shmem: rescan after nonuniform folio splitting Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 253/686] mm/shmem: fix truncate hang in large swap entry Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 254/686] mm/shmem: fix truncate loop after boundary swapin failure Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 255/686] mm/shmem: fix truncation of files containing only swapin-error markers Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 256/686] mm/mglru: dont use stack pointers when walking PUD and PMD tables Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 257/686] mm/memfd: make f_pos accesses atomic Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 258/686] mm/filemap: dont lose a folio lock wakeup to a signal Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 259/686] mm/filemap: finish fault cleanup before dropping the fault lock Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 260/686] ext2: preserve completed DIO bytes when buffered fallback fails Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 261/686] xfs: dont skip free extents in later batches of a whole-AG FITRIM Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 262/686] xfs: dont skip free extents of the longest length in " Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 263/686] drm/v3d: Initialize timedout_batches when running a CSD job Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 264/686] drm/v3d: Widen cache_clean_lock over the whole L2TCACTL sequence Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 265/686] cipso: fix optlen corruption in cipso_v4_delopt() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 266/686] vhost-vdpa: fix pinned page leak in vhost_vdpa_pa_map() error path Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 267/686] vringh: bound top-level re-entry into indirect tables Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 268/686] vringh: reject empty / undersized indirect descriptor tables Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 269/686] veth: keep carrier off when resizing channels with a down peer Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 270/686] hwmon: (corsair-cpro) Cache fan target only after a successful command Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 271/686] hwmon: (aquacomputer_d5next) reject short status reports Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 272/686] hwmon: chipcap2: fix command error diagnostics Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 273/686] hwmon: chipcap2: fix off-by-one in command mode retry loop Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 274/686] hwmon: chipcap2: fix be16 handling Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 275/686] hwmon: chipcap2: defer probe when IRQs are unavailable Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 276/686] hwmon: chipcap2: enable IRQ processing when regulator is already enabled Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 277/686] hwmon: chipcap2: balance regulator state Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 278/686] hwmon: chipcap2: do not discard pending alarms on disable Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 279/686] hwmon: (aquacomputer_d5next) Check maxcollection when probing AQUAERO devices Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 280/686] hwmon: (asus_wmi_sensors) Avoid global struct mutation Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 281/686] hwmon: (hp-wmi-sensors) " Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 282/686] hwmon: (hp-wmi-sensors) Fix unbounded loops in scale_numeric_sensor() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 283/686] hwmon: (lm87) Fix drvdata type confusion in vrm_show() and vrm_store() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 284/686] hwmon: (nct6683) Fix incorrect struct cast in show_pwm() and store_pwm() Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 285/686] hwmon: (peci/dimmtemp) Fix devres leak and UAF on concurrent unbind Greg Kroah-Hartman
2026-11-13 15:46 ` [PATCH 6.18 286/686] hwmon: (pmbus/q54sj108a2) Add missing NULL pointer check Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 287/686] hwmon: (pmbus) Check return value from pmbus_thermal_add_sensor() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 288/686] hwmon: (pmbus) Release devres allocated memory after devm_thermal_of_zone_register error Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 289/686] hwmon: (pmbus) Fix return value check from thermal zone registration Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 290/686] hwmon: (gpio-fan) Update the speed cache before dropping the PM reference Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 291/686] hwmon: (coretemp) Check for NULL platform device in hotplug callbacks Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 292/686] hwmon: (sht4x) Convert update_interval to jiffies in pending data check Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 293/686] hwmon: (aquacomputer_d5next) Avoid truncating scaled sensor readings Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 294/686] nvme: unregister when pr_register() is given a zero new key Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 295/686] KVM: x86/mmu: Conditionally resched when retrying gPTE walk on A/D update failure Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 296/686] KVM: x86: Conditionally resched when restarting REP string emulation Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 297/686] KVM: nVMX: Process each host MSR entry at most once when unwinding failed VM-Entry Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 298/686] KVM: x86/mmu: Cap number of parent PTEs per SP at 1000 (the arbitrary rmap limit) Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 299/686] KVM: x86: Unconditionally reset MMU context when emulating INIT Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 300/686] ipv6: reject wrapped temporary address preferred lifetimes Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 301/686] x86/vmware: Fix i386 high-bandwidth hypercall arguments Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 302/686] Bluetooth: hci_sync: re-enable legacy advertising on resume Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 303/686] Bluetooth: hci_sync: pause advertising for the scan address update Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 304/686] Bluetooth: qca: Fix the WCN3950 NVM baud rate offset Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 305/686] ASoC: qcom: q6apm: Guard callbacks until probe data is ready Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 306/686] x86/resctrl: Correct ABMC counter ID field width Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 307/686] x86,fs/resctrl: Keep mbm_assign_mode in default mode at boot Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 308/686] mm/khugepaged: flush deferred unmaps before dropping a failed folio Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 309/686] mm/page-writeback: avoid 32-bit overflow in dirty threshold shares Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 310/686] mm/hugetlb: fix mremap move length truncation Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 311/686] mm/hugetlb: fix mremap deadlock when PMD sharing is possible Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 312/686] mm/page_alloc: mark pages freed by __free_pages_core() as not tagged Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 313/686] mm/ksm: keep soft-dirty when merging a page Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 314/686] fs/proc/task_mmu: return -ENOTTY for unknown pagemap ioctls Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 315/686] mm/damon/sysfs-schemes: hold damon_sysfs_lock in target_metric_store() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 316/686] mm: make swapoff interruptible when unusing mms/shmem Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 317/686] mm/migrate: untag addresses when querying page nodes Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 318/686] mm/migrate: snapshot the source nid before the misplaced migration Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 319/686] mm/vma: update VMA iterator state on error in new VMA merge Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 320/686] mm/cma: accept memory of multi-range CMA areas Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 321/686] mm/cma: accept memory of CMA areas reserved at a fixed address Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 322/686] mm: memcontrol: fix NULL pointer deref and UAF from high_work_func() on dying memcg Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 323/686] openrisc: export __mulsi3 for modules Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 324/686] ocfs2: find the xattr entry again after defragmenting a bucket Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 325/686] ocfs2: find the xattr entry again after converting a block to " Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 326/686] ocfs2: do not read the entry array of an empty xattr bucket Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 327/686] ocfs2: do not index before the entry array when dividing an empty bucket Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 328/686] ocfs2: do not read the entry array of an empty xattr block Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 329/686] fat: hold truncate_lock in fat_write_failed() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 330/686] ocfs2: keep locking_state within the cluster connection lifetime Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 331/686] ocfs2/dlm: serialize migration MLE cleanup on failure Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 332/686] ocfs2: stop recovery before shutting down local allocators Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 333/686] ocfs2/cluster: unlink socket containers before releasing resources Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 334/686] ocfs2: wait for filecheck kobject release after a failed add Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 335/686] ocfs2: cache the mount context for dentry lock callbacks Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 336/686] x86/init: Initialize wall clock in get_rtc_noop() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 337/686] xfs: fix temporary cursor leak in btree shift corruption paths Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 338/686] net/sched: sch_qfq: prevent aggregate self-replacement Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 339/686] vhost-scsi: zero misaligned I/O bounce pages Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 340/686] vhost: fix used ring index wrap in vhost_add_used_n_in_order Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 341/686] iommu/virtio: Reset device before deleting virtqueues on probe failure Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 342/686] vdpa/snet: Dont discard the DPU error in snet_send_ctrl_msg() Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 343/686] drm/bridge: nwl-dsi: Cleanup endpoint mux control selection Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 344/686] drm/bridge: nwl-dsi: Limit LCDIF specific sync override Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 345/686] hwrng: virtio - prevent use-after-free after a failed restore Greg Kroah-Hartman
2026-11-13 15:47 ` [PATCH 6.18 346/686] vduse: fix VA/PA confusion in the coherent page fault path Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 347/686] inotify: do not coalesce rename events Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 348/686] blk-mq: end the request if getting a keyslot fails Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 349/686] virtio_blk: use synchronous quiesce in virtblk_freeze_priv() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 350/686] block: Return the soft block size for compat BLKBSZGET Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 351/686] xfs: fix wrong compat fields in xfs_ioctl32_bstat_copyin() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 352/686] blk-mq: fix out-of-bounds read in blk_mq_free_rqs Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 353/686] blk-iocost: account flush sequence latency only once Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 354/686] xfs: mark the inode preallocated for pNFS write layouts past EOF Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 355/686] xfs: add a flag to convert unwritten extents without allocating blocks Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 356/686] xfs: clamp a pNFS LAYOUTCOMMIT extent before computing its end Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 357/686] xfs: cap the block count of xfs_iomap_write_direct() at one extent Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 358/686] xfs: clamp the pNFS layout range to the maximum file size Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 359/686] net: restore refcount ordering for lockless socket access Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 360/686] xfs: fix recovery of partial attr removals Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 361/686] nvmet: reject keep-alive timeouts that would overflow Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 362/686] can: isotp: check the frame type, not just the length Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 363/686] can: dev: can_put_echo_skb(): free skb on invalid echo index Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 364/686] can: isotp: check the return values of can_rx_register() in isotp_bind() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 365/686] can: proc: reset pkg_stats atomics individually Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 366/686] can: proc: skip stats calculation after reset in can_stat_update() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 367/686] can: dev: can_fill_info(): dont wake up controller if interface is down Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 368/686] can: peak_usb: pcan_usb_fd_decode_buf(): accept short uCAN end-of-list records Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 369/686] mm/khugepaged: always recheck the pmd in try_collapse_pte_mapped_thp() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 370/686] mm/khugepaged: fix PMD table lock leak " Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 371/686] mm/khugepaged: preserve dirty bits when collapsing PTE-mapped THPs Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 372/686] mm/gup: recheck the PUD under PTL in follow_pud_mask() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 373/686] mm/gup: fix clearing folios in memfd_pin_folios() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 374/686] mm/gup: fix out-of-bounds write for nr_pages == 0 in GUP-fast Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 375/686] mm/gup: check for overflow when converting nr_pages to bytes " Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 376/686] mm/mmu_gather: fix flushing ranges with 4 GiB or larger Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 377/686] mm/mmu_notifier: finish non-blocking interval invalidation on error Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 378/686] mm/mmu_notifier: set ->mm only after mmgrab() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 379/686] mm/mremap: use pudp_huge_get_and_clear() when moving huge PUDs Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 380/686] mm/mremap: recheck PUDs under the page table lock Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 381/686] mm/mremap: fix moving PUD leaves Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 382/686] mm/madvise: fix data loss from MADV_FREE on a KSM page Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 383/686] mm/memory: reject remote COW faults on PFN mappings Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 384/686] mm: fix unmap_mapping_range() beyond 4 GiB on 32-bit Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 385/686] mm: fix unkillable fault loop on MAP_DROPPABLE memory Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 386/686] mm/ksm: reset the unstable trees of all nodes Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 387/686] mm/vma: call ->may_split() before a partial merge Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 388/686] mm/memory-tiers: unregister empty tiers outside memory_tier_lock Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 389/686] mm/huge_memory: set the mmu_gather page size in zap_huge_pud() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 390/686] mm/gup: check folio->mapping under folio lock in memfd_pin_folios() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 391/686] ipv6: fix device binding after failed datagram connect Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 392/686] ovl: do not let chattr change the casefold flag Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 393/686] net/sched: clamp skb->queue_mapping before indexing the tx queue Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 394/686] vhost/vsock: size receive SKBs from declared payload Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 395/686] mptcp: do not use Fast Open on MP_JOIN subflows Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 396/686] ublk: add missing DEL_DEV_ASYNC to unprivileged permission check Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 397/686] nvme-keyring: Add a missing key_put() call to nvme_tls_key_lookup() Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 398/686] drm/amdgpu: Check cs flags Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 399/686] drm/amdgpu: parse CS IBs at the BO offset their VA mapping starts at Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 400/686] drm/amdgpu: keep the CS user fence BO in GTT Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 401/686] drm/amdkfd: use the queues process info for the WPTR BO eviction fence Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 402/686] drm/amdgpu: check amdgpu_vm_ready() in dma-buf move notify Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 403/686] drm/amdgpu: finish GPU recovery callbacks before restarting schedulers Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 404/686] drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for navi10_ih Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 405/686] drm/amdgpu: publish IH enabled before PSP programs IH_RB_CNTL Greg Kroah-Hartman
2026-11-13 15:48 ` [PATCH 6.18 406/686] drm/amd/display: Avoid closing unowned DDC pins Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 407/686] drm/amdgpu/gfx12: disallow GFXOFF while updating the SPM VMID Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 408/686] drm/amd/display: Fix NULL deref in dcn401_update_clocks_update_dtb_dto Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 409/686] drm/amd/display: Drop clock requirements on DCN32 when no displays are active Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 410/686] drm/amd/display: Keep the nominal vtotal while VRR is inactive Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 411/686] drm/amd/display: Dont select zero V_TOTAL_MIN/MAX on seamless boot Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 412/686] drm/amdgpu: Fix duplicate dependency fence releases Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 413/686] drm/amdgpu: Report MES ring wait timeouts Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 414/686] drm/amdgpu: Clamp the ATIF backlight curve to its 99 points Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 415/686] drm/amdgpu: drop the dma-buf reference when a KFD import fails Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 416/686] drm/amdgpu: Only enable HDMI audio if display supports it Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 417/686] drm/amdgpu: dont drop the gang dependency fence twice Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 418/686] nvmet: dont return memory contents beyond valid data when reading ANA log page Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 419/686] arm64: suspend: Save and restore TPIDR2_EL0 across CPU suspend Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 420/686] arm64: mm: validate /dev/mem mmap ranges without overflow Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 421/686] nvme-pci: add NVME_QUIRK_DMAPOOL_ALIGN_512 for KIOXIA XG10d Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 422/686] ovl: look up the index by the decoded origin Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 423/686] l2tp: only return sessions of the given tunnel in l2tp_session_get() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 424/686] drm/nouveau/nvkm: clear use.enabled when subdev init fails Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 425/686] drm/dp: keep MOT set between messages when no_zero_sized is set Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 426/686] drm/nouveau/devinit/gf100-: try to avoid double-running vbios scripts Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 427/686] ALSA: ump: Fix dropped data bytes at UMP System message conversion Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 428/686] ALSA: hda/realtek: Enable bass speakers on Alienware m17 R3 Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 429/686] ALSA: cs46xx: Handle SCB creation failures before dereferencing Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 430/686] ALSA: bcd2000: Fix use-after-free of MIDI URBs on file close Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 431/686] ALSA: usx2y: Refuse a retried DSP load after a failure Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 432/686] ALSA: hda/tas2781: Only accept CRC-less V1 data if all entries are valid Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 433/686] ALSA: line6: Reject capture buffers smaller than two packets Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 434/686] ALSA: caiaq: free the EP4 URB when input setup fails Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 435/686] ALSA: usx2y: Require a buffer of two URBs Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 436/686] ALSA: usx2y: Guard the playback copy Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 437/686] ext2: preserve IOMAP_F_DIRTY for extending direct writes Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 438/686] net/smc: dont spin in smc_rx_recvmsg() while a pipe holds spliced data Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 439/686] net: count last skb of each sk_backlog pass in __release_sock() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 440/686] net: ethernet: ti: am65-cpsw-nuss: Enable timestamping of unicast PTP packets Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 441/686] drm/etnaviv: Flush the tile status cache through both the PE and BLT Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 442/686] mptcp: pm: kernel: use RCU to free endpoint listeners Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 443/686] udf: dont let the extent type hide an exhausted free-space table extent Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 444/686] udf: check the unallocated space table when it is loaded Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 445/686] udf: fix preallocation discarding before an empty allocation extent Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 446/686] udf: dont use eloc after the end of the unallocated space table Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 447/686] MIPS: mm: Fix the cache error vector jump for XKPHYS kernels Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 448/686] MIPS: sgi-ip32: Mask MACE PCI interrupts in CRIME only Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 449/686] MIPS: sgi-ip32: Leave MACE PCI control alone in config accesses Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 450/686] srcu: Add list_splice_init_srcu() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 451/686] nvme: wait for SRCU readers before splicing the namespace list Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 452/686] nvmet: bound the traddr and trsvcid configfs writes Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 453/686] perf/core: Dont send SIGTRAP after exec removed the event Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 454/686] x86/nmi: Ignore negative NMI handler durations Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 455/686] iommu/amd: Skip non-IVMD entries when parsing IVRS memory definitions Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 456/686] arm64: kexec_file: Fix elf_headers memory leak in retry loop Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 457/686] x86/boot: Fix off-by-one error in sme_clear_pgd() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 458/686] arm64: sdei: Run the event handler on the kernel vectors Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 459/686] arm64: sdei: Preserve the interrupted contexts exception registers Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 460/686] ata: libata-pmp: disable the SEMB port on Marvell 88SM9705 Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 461/686] x86/mm: Fix global ASID handed out to two processes Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 462/686] iommu/amd: Force device table to maximum size Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 463/686] Revert "hugetlb: remove VMEMMAP_SYNCHRONIZE_RCU" Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 464/686] can: replace ARPHRD_CAN type checks with can_get_ml_priv() Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 465/686] can: protect the receive lists with a per-device lock Greg Kroah-Hartman
2026-11-13 15:49 ` [PATCH 6.18 466/686] ceph: clamp the inline data length in ceph_fill_inline_data() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 467/686] Revert "mm/page_owner: fix memory leak in page_owner_stack_fops->release()" Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 468/686] timekeeping: Require permission to set auxiliary clocks Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 469/686] vxlan: Stop rejecting dynamic FDB entries with a nexthop ID Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 470/686] mm/damon/core: move static variable last_nr_regions to damon_ctx Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 471/686] batman-adv: tpmeter: fix u32 truncation of reported bytes Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 472/686] batman-adv: tt: only transmit local ROAM flag together with DEL Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 473/686] batman-adv: tt: clear ROAM flag when re-adding a pending local client Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 474/686] batman-adv: tt: send ROAM_ADV on each roamed back client Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 475/686] batman-adv: tt: ignore ROAM flag of received ADD changes Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 476/686] batman-adv: tt: only update flags for TT events Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 477/686] batman-adv: tt: dont drop local events queued during TVLV update Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 478/686] can: raw, isotp: copy socket options outside of lock_sock() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 479/686] sched_ext: Reset runnable_at when a task leaves its scheduler Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 480/686] ata: libata-scsi: reject data-in commands with a data-out buffer Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 481/686] powerpc/bpf: fix buffer overflow in JIT for large BPF programs Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 482/686] lib/crypto: mips: Disable Octeon SHA code on little-endian kernels Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 483/686] kho: do not reserve scratch memory in the kdump kernel Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 484/686] mtd: spi-nor: macronix: Restore fallback parameters for MX25L12805D Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 485/686] media: i2c: imx219: Propagate errors from control range updates Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 486/686] media: imx219: The horizontal blanking step is 8 Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 487/686] soc: qcom: pmic_glink: Fix device access from worker during suspend Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 488/686] PCI: endpoint: pci-epf-vntb: Manage virtual NTB and PCI bus lifetime Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 489/686] platform: int3472: discrete: Support multiple HIDs per GPIO map entry Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 490/686] platform/x86: int3472: Increase handshake GPIO delay to 200 ms Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 491/686] KVM: guest_memfd: Split bind() into prepare()+commit() phases Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 492/686] iio: light: isl29028: remove isl29028_set_pm_runtime_busy() helper Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 493/686] iio: light: isl29028: fix runtime PM reference leak on error paths Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 494/686] KVM: arm64: Use kvm_s2_fault_vma_info in gmem_abort() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 495/686] KVM: arm64: ptdump: Check the page tables arent freed when accessing Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 496/686] media: microchip-isc: store the unshifted PFE_CFG0 BPS value Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 497/686] media: microchip-isc: fix ISC_PFG_CFG0_BPS macro name typo Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 498/686] media: microchip-isc: fix SBGGR10 Bayer pattern Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 499/686] media: i2c: imx219: Replace exposure magic value with named constant Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 500/686] media: imx219: Account rate_factor in setting upper exposure limit Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 501/686] media: imx219: Account for rate_factor in control steps Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 502/686] media: iris: Fix iova allocation from restrict region Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 503/686] iio: adc: ad7192: Revert "properly check spi_get_device_match_data()" Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 504/686] iio: adc: ad7192: reject devices without match data Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 505/686] ALSA: core: Clean up file_operations definitions Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 506/686] ALSA: timer: Handle userspace-driven timer ioctls from 32-bit tasks Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 507/686] ALSA: usb-audio: keep MIDI input running for Roland TD-11 Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 508/686] ALSA: usb-audio: Protect Roland control activation Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 509/686] hwmon: (tmp102) Fix jiffies wraparound in conversion-ready check Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 510/686] gfs2: reject invalid inode sizes Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 511/686] media: i2c: og01a1b: Switch from .s_stream to .enable_streams/.disable_streams Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 512/686] media: i2c: og01a1b: power off sensor on remove Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 513/686] f2fs: fix to avoid folio->mapping dereference in is_{meta, node}_folio() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 514/686] m68k: Fix task info flags handling for 68000 Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 515/686] m68k: Fix seccomp filtering on ColdFire and 68000 Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 516/686] powerpc/pseries/iommu: Add TCEs for 16GB pages when RAM is pre-mapped Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 517/686] f2fs: fix to check continuousness in f2fs_sync_meta_pages() correctly Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 518/686] iio: light: Remove redundant dev_err()/dev_err_probe() Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 519/686] iio: light: ltr501: Power down chip if request irq fails Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 520/686] media: redrat3: Error path leaves device in transmitting state Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 521/686] media: i2c: ov5647: fix power cleanup on remove Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 522/686] KVM: guest_memfd: Establish memslot<=>guest_memfd bindings *after* memslot is ready Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 523/686] ublk: keep a canceled FETCH round canceling until the server is gone Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 524/686] misc: fastrpc: Rename phys to dma_addr for clarity Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 525/686] misc: fastrpc: fix double-free in fastrpc_map_attach() error path Greg Kroah-Hartman
2026-11-13 15:50 ` [PATCH 6.18 526/686] cxl/port: Cleanup handling of the nr_dports 0 -> 1 transition Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 527/686] cxl/port: Clear cached dport pointers when a dport is removed Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 528/686] KVM: arm64: Pin the host vCPU before adjusting its PC under pKVM Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 529/686] sctp: hold shkey across socket migration Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 530/686] sctp: re-point retained control chunks on association migration Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 531/686] bnxt_en: Refactor some basic ring setup and adjustment logic Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 532/686] bnxt_en: dont leave an XDP program installed when the open fails Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 533/686] fs/ntfs3: validate the EA value length in ntfs_read_ea() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 534/686] mm/hugetlb: unmap the page where the other VMA maps it Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 535/686] mm/userfaultfd: only allocate anon_vma in CoW mappings Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 536/686] ceph: fix longname buffer overflow in ceph_fname_to_usr() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 537/686] mm/page_vma_mapped: continue past nonmatching huge PMDs Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 538/686] mm/shmem: honour F_SEAL_EXEC when an ACL is set Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 539/686] spi: cadence-xspi: Replace ACPI specifics by agnostic APIs Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 540/686] spi: cadence-xspi: Use FIELD_MODIFY() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 541/686] spi: cadence-xspi: group marvell support code together Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 542/686] spi: cadence-xspi: reject SDMA transfers larger than the requested length Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 543/686] mm: memory: fix truncation removing mapped folios Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 544/686] ipmr: prevent info-leak in pmr_cache_report() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 545/686] ipmr: only copy pktinfo to cache reports Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 546/686] nvme-tcp: skip TLS control records while waiting for the ICResp Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 547/686] wifi: rtw88: usb: route bmc frames via the high queue only for DTIM delivery Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 548/686] wifi: rtw88: usb: bound what the driver feeds the after-DTIM queue Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 549/686] wifi: rtw88: usb: only let the frames a dozing station needs use " Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 550/686] wifi: rtw88: widen the ATIM window while an AP interface is up Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 551/686] ovl: fail the mount if the casefold flag has changed Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 552/686] udf: validate the device specification EA before using it Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 553/686] hwmon: (tmp108) Fix jiffies wraparound in conversion-ready check Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 554/686] dmaengine: qcom: bam_dma: Defer IRQ trigger type to device tree Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 555/686] dmaengine: qcom: bam_dma: free interrupt before the clock in error path Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 556/686] ASoC: stm: stm32_i2s: Drop redundant error messages Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 557/686] ASoC: stm: stm32_i2s: request IRQ after regmap initialization Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 558/686] iio: dac: mcp4821: reject devices without match data Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 559/686] ALSA: hda/realtek: Add codec SSID quirk for Lenovo Yoga Pro 9 16IMH9 Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 560/686] ALSA: hda/realtek: Fix Legion 7 16ITHG6 speaker amp binding Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 561/686] ALSA: hda/realtek: Fix silent speakers on Lenovo Legion S7 15IMH05 Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 562/686] spi: atmel-quadspi: add controller init callback Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 563/686] spi: atmel-quadspi: use init callback for gclk variants Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 564/686] spi: atmel-quadspi: balance runtime PM and pclk across system sleep Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 565/686] vfio/pci: Restore 8-byte ioeventfd support Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 566/686] ata: libata: Add an argument to ata_eh_reset() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 567/686] ata: sata_inic162x: remove dangerous broken driver Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 568/686] f2fs: zone: fix to avoid bio split on sequential zone Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 569/686] cgroup: Expose some cgroup helpers Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 570/686] mm/mglru: fix ineffective memory protection for non-kswapd reclaim Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 571/686] f2fs: return -EIO for a lost inode block after cp_error Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 572/686] drm/amd/pm:restate all customized OD features on every table upload for smu 13.0.0/smu 14.0.2 Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 573/686] mfd: twl-core: Use i2c_check_functionality as boolean value Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 574/686] mfd: twl-core: Unregister the auxiliary platform device on unbind Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 575/686] ALSA: hda: cs35l41: Use auto-cleanup for put_device() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 576/686] ALSA: hda: cs35l41: Fix ACPI device reference leak on probe failure Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 577/686] platform/x86: asus-wmi: Serialize WMI method evaluations with a mutex Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 578/686] KVM: arm64: nv: Move L2->L1 switch on interrupt early Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 579/686] media: rockchip: rga: use clk_bulk api Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 580/686] media: rockchip: rga: quiesce IRQ before releasing m2m state Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 581/686] filemap: Add folio_next_pos() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 582/686] xfs: Use folio_next_pos() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 583/686] xfarray: dont crash when sorting if array element crosses a folio Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 584/686] s390/pci: Add error cleanup in zpci_directed_irq_init() Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 585/686] serial: sc16is7xx: declare SPR/TLR/XOFF2 register as volatile Greg Kroah-Hartman
2026-11-13 15:51 ` [PATCH 6.18 586/686] serial: sc16is7xx: add comments for lock requirements Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 587/686] serial: sc16is7xx: declare MCR and IER as volatile registers Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 588/686] virtiofs: add FUSE protocol validation Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 589/686] virtiofs: validate fixed-output response length Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 590/686] rculist: Add hlist_nulls_replace_rcu() and hlist_nulls_replace_init_rcu() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 591/686] mptcp: fix MP_CAPABLE token migration when cloning reqsk Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 592/686] ALSA: ua101: Bound packet copies by the PCM buffer size Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 593/686] serial: sc16is7xx: fix data corruption due to unexpected xon/xoff Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 594/686] media: iris: Fix power-off ordering to disable power domain after clocks Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 595/686] ASoC: qcom: q6apm-dai: wrap the position of a full ring to 0 Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 596/686] iomap: use largest_zero_folio() in iomap_dio_zero() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 597/686] iomap: dont lose a failed direct I/O bios error when zeroing the tail Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 598/686] exfat: advance valid_size to EOF for append writes Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 599/686] f2fs: bound the SIT/NAT bitmaps by the checkpoint pack Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 600/686] block: introduce bio_in_atomic() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 601/686] f2fs: fix to use bio_in_atomic() in f2fs_read_end_io() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 602/686] scsi: ufs: core: Add a helper for clearing hba->outstanding_reqs Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 603/686] wifi: mt76: mt7921: assert sniffer on chanctx change Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 604/686] wifi: mt76: move the channel survey when the channel changes Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 605/686] ASoC: amd: acp: add DMI override for ACP70 flag Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 606/686] ASoC: amd: acp: Add DMI quirk for ASUS Zenbook S16 UM5606GA Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 607/686] ASoC: amd: acp: Add DMI quirk for Lenovo Yoga Pro 7 15ASH11 Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 608/686] ASoC: amd: acp-config: force SoundWire probe on HP OmniBook X Flip 16 Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 609/686] ASoC: amd: acp-config: force SoundWire probe on Dell 14S DS14265 Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 610/686] perf evsel: Restrict incremental open error unwind Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 611/686] perf evsel: Close the fds opened so far when disabling missing features Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 612/686] KVM: arm64: vgic: Stop the target vcpu when disabling LPIs Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 613/686] platform/x86: Rename lenovo-wmi-capdata01 to lenovo-wmi-capdata Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 614/686] platform/x86: lenovo-wmi-capdata: Do not stop the AC notifier chain on error Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 615/686] iio: adc: ad4080: enable address ascension for chip identification Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 616/686] fbcon: Retry rotated font allocation after failure Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 617/686] mm: hugetlb: return -ENOSPC on memcg charge failure Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 618/686] mm: hugetlb: drop refcount before freeing " Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 619/686] xen/gntdev: Fix gntdev_dmabuf ref leak in dmabuf_exp_wait_released() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 620/686] mm/mempolicy: use vm_normal_folio_pmd() in queue_folios_pmd() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 621/686] ublk: mark the io command cancelable before publishing it Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 622/686] nvmem: rockchip-otp: alloc clks with main struct Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 623/686] nvmem: rockchip-otp: Serialize reads Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 624/686] tpm: tpm2_probe: propagate transport errors Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 625/686] fs: assert on ->i_count in iput_final() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 626/686] fs: add missing fences to I_NEW handling Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 627/686] fs: spell out fenced ->i_state accesses with explicit smp_wmb/smp_rmb Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 628/686] fs: provide accessors for ->i_state Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 629/686] fs: Ignore inode metadata buffers in inode_lru_isolate() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 630/686] fs: rotate inodes whose page cache could not be dropped Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 631/686] mm: memcontrol: refactor mod_memcg_state() and mod_memcg_lruvec_state() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 632/686] mm: use enum migrate_reason instead of int for migration reason parameters Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 633/686] mm/memcg: migrate per-node hugetlb lruvec stat together with hugetlb folio Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 634/686] mm/vma: dont leak the commit charge on mmap failure Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 635/686] mm/hugetlb: charge folios to the target mms memcg Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 636/686] mm/memfd: fix hugetlb reservation accounting in error paths Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 637/686] ASoC: hdac_hda: Allocate the private data at codec driver bind Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 638/686] ASoC: hdac_hda: Restore the codec device type on unbind Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 639/686] fs: dont lose inodes that another LRU walker is isolating Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 640/686] LoongArch: Fix one-shot limitation for perf hardware breakpoints Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 641/686] ocfs2: fix oob in __ocfs2_find_path Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 642/686] ocfs2: fix array out of bound access in __ocfs2_find_path() Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 643/686] arm64/gcs: release GCS on failed fork Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 644/686] PCI: cadence: Store the core controller in platform drvdata Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 645/686] iomap: dont mark unwritten parts of a folio uptodate Greg Kroah-Hartman
2026-11-13 15:52 ` [PATCH 6.18 646/686] mm/shmem: dont release a swapin-error marker as a swap entry Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 647/686] f2fs: fix to invalidate curseg if change_curseg() fails Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 648/686] LoongArch: Dont init & online empty nodes Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 649/686] Documentation/kernel-parameters: Move the kernel build options Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 650/686] nvmet-tcp: validate the TLS handshake timeout Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 651/686] nvme-tcp: " Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 652/686] watchdog/hpwdt: Refine hpwdt message for UV platform Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 653/686] panic: restore variable arguments to nmi_panic() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 654/686] ALSA: hda/realtek: Enable all four speaker amps on Lenovo ThinkBook X G2 IAH Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 655/686] posix-timers: Handle the timer_[re]arm() return value Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 656/686] posix-timers: Report zero remaining time for disarmed SIGEV_NONE timers Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 657/686] PCI: imx6: Avoid dereferencing a NULL clock name Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 658/686] mm/huge_memory: split huge PUDs when adjusting VMA boundaries Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 659/686] PCI: dwc: Set DMA_BYPASS bit in outbound IATU CTRL2 register Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 660/686] clk: nuvoton: ma35d1: Keep the clock count in the driver Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 661/686] dt-bindings: clock: ma35d1: Drop CLK_MAX_IDX define Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 662/686] dt-bindings: clock: ma35d1: Add missing WDT/WWDT parent clocks Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 663/686] clk: nuvoton: " Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 664/686] f2fs: release a removed xattr node in roll-forward recovery Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 665/686] media: ipu6: Rename pointer to firmware context Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 666/686] media: ipu6: Fix firmware config leak on stream start Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 667/686] mm/vma: avoid broken uffd merge on mremap Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 668/686] iommufd/iova_bitmap: Ensure that iova_bitmap_set() handles the full IOVA Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 669/686] hwmon: (coretemp) Return -ENODATA for invalid temperature readings Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 670/686] crypto: omap - add omap_sham_unregister_algs helper Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 671/686] crypto: omap-sham - fix crypto engine cleanup Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 672/686] irqchip/renesas-rzv2h: Preserve TIEN state in rzv2h_tint_set_type() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 673/686] power: supply: ltc2941: Fix of_node reference leak in ltc294x_i2c_probe() Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 674/686] fbdev: nvidia: Convert to managed PCI and ioremap API Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 675/686] fbdev: nvidia: Release write-combining handle on probe failure Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 676/686] platform/x86/amd/pmf: Add AMDI0112 ACPI ID Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 677/686] fb: Add dev_of_fbinfo() helper for optional sysfs support Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 678/686] fbdev: sh_mobile_lcdc: Make FB_DEVICE dependency optional Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 679/686] fbdev: sh_mobile_lcdcfb: Restore the per-overlay sysfs attributes Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 680/686] perf python: Free the parse error entries when parsing fails Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 681/686] selftests/landlock: Fix snprintf truncation checks in test files Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 682/686] lib/tests: extend cmdline KUnit with next_arg() tests Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 683/686] lib/cmdline: fix get_options() count and overflow with large ranges Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 684/686] ASoC: amd: yc: Add DMI quirk for HP OmniBook 3 Laptop 16-by0xxx Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 685/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook 7 17-dc0xxx Greg Kroah-Hartman
2026-11-13 15:53 ` [PATCH 6.18 686/686] ALSA: hda/realtek: Enable mute LEDs on HP OmniBook X Flip 14-fm0xxx Greg Kroah-Hartman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox