Skip to contentSkip to conversation

7.1.4-rc1 review

PATCH In review Greg Kroah-Hartman 13 participants 533 messages Jul 16 – Jul 17 Page 1 of 4

Subsystems (2)
lore
Share & tools
lore

Greg Kroah-Hartman

author maintainer
#0 lore raw

cover 7.1.4-rc1 review

This is the start of the stable review cycle for the 7.1.4 release. There are 518 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 Sat, 18 Jul 2026 13:30:01 +0000. Anything received after that time might be too late.

The whole patch series can be found in one patch at:

	https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.1.4-rc1.gz

or in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.1.y
and the diffstat can be found below.

thanks,

greg k-h

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

Greg Kroah-Hartman <[email protected]>

    Linux 7.1.4-rc1

Luiz Augusto von Dentz <[email protected]>

    Bluetooth: 6lowpan: Fix using chan->conn as indication to no remote netdev

Mikhail Gavrilov <[email protected]>
timekeeping: Register default clocksource before taking tk_core.lock

Rong Zhang <[email protected]>
ALSA: doc: usb-audio: Add doc for QUIRK_FLAG_IFB_SILENCE_ON_EMPTY

Joanne Koong <[email protected]>
fuse-uring: remove request-less entries from ent_w_req_queue to fix NULL deref

Bernd Schubert <[email protected]>
fuse-uring: make a fuse_req on SQE commit only findable after memcpy

Bernd Schubert <[email protected]>

    fuse-uring: Avoid queue->stopped races and set/read that value under lock

Bernd Schubert <[email protected]>
fuse-uring: Avoid use-after-free in fuse_uring_async_stop_queues

Chris Mason <[email protected]>
fuse-uring: end fuse_req on io-uring cancel task work

Joanne Koong <[email protected]>
fuse-uring: fix moving cancelled entry to ent_in_userspace list

Chris Mason <[email protected]>

    fuse-uring: fix data races on ring->ready

Chris Mason <[email protected]>
fuse-uring: fix EFAULT clobber in fuse_uring_commit

Ji'an Zhou <[email protected]>
fuse: clear intr_entry in fuse_resend and fuse_remove_pending_req

Joanne Koong <[email protected]>
fuse: don't block in fuse_get_dev() for non-sync_init case

Joanne Koong <[email protected]>
fuse: fix io-uring background queue dispatch on request completion

Joanne Koong <[email protected]>
fuse: re-lock request before returning from fuse_ref_folio()

Miklos Szeredi <[email protected]>
fuse: do not use start_removing_noperm()

Alberto Ruiz <[email protected]>
fuse: fix device node leak in cuse_process_init_reply()

Miklos Szeredi <[email protected]>
Revert "fuse: fix conversion of fuse_reverse_inval_entry() to start_removing()"

Samuel Moelius <[email protected]>
fuse: avoid 32-bit prune notification count wrap

Matthew R. Ochs <[email protected]>
fuse: back uncached readdir buffers with pages

Michael Bommarito <[email protected]>
RDMA/siw: bound Read Response placement to the RREAD length

Maher Sanalla <[email protected]>
RDMA/core: Fix broadcast address falsely detected as local

Zhenhao Wan <[email protected]>
RDMA/rtrs-srv: Bound RDMA-Write length to chunk size in rdma_write_sg

Dmitry Torokhov <[email protected]>
Input: maplecontrol - set driver data before registering input device

Dmitry Torokhov <[email protected]>
Input: maplemouse - set driver data before registering input device

Dmitry Torokhov <[email protected]>
Input: maple_keyb - set driver data before registering input device

Dmitry Torokhov <[email protected]>
Input: mms114 - fix multi-touch slot corruption

Florian Fuchs <[email protected]>
Input: maplemouse - fix NULL pointer dereference in open()

Xu Rao <[email protected]>
Input: gscps2 - advance receive buffer write index

Bryam Vargas <[email protected]>
Input: mms114 - reject an oversized device packet size

Bryam Vargas <[email protected]>
Input: touchwin - reset the packet index on every complete packet

Kris Bahnsen <[email protected]>
Input: ads7846 - don't use scratch for tx_buf when clearing register

Dmitry Torokhov <[email protected]>
Input: mms114 - fix touch indexing for MMS134S and MMS136

Bryam Vargas <[email protected]>
Input: iforce - bound the device-reported force-feedback effect index

Bryam Vargas <[email protected]>
Input: goodix - clamp the device-reported contact count

Ranjan Kumar <[email protected]>
Input: elan_i2c - prevent division by zero and arithmetic underflow

Bryam Vargas <[email protected]>
Input: synaptics-rmi4 - bound the F30 keymap to the GPIO/LED count

Bryam Vargas <[email protected]>
Input: synaptics-rmi4 - bound the F3A keymap to the GPIO count

Haoxiang Li <[email protected]>
Input: synaptics-rmi4 - unregister function handlers on physical driver registration failure

Mingyu Wang <[email protected]>
i2c: i801: fix hardware state machine corruption in error path

Carlos Song <[email protected]>
i2c: imx-lpi2c: mark I2C adapter when hardware is powered down

Guillermo Rodríguez <[email protected]>
i2c: stm32f7: truncate clock period instead of rounding it

Haoxiang Li <[email protected]>
i2c: davinci: Unregister cpufreq notifier on probe failure

Andy Shevchenko <[email protected]>
i2c: mpc: Fix timeout calculations

Johan Hovold <[email protected]>
i2c: core: fix adapter deregistration race

Johan Hovold <[email protected]>
i2c: core: fix adapter debugfs creation

Johan Hovold <[email protected]>
i2c: core: fix NULL-deref on adapter registration failure

Johan Hovold <[email protected]>
i2c: core: fix irq domain leak on adapter registration failure

Johan Hovold <[email protected]>
i2c: core: fix adapter probe deferral loop

Sebastian Alba Vives <[email protected]>
fpga: dfl-afu: validate DMA mapping length in afu_dma_map_region()

Chuck Lever <[email protected]>
Revert "svcrdma: Use contiguous pages for RDMA Read sink buffers"

Chuck Lever <[email protected]>
svcrdma: wake sq waiters when the transport closes

Mikhail Gavrilov <[email protected]>
dma-buf/udmabuf: skip redundant cpu sync to fix cacheline EEXIST warning

Mikhail Gavrilov <[email protected]>
udmabuf: fix DMA direction mismatch in release_udmabuf()

Oliver Upton <[email protected]>
KVM: arm64: Don't leak PFN when kvm_translate_vncr() races MMU notifier

Sean Christopherson <[email protected]>
KVM: x86: Add dedicated API for getting mask of accelerated x2APIC MSRs

Sean Christopherson <[email protected]>
KVM: guest_memfd: Treat memslot binding offset+size as unsigned values

Sean Christopherson <[email protected]>
KVM: x86: Ensure vendor's exit handler runs before fastpath userspace exits

Sean Christopherson <[email protected]>
KVM: TDX: Account all non-transient page allocations for per-TD structures

Xuanqing Shi <[email protected]>
KVM: VMX: Handle bad values on proxied writes to LBR MSRs

Sean Christopherson <[email protected]>
KVM: SEV: Don't terminate SNP VMs on #VMGEXIT without a registered GHCB

Sean Christopherson <[email protected]>
KVM: VMX: Refresh GUEST_PENDING_DBG_EXCEPTIONS.BS on all injected #DBs

Sean Christopherson <[email protected]>
KVM: SVM: Only disable x2AVIC WRMSR interception for MSRs that are accelerated

Sean Christopherson <[email protected]>
KVM: SVM: Disable x2AVIC RDMSR interception for MSRs KVM actually supports

Sean Christopherson <[email protected]>
KVM: SEV: Pin source page for write when adding CPUID data for SNP guest

Hyunwoo Kim <[email protected]>
KVM: arm64: Clear __hyp_running_vcpu when flushing the pKVM hyp vCPU

Hyunwoo Kim <[email protected]>
KVM: arm64: Bound used_lrs when flushing the pKVM hyp vCPU

Zeng Chi <[email protected]>
LoongArch: KVM: Add missing slots_lock for device register/unregister

Marc Zyngier <[email protected]>
KVM: arm64: nv: Avoid dereferencing NULL VNCR pseudo-TLB

Mickaël Salaün <[email protected]>
selftests/landlock: Increase default audit socket timeout

Mickaël Salaün <[email protected]>
selftests/landlock: Filter dealloc records in audit_count_records()

Mickaël Salaün <[email protected]>
landlock: Account all audit data allocations to user space

Maximilian Heyne <[email protected]>
selftests/landlock: Explicitly disable audit in teardowns

Mickaël Salaün <[email protected]>
landlock: Set audit_net.sk for socket access checks

Ricardo Robaina <[email protected]>
audit: fix removal of dangling executable rules

Nicolin Chen <[email protected]>
iommufd: Set upper bounds on cache invalidation entry_num and entry_len

Nicolin Chen <[email protected]>
iommufd: Avoid partial fault group delivery in iommufd_fault_fops_read()

Nicolin Chen <[email protected]>
iommufd: Break the loop on failure in iommufd_fault_fops_read()

Nicolin Chen <[email protected]>
iommufd: Reject invalid read count in iommufd_fault_fops_read()

Nicolin Chen <[email protected]>
iommufd: Propagate allocation failure in iommufd_veventq_deliver_fetch()

Nicolin Chen <[email protected]>
iommufd: Reject invalid read count in iommufd_veventq_fops_read()

Nicolin Chen <[email protected]>
iommufd: Rewind header length in done if iommufd_veventq_fops_read() fails

Nicolin Chen <[email protected]>
iommufd: Set veventq_depth upper bound

Nicolin Chen <[email protected]>
iommufd: Move vevent memory allocation outside spinlock

Nicolin Chen <[email protected]>
iommufd: Fix data_len byte-count vs element-count mismatch

Kai Aizen <[email protected]>
iommufd: Use sizeof(*hdr) instead of sizeof(hdr) in veventq read

Weinan Liu <[email protected]>
iommu/amd: Don't split flush for amd_iommu_domain_flush_all()

Lu Baolu <[email protected]>
iommu/vt-d: Avoid WARNING in sva unbind path

Matt Bobrowski <[email protected]>
bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized

Dave Airlie <[email protected]>
nouveau/vmm: fix another SPT/LPT race

Sarthak Sharma <[email protected]>
selftests/mm: fix ksft_process_madv.sh test category

Zenghui Yu <[email protected]>
selftests/mm: pagemap_ioctl: use the correct page size for transact_test()

Pedro Falcato <[email protected]>
mm: do file ownership checks with the proper mount idmap

Ketan <[email protected]>
mm: page_ext: add count limit to page_ext_iter_next to prevent invalid PFN access

David Hildenbrand (Arm) <[email protected]>
selftests: mm: fix and speedup "droppable" test

Anthony Yznaga <[email protected]>
mm: fix mmap errno value when MAP_DROPPABLE is not supported

Hao Ge <[email protected]>
lib/test_hmm: use kvfree() to free kvcalloc() allocations

Vivian Wang <[email protected]>
riscv: mm: Unconditionally sfence.vma for spurious fault

Vivian Wang <[email protected]>
riscv: mm: Define DIRECT_MAP_PHYSMEM_END

Koichiro Den <[email protected]>
NTB: epf: Fix request_irq() unwind in ntb_epf_init_isr()

Bryam Vargas <[email protected]>
exfat: bound uniname advance in exfat_find_dir_entry()

Rochan Avlur <[email protected]>
exfat: preserve benign secondary entries during rename and move

Nicolas Pitre <[email protected]>
vt: fix spurious modifier in CSI/cursor key sequences

Andrii Kuchmenko <[email protected]>
module: decompress: check return value of module_extend_max_pages()

Gabriele Monaco <[email protected]>
rqspinlock: Fix order in raw_res_spin_(un)lock_irq to allow schedule

Benjamin Coddington <[email protected]>
NFSv4: include MAY_WRITE in open permission mask for O_TRUNC

Ricardo Robaina <[email protected]>
audit: fix potential integer overflow in audit_log_n_hex()

Huihui Huang <[email protected]>
tracing: Prevent out-of-bounds read in glob matching

Luca Boccassi <[email protected]>
selftests/liveupdate: add test cases for LIVEUPDATE_IOCTL_CREATE_SESSION calls with invalid length

Luca Boccassi <[email protected]>
liveupdate: reject LIVEUPDATE_IOCTL_CREATE_SESSION with invalid name length

Lee Jia Jie <[email protected]>
perf/aux: Fix page UAF in map_range()

Johan Hovold <[email protected]>
i2c: core: fix hang on adapter registration failure

Wentao Liang <[email protected]>
regulator: scmi: fix of_node refcount leak in scmi_regulator_probe()

Janne Grunau <[email protected]>
watchdog: apple: Add "apple,t8103-wdt" compatible

Vasily Khoruzhick <[email protected]>
EDAC/i10nm: Don't fail probing if ADXL is missing

David Hildenbrand (Arm) <[email protected]>
x86/mm: Fix freeing of PMD-sized vmemmap pages

Carlos Song <[email protected]>
spi: fsl-lpspi: terminate the RX channel on TX prepare failure path

Carlos Song <[email protected]>
spi: fsl-lpspi: replace dmaengine_terminate_all() with dmaengine_terminate_sync()

Mark Rutland <[email protected]>
arm64: fpsimd: Fix type mismatch in sme_{save,load}_state()

Paul Louvel <[email protected]>
crypto: talitos/hash - fix SEC2 64k - 1 ahash request limitation

Paul Louvel <[email protected]>
crypto: talitos/hash - remove useless wrapper

Paul Louvel <[email protected]>
crypto: talitos/hash - rename first_desc/last_desc to first_request/last_request

Paul Louvel <[email protected]>
crypto: talitos/hash - drop workqueue mechanism for SEC1

Paul Louvel <[email protected]>
crypto: talitos/hash - use descriptor chaining for SEC1 instead of workqueue

Paul Louvel <[email protected]>
crypto: talitos/hash - prepare SEC1 descriptor chaining, remove additional descriptor

Paul Louvel <[email protected]>
crypto: talitos - move code in current_desc_hdr() into a standalone function

Paul Louvel <[email protected]>
crypto: talitos - move dma mapping code in talitos_submit() into a standalone dma_map_request() function

Paul Louvel <[email protected]>
crypto: talitos - move dma unmapping code in flush_channel() into a standalone dma_unmap_request() function

Paul Louvel <[email protected]>
crypto: talitos - add chaining of arbitrary number of descriptor for the SEC1

Paul Louvel <[email protected]>
crypto: talitos - use dma_sync_single_for_cpu() before reading descriptor header

Ahsan Atta <[email protected]>
crypto: qat - factor out AER reset helpers

Giovanni Cabiddu <[email protected]>
crypto: qat - validate RSA CRT component lengths

Ahsan Atta <[email protected]>
crypto: qat - skip restart for down devices

Ahsan Atta <[email protected]>
crypto: qat - protect service table iterations with service_lock

Ahsan Atta <[email protected]>
crypto: qat - notify fatal error before AER reset preparation

Ahsan Atta <[email protected]>
crypto: qat - keep VFs enabled during reset

Ahsan Atta <[email protected]>
crypto: qat - handle sysfs-triggered reset callbacks

Ahsan Atta <[email protected]>
crypto: qat - fix restarting state leak on allocation failure

Ahsan Atta <[email protected]>
crypto: qat - centralize bus master enable

Eric Biggers <[email protected]>
crypto: drbg - Fix the fips_enabled priority boost

Eric Biggers <[email protected]>
crypto: drbg - Fix drbg_max_addtl() on 64-bit kernels

Eric Biggers <[email protected]>
crypto: drbg - Fix ineffective sanity check

Eric Biggers <[email protected]>
crypto: drbg - Fix misaligned writes in CTR_DRBG and HASH_DRBG

Eric Biggers <[email protected]>
crypto: drbg - Fix returning success on failure in CTR_DRBG

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for ioctl(SNP_CONFIG)

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for ioctl(SNP_VLEK_LOAD)

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for ioctl(SNP_COMMIT)

Tycho Andersen (AMD) <[email protected]>
crypto: ccp - Do not initialize SNP for SEV ioctls

Eric Biggers <[email protected]>
crypto: loongson - Remove broken and unused loongson-rng

Eric Biggers <[email protected]>
crypto: loongson - Select CRYPTO_RNG

Wentao Liang <[email protected]>
crypto: tegra - fix refcount leak in tegra_se_host1x_submit()

Ruijie Li <[email protected]>
crypto: pcrypt - restore callback for non-parallel fallback

Eric Biggers <[email protected]>
crypto: hisi-trng - Remove crypto_rng interface

Anastasia Tishchenko <[email protected]>
crypto: ecc - Fix carry overflow in vli multiplication

Eric Biggers <[email protected]>
crypto: crypto4xx - Remove insecure and unused rng_alg

Xiaonan Zhao <[email protected]>
crypto: chacha20poly1305 - validate poly1305 template argument

Thorsten Blum <[email protected]>
crypto: caam - use print_hex_dump_devel to guard key hex dumps again

Thorsten Blum <[email protected]>
crypto: caam - use print_hex_dump_devel to guard key hex dumps

Eric Biggers <[email protected]>
crypto: af_alg - Remove zero-copy support from skcipher and aead

Bryam Vargas <[email protected]>
isofs: bound Rock Ridge symlink components to the SL record

Qu Wenruo <[email protected]>
btrfs: fix incorrect buffered IO fallback for append direct writes

Bryam Vargas <[email protected]>
partitions: aix: bound the pp_count scan to the ppe array

Qu Wenruo <[email protected]>
btrfs: do not trim a device which is not writeable

Qu Wenruo <[email protected]>
btrfs: check and set EXTENT_DELALLOC_NEW before clearing EXTENT_DELALLOC

Tianchu Chen <[email protected]>
nvmet-auth: validate reply message payload bounds against transfer length

Qu Wenruo <[email protected]>
btrfs: fix false IO failure after falling back to buffered write

Bryam Vargas <[email protected]>
nvmet: fix pre-auth out-of-bounds heap read in Discovery Get Log Page

Achkinazi, Igor <[email protected]>
nvme-multipath: set BIO_REMAPPED on bios remapped to per-path namespace disks

Mikulas Patocka <[email protected]>
dm-ioctl: report an error if a device has no table

Wentao Liang <[email protected]>
block: partitions: fix of_node refcount leak in of_partition()

Wentao Liang <[email protected]>
nvme: target: rdma: fix ndev refcount leak on queue connect

Thorsten Blum <[email protected]>
crypto: atmel-sha204a - fail on hwrng registration error in probe path

Thorsten Blum <[email protected]>
crypto: atmel-sha204a - drop hwrng quality reduction for ATSHA204A

Wentao Liang <[email protected]>
hwrng: jh7110 - fix refcount leak in starfive_trng_read()

Bryam Vargas <[email protected]>
udf: validate sparing table length as an entry count, not a byte count

Bryam Vargas <[email protected]>
udf: validate VAT header length against the VAT inode size

Michael Bommarito <[email protected]>
udf: validate free block extents against the partition length

Arjan van de Ven <[email protected]>
wifi: mt76: mt7921/mt7925: fix NULL dereference in CSA beacon

Chao Shi <[email protected]>
block: skip sync_blockdev() on surprise removal in bdev_mark_dead()

Neill Kapron <[email protected]>
usb: gadget: f_fs: Tie read_buffer lifetime to ffs_epfile

Neill Kapron <[email protected]>

    usb: gadget: f_fs: Initialize epfile->in early to fix endpoint direction checks

Paul Cercueil <[email protected]>
usb: gadget: f_fs: Fix DMA fence leak

Tyler Baker <[email protected]>
usb: gadget: f_fs: initialize reset_work at allocation time

Paul Menzel <[email protected]>
usb: typec: ucsi: cancel pending work on system suspend

Fan Wu <[email protected]>
usb: typec: ucsi: ccg: Fix use-after-free of ucsi on remove

Madhu M <[email protected]>
usb: typec: ucsi: Pass full DP config payload in SET_NEW_CAM for DP alt mode

Andrei Kuchynski <[email protected]>
usb: typec: ucsi: Invert DisplayPort role assignment

Badhri Jagan Sridharan <[email protected]>
usb: typec: tcpm: Validate SVID index in svdm_consume_modes()

Andy Yan <[email protected]>
usb: typec: tcpm: Fix VDM type for Enter Mode commands

Stephan Gerhold <[email protected]>
usb: typec: ps883x: Fix DP+USB3 configuration

Shuangpeng Bai <[email protected]>
usb: typec: class: drop PD lookup reference

Myeonghun Pak <[email protected]>
usb: typec: anx7411: use devm_pm_runtime_enable()

Sam Day <[email protected]>
usbip: vudc: fix NULL deref in vep_dequeue()

Yichong Chen <[email protected]>
usbip: tools: support SuperSpeedPlus devices

Xu Rao <[email protected]>
USB: usb-storage: ene_ub6250: restore media-ready check

Johan Hovold <[email protected]>
USB: ulpi: fix memory leak on registration failure

Johan Hovold <[email protected]>
USB: serial: digi_acceleport: fix write buffer corruption

Johan Hovold <[email protected]>
USB: serial: digi_acceleport: fix hard lockup on disconnect

Johan Hovold <[email protected]>
USB: serial: digi_acceleport: fix broken rx after throttle

Fabio Porcedda <[email protected]>
USB: serial: option: add Telit Cinterion FE990D50 compositions

Johan Hovold <[email protected]>
USB: serial: keyspan_pda: fix information leak

Haoxiang Li <[email protected]>
usb: mtu3: unmap request DMA on queue failure

Myeonghun Pak <[email protected]>
USB: misc: uss720: unregister parport on probe failure

HE WEI (ギカク) <[email protected]>
usb: misc: usbio: bound bulk IN response length to the received transfer

Xu Rao <[email protected]>
USB: storage: include US_FL_NO_SAME in quirks mask

Myeonghun Pak <[email protected]>
usb: sl811-hcd: disable controller wakeup on remove

Johan Hovold <[email protected]>
USB: legousbtower: fix use-after-free on disconnect race

Erich E. Hoover <[email protected]>
USB: quirks: add NO_LPM for the Samsung T5 EVO Portable SSD

Johan Hovold <[email protected]>
USB: iowarrior: fix use-after-free on disconnect race

Johan Hovold <[email protected]>
USB: iowarrior: fix use-after-free on disconnect

Johan Hovold <[email protected]>
USB: ldusb: fix use-after-free on disconnect race

Johan Hovold <[email protected]>
USB: idmouse: fix use-after-free on disconnect race

Xu Rao <[email protected]>
usb: gadget: f_printer: take kref only for successful open

Jimmy Hu <[email protected]>
usb: gadget: udc: Fix use-after-free in gadget_match_driver

Maoyi Xie <[email protected]>
usb: gadget: composite: fix dead empty check in the USB_DT_OTG handler

Dawei Feng <[email protected]>
usb: free iso schedules on failed submit

WenTao Liang <[email protected]>
usb: dwc3: meson-g12a: fix refcount leak in dwc3_meson_g12a_resume()

Ben Dooks <[email protected]>
usb: dwc3: fix dwc3_readl() and dwc3_writel() calls in dwc3_ulpi_setup()

Rodrigo Lugathe da Conceição Alves <[email protected]>
USB: core: add USB_QUIRK_NO_LPM for VIA Labs USB 2.0 hub

Haoxiang Li <[email protected]>
usb: cdnsp: fix stream context array leak in cdnsp_alloc_stream_info()

Jared Baldridge <[email protected]>
usb: cdc_acm: Add quirk for Uniden BC125AT scanner

Jens Glathe <[email protected]>
Revert "usb: typec: mux: avoid duplicated mux switches"

Maoyi Xie <[email protected]>
net: usb: kalmia: bound RX frame length in kalmia_rx_fixup()

Vlad Poenaru <[email protected]>
bpf: Allow LPM map access from sleepable BPF programs

Nuoqi Gui <[email protected]>
bpf: Keep dynamic inner array lookups nullable

Paul Moses <[email protected]>
bpf: Validate BTF repeated field counts before expansion

Dawei Feng <[email protected]>
bpf: Restore sysctl new-value from 1 to 0

Zhao Zhang <[email protected]>
bpf: Reject fragmented frames in devmap

Dawei Feng <[email protected]>
xfs: fix memory leak in xfs_dqinode_metadir_create()

Yingjie Gao <[email protected]>
xfs: fix exchmaps reservation limit check

Darrick J. Wong <[email protected]>
xfs: fix pointer arithmetic error on 32-bit systems

Alexey Nepomnyashih <[email protected]>
xfs: fix unreachable BIGTIME check in dquot flush validation

Christoph Hellwig <[email protected]>

    xfs: initialize iomap->flags earlier in xfs_bmbt_to_iomap

Christoph Hellwig <[email protected]>
xfs: only log freed extents for the current RTG in zoned growfs

Christoph Hellwig <[email protected]>
xfs: pass back updated nb from xfs_growfs_compute_deltas

Yingjie Gao <[email protected]>
xfs: release dquot buffer after dqflush failure

Yousef Alhouseen <[email protected]>
xfs: use null daddr for unset first bad log block

Andy Shevchenko <[email protected]>
serial: 8250_mid: Disable DMA for selected platforms

Louis-Alexis Eyraud <[email protected]>
media: mtk-jpeg: cancel workqueue on release for supported platforms only

Deepanshu Kartikey <[email protected]>
nilfs2: reject CLEAN_SEGMENTS ioctl with out-of-range segment numbers

Tristan Madani <[email protected]>
hfs/hfsplus: zero-initialize buffer in hfs_bnode_read

Tristan Madani <[email protected]>
hfs/hfsplus: fix u32 overflow in check_and_correct_requested_length

Srinivas Pandruvada <[email protected]>
HID: sensor-hub: Add sensor_hub_input_attr_read_values() for multi-byte reads

Maoyi Xie <[email protected]>
HID: lg-g15: cancel pending work on remove to fix a use-after-free

Manish Khadka <[email protected]>
HID: appleir: fix UAF on pending key_up_timer in remove()

Trung Nguyen <[email protected]>
HID: multitouch: fix out-of-bounds bit access on mt_io_flags

Manish Khadka <[email protected]>
HID: letsketch: fix UAF on inrange_timer at driver unbind

Jinmo Yang <[email protected]>
HID: wacom: use GFP_ATOMIC in wacom_wac_queue_flush()

Jinmo Yang <[email protected]>
HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert

Manish Khadka <[email protected]>
HID: hid-lenovo-go: cancel cfg_setup work in hid_go_cfg_remove()

Oleg Makarenko <[email protected]>
HID: pidff: Use correct effect type in effect update

Myeonghun Pak <[email protected]>
HID: wacom: stop hardware after post-start probe failures

Carlos Llamas <[email protected]>
HID: uhid: convert to hid_safe_input_report()

Tianchu Chen <[email protected]>
HID: hid-goodix-spi: validate report size to prevent stack buffer overflow

Yichong Chen <[email protected]>
tools/mm/slabinfo: fix total_objects attribute name

Xuewen Wang <[email protected]>
tools/mm/slabinfo: Fix trace disable logic inversion

Vlastimil Babka (SUSE) <[email protected]>
mm/slab: do not limit zeroing to orig_size when only red zoning is enabled

Lukas Wunner <[email protected]>
X.509: Fix validation of ASN.1 certificate header

Robin Murphy <[email protected]>
perf/arm-cmn: Fix DVM node events

Heiko Carstens <[email protected]>
s390: Revert support for DCACHE_WORD_ACCESS

Kartik Rajput <[email protected]>
clocksource/drivers/timer-tegra186: Fix support for multiple watchdog instances

Thomas Gleixner <[email protected]>
time/jiffies: Register jiffies clocksource before usage

WenTao Liang <[email protected]>
posix-cpu-timers: Fix pid refcount leak in do_cpu_nanosleep() error path

Jann Horn <[email protected]>
proc: protect ptrace_may_access() with exec_update_lock (part 1)

Yuho Choi <[email protected]>
cpufreq: pcc: fix use-after-free and double free in _OSC evaluation

Tianxiang Chen <[email protected]>
cpufreq: Fix hotplug-suspend race during reboot

Steven Rostedt <[email protected]>
sched/rt: Have RT_PUSH_IPI be default off for non PREEMPT_RT

Fushuai Wang <[email protected]>

    cpufreq: intel_pstate: Sync policy->cur during CPU offline

Zide Chen <[email protected]>
perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box()

Jann Horn <[email protected]>
proc: protect ptrace_may_access() with exec_update_lock (FD links)

John Hubbard <[email protected]>
libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo()

Guangshuo Li <[email protected]>
firmware_loader: fix device reference leak in firmware_upload_register()

Guangshuo Li <[email protected]>
cpufreq: qcom-cpufreq-hw: Fix possible double free

Abdun Nihaal <[email protected]>
OPP: of: Fix potential memory leak in opp_parse_supplies()

Baokun Li <[email protected]>
writeback: fix race between cgroup_writeback_umount() and inode_switch_wbs()

ChenXiaoSong <[email protected]>
smb/server: do not require delete access for non-replacing links

Norbert Manthey <[email protected]>
smb: client: mask server-provided mode to 07777 in modefromsid

Xu Rao <[email protected]>
smb: client: fix atime clamp check in read completion

Zihan Xi <[email protected]>
smb: client: harden POSIX SID length parsing

Zihan Xi <[email protected]>
smb: client: use unaligned reads in parse_posix_ctxt()

Haoxiang Li <[email protected]>
smb: client: Fix next buffer leak in receive_encrypted_standard()

Henrique Carvalho <[email protected]>
smb: client: fix double-free in SMB2_close() replay

Henrique Carvalho <[email protected]>
smb: client: fix double-free in SMB2_open() replay

Zhao Zhang <[email protected]>
smb: client: fix double-free in SMB2_flush() replay

Henrique Carvalho <[email protected]>
smb: client: fix change notify replay double-free

Henrique Carvalho <[email protected]>
smb: client: fix double-free in SMB2_ioctl() replay

Henrique Carvalho <[email protected]>
smb: client: fix query_info() replay double-free

Henrique Carvalho <[email protected]>
smb: client: fix query directory replay double-free

Ralph Boehme <[email protected]>
smb/client: fix chown/chgrp with SMB3 POSIX Extensions

Haofeng Li <[email protected]>
ksmbd: validate NTLMv2 response before updating session key

Namjae Jeon <[email protected]>
ksmbd: track the connection owning a byte-range lock

Namjae Jeon <[email protected]>
ksmbd: use opener credentials for ADS I/O

Namjae Jeon <[email protected]>
ksmbd: use opener credentials for delete-on-close

Gil Portnoy <[email protected]>
ksmbd: add per-handle permission check to FILE_LINK_INFORMATION

Gil Portnoy <[email protected]>
ksmbd: enforce FILE_READ_ATTRIBUTES on SMB_FIND_FILE_POSIX_INFORMATION

Namjae Jeon <[email protected]>
ksmbd: run set info with opener credentials

Gil Portnoy <[email protected]>
ksmbd: add a WRITE_DAC/WRITE_OWNER check to SMB2 SET_INFO SECURITY

Namjae Jeon <[email protected]>
ksmbd: require source read access for duplicate extents

Davide Ornaghi <[email protected]>
ksmbd: fix UAF of struct file_lock in SMB2_LOCK deferred-lock cancellation

Namjae Jeon <[email protected]>
ksmbd: serialize QUERY_DIRECTORY requests per file

Gil Portnoy <[email protected]>
ksmbd: add a permission check for FSCTL_SET_ZERO_DATA

Gil Portnoy <[email protected]>
ksmbd: add permission checks for FSCTL_DUPLICATE_EXTENTS_TO_FILE

Namjae Jeon <[email protected]>
ksmbd: prevent path traversal bypass by restricting caseless retry

Dan Carpenter <[email protected]>
smb/client: Fix error code in smb2_aead_req_alloc()

Michael Bommarito <[email protected]>
smb: client: resolve SWN tcon from live registrations

Junrui Luo <[email protected]>
coresight: ultrasoc-smb: Fix OOB write in smb_sync_perf_buffer()

Muhammad Bilal <[email protected]>
Bluetooth: L2CAP: validate option length before reading conf opt value

Runyu Xiao <[email protected]>

    Bluetooth: L2CAP: cancel pending_rx_work before taking conn->lock

Muhammad Bilal <[email protected]>
Bluetooth: ISO: avoid NULL deref of conn in iso_conn_big_sync()

Pauli Virtanen <[email protected]>
Bluetooth: hci_uart: clear HCI_UART_SENDING when write_work is canceled

Siwei Zhang <[email protected]>
Bluetooth: hci_conn: Fix null ptr deref in hci_abort_conn()

Yousef Alhouseen <[email protected]>
Bluetooth: fix UAF in bt_accept_dequeue()

Maoyi Xie <[email protected]>
Bluetooth: btnxpuart: Fix out-of-bounds firmware read in nxp_recv_fw_req_v3()

Yousef Alhouseen <[email protected]>
Bluetooth: bnep: pin L2CAP connection during netdev registration

Sergey Senozhatsky <[email protected]>
Bluetooth: btmtksdio: fix infinite loop in btmtksdio_txrx_work()

Pablo Neira Ayuso <[email protected]>
netfilter: flowtable: IPIP tunnel hardware offload is not yet support

Adrian Bente <[email protected]>
netfilter: flowtable: fix offloaded ct timeout never being extended

Xiang Mei <[email protected]>
netfilter: ebtables: terminate table name before find_table_lock()

Florian Westphal <[email protected]>
netfilter: ebtables: module names must be null-terminated

Florian Westphal <[email protected]>
netfilter: ebtables: zero chainstack array

Florian Westphal <[email protected]>
netfilter: handle unreadable frags

Pratham Gupta <[email protected]>
netfilter: ctnetlink: use nf_ct_exp_net() in expectation dump

Zijiang Huang <[email protected]>
mm/swap: add cond_resched() in swap_reclaim_full_clusters to prevent softlockup

Jose Fernandez (Anthropic) <[email protected]>
mm: swap_cgroup: fix NULL deref in lookup_swap_cgroup_id on swapless host

Qi Zheng <[email protected]>
mm: shrinker: fix NULL pointer dereference in debugfs

Qi Zheng <[email protected]>
mm: shrinker: fix shrinker_info teardown race with expansion

Shakeel Butt <[email protected]>
mm/shrinker: do not hold RCU lock in shrinker_debugfs_count_show()

Andrei Kuchynski <[email protected]>
mfd: cros_ec: Delay dev_set_drvdata() until probe success

Xiaolei Wang <[email protected]>
media: nxp: imx8-isi: Fix use-after-free on remove

Wyatt Feng <[email protected]>
net: ipv4: bound TCP reordering sysctl writes and MTU probe sizes

Yuyang Huang <[email protected]>
ipv4: igmp: remove multicast group from hash table on device destruction

Breno Leitao <[email protected]>
netpoll: fix a use-after-free on shutdown path

Michael Wigham <[email protected]>
io_uring/rw: preserve partial result for iopoll

Runyu Xiao <[email protected]>
io_uring/io-wq: re-check IO_WQ_BIT_EXIT for each linked work item

Vasileios Almpanis <[email protected]>
io_uring/nop: fix file reference leak with IOSQE_FIXED_FILE

HyeongJun An <[email protected]>
HID: logitech-dj: Fix maxfield check in DJ short report validation

Runyu Xiao <[email protected]>
gpio: sch: use raw_spinlock_t in the irq startup path

Runyu Xiao <[email protected]>
gpio: eic-sprd: use raw_spinlock_t in the irq startup path

Koichiro Den <[email protected]>
NTB: epf: Avoid calling pci_irq_vector() from hardirq context

Valeriy Yashnikov <[email protected]>
ntfs: avoid calling post_write_mst_fixup() for invalid index_block

Yunpeng Tian <[email protected]>
fs/ntfs3: validate Dirty Page Table capacity in log_replay copy_lcns

Thomas Gleixner <[email protected]>
debugobjects: Plug race against a concurrent OOM disable

Runyu Xiao <[email protected]>
coresight: etb10: restore atomic_t for shared reading state

Samuel Page <[email protected]>
Bluetooth: MGMT: Fix UAF of hci_conn_params in add_device_complete

Marco Elver <[email protected]>
Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref

Chi Wang <[email protected]>
audit: Fix data races of skb_queue_len() readers on audit_queue

Zijing Yin <[email protected]>
net: af_key: initialize alg_key_len for IPComp states

Gil Portnoy <[email protected]>
ksmbd: fix use-after-free of a deferred file_lock on SMB2_CLOSE then SMB2_CANCEL

Giovanni Cabiddu <[email protected]>
crypto: qat - fix VF2PF work teardown race in adf_disable_sriov()

Michael Bommarito <[email protected]>
crypto: krb5 - filter out async aead implementations at alloc

Dawei Feng <[email protected]>
crypto: amlogic - avoid double cleanup in meson_crypto_probe()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB write in HT_caps_handler()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB reads in rtw_get_sec_ie(), rtw_get_wapi_ie(), and rtw_get_wps_attr()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB reads in is_ap_in_tkip() IE loop

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB reads in IE loops in issue_assocreq() and join_cmd_hdl()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB read in update_beacon_info() IE loop

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix OOB read in OnAssocRsp() IE loop

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix WEP length underflow and OOB read in OnAuth()

Alexandru Hossu <[email protected]>
staging: rtl8723bs: fix heap buffer overflow in rtw_cfg80211_set_wpa_ie()

Christopher Mackle <[email protected]>
staging: rtl8723bs: don't drop short TX frames in _rtw_pktfile_read()

Alexandru Hossu <[email protected]>
staging: media: ipu7: fix double-free and use-after-free in error paths

Arnd Bergmann <[email protected]>
staging: media: atomisp: reduce load_primary_binaries() stack usage

Ricardo Ribalda <[email protected]>
media: staging: ipu3-imgu: Add range check for imgu_css_cfg_acc_stripe

Hao-Qun Huang <[email protected]>
staging: vme_user: fix location monitor leak in tsi148 bridge

Hao-Qun Huang <[email protected]>
staging: vme_user: fix location monitor leak in fake bridge

Shoichiro Miyamoto <[email protected]>
smb: client: restrict implied bcc[0] exemption to responses without data area

Michael Tautschnig <[email protected]>
staging: vme_user: bound slave read/write to the kern_buf size

Samuel Page <[email protected]>
tipc: fix out-of-bounds read in broadcast Gap ACK blocks

Yuanhe Shu <[email protected]>
tracing: Fix NULL pointer dereference in func_set_flag()

Yizhou Zhao <[email protected]>
6lowpan: fix NHC entry use-after-free on error path

Cen Zhang <[email protected]>
usb: misc: usbio: fix disconnect UAF in client teardown

Runyu Xiao <[email protected]>
usb: dwc3: run gadget disconnect from sleepable suspend context

Alan Stern <[email protected]>
USB: chaoskey: Fix slab-use-after-free in chaoskey_release()

Michael Bommarito <[email protected]>
hwrng: virtio: clamp device-reported used.len at copy_data()

Johan Hovold <[email protected]>
virtio-mmio: fix device release warning on module unload

Ammar Faizi <[email protected]>
virtio_pci: fix vq info pointer lookup via wrong index

Xiang Mei <[email protected]>
netfilter: ipset: fix race between dump and ip_set_list resize

SeongJae Park <[email protected]>
mm/damon/ops-common: handle extreme intervals in damon_hot_score()

Michael Bommarito <[email protected]>
tcp: restore RCU grace period in tcp_ao_destroy_sock

Marco Nenciarini <[email protected]>
PCI/IOV: Skip VF Resizable BAR restore on read error

Marco Nenciarini <[email protected]>
PCI: Skip Resizable BAR restore on read error

Yadu M G <[email protected]>
PCI: qcom: Initialize DWC MSI lock for firmware-managed ECAM hosts

Manivannan Sadhasivam <[email protected]>
PCI: mediatek: Fix IRQ domain leak when port fails to enable

Richard Zhu <[email protected]>
PCI: imx6: Assert ref_clk_en after reference clock stabilizes on i.MX95

Richard Zhu <[email protected]>
PCI: imx6: Fix IMX6SX_GPR12_PCIE_TEST_POWERDOWN handling

Richard Zhu <[email protected]>
PCI: imx6: Configure REF_USE_PAD before PHY reset for i.MX95

Ratheesh Kannoth <[email protected]>
PCI: host-common: Request bus reassignment when not probe-only

Maciej W. Rozycki <[email protected]>
PCI: Always lift 2.5GT/s restriction in PCIe failed link retraining

Mahesh Vaidya <[email protected]>
PCI: altera: Fix resource leaks on probe failure

Mahesh Vaidya <[email protected]>
PCI: altera: Do not dispose parent IRQ mapping

Ziyao Li <[email protected]>
PCI: loongson: Override PCIe bridge supported speeds for Loongson-3C6000 series

Han Gao <[email protected]>
riscv: dts: sophgo: Add dma-coherent to SG2042 PCIe controllers

Myeonghun Pak <[email protected]>
usb: typec: tcpci_rt1711h: unregister TCPCI port with devres

Xu Rao <[email protected]>
xhci: sideband: fix ring sg table pages leak

胡连勤 <[email protected]>
usb: xhci: Fix sleep in atomic context in xhci_free_streams()

Alice Ryhl <[email protected]>
rust_binder: clear freeze listener on node removal

Keshav Verma <[email protected]>
rust_binder: synchronize Rust Binder stats with freeze commands

Keshav Verma <[email protected]>
rust_binder: reject context manager self-transaction

Alice Ryhl <[email protected]>
rust_binder: fix BINDER_GET_EXTENDED_ERROR

Hyunwoo Kim <[email protected]>
rust_binder: use a u64 stride when cleaning up the offsets array

Carlos Llamas <[email protected]>
binder: fix UAF in binder_free_transaction()

Carlos Llamas <[email protected]>
binder: fix UAF in binder_thread_release()

Johan Hovold <[email protected]>
Bluetooth: btusb: fix wakeup source leak on probe failure

Johan Hovold <[email protected]>
Bluetooth: btusb: fix use-after-free on marvell probe failure

Johan Hovold <[email protected]>
Bluetooth: btusb: fix use-after-free on registration failure

Zenm Chen <[email protected]>
Bluetooth: btusb: Add USB ID 2c4e:0128 for Mercusys MA60XNB

Alex Williamson <[email protected]>
vfio/mlx5: Fix racy bitfields and tighten struct layout

Alex Williamson <[email protected]>
vfio: Remove device debugfs before releasing devres

Junrui Luo <[email protected]>
vfio: prevent infinite loop in vfio_mig_get_next_state() on blocked arc

Alex Williamson <[email protected]>
vfio/pci: Fix racy bitfields and tighten struct layout

Alex Williamson <[email protected]>
vfio/pci: Release the VGA arbiter client on register_device() failure

Alex Williamson <[email protected]>
vfio/pci: Latch disable_idle_d3 per device

Raghavendra Rao Ananta <[email protected]>
vfio/pci: Use a private flag to prevent power state change with VFs

Reinette Chatre <[email protected]>
x86,fs/resctrl: Prevent out-of-bounds access while offlining CPU when SNC enabled

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Update Babyface Pro control caches only after successful writes

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Roll back quirk control caches on write errors

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks

Cássio Gabriel <[email protected]>
ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()

Darvell Long <[email protected]>
ALSA: usb-audio: avoid kobject path lookup in DualSense match

Gordon Chen <[email protected]>
ALSA: usb-audio: add IFB_SILENCE_ON_EMPTY quirk for Behringer Flow 8

WenTao Liang <[email protected]>
ALSA: us144mkii: capture_urb_complete: redundant usb_anchor_urb corrupts anchor list on each resubmission

HyeongJun An <[email protected]>
ALSA: seq: Fix uninitialised heap leak in snd_seq_event_dup()

Zhao Dongdong <[email protected]>
ALSA: ice1712: check snd_ctl_new1() return value

Aaron Erhardt <[email protected]>
ALSA: hda/realtek: Fix noisy mic for Clevo V6xxAW

Huacai Chen <[email protected]>
ALSA: hda/hdmi: Use 'AC_PINSENSE_ELDV' to detect pinsense for Loongson

Cameron Graham <[email protected]>
ALSA: hda/hdmi: Add force-connect quirk for HP EliteDesk 800 G5 Mini

Cássio Gabriel <[email protected]>
ALSA: hda/cs35l41: Fix firmware load work teardown

Zhao Dongdong <[email protected]>
ALSA: gus: check snd_ctl_new1() return value

Maoyi Xie <[email protected]>
ALSA: firewire: isight: bound the sample count to the packet payload

Geoffrey D. Bennett <[email protected]>
ALSA: FCP: Add Focusrite ISA C8X support

Zhao Dongdong <[email protected]>
ALSA: es1938: check snd_ctl_new1() return value

Cássio Gabriel <[email protected]>
ALSA: compress: Fix task creation error unwind

Zhao Dongdong <[email protected]>
ALSA: cmipci: check snd_ctl_new1() return value

Maoyi Xie <[email protected]>
ALSA: caiaq: fix out-of-bounds read in the Traktor Kontrol S4 input parser

Zhao Dongdong <[email protected]>
ALSA: aoa: check snd_ctl_new1() return value

Zhao Dongdong <[email protected]>
ALSA: ymfpci: check snd_ctl_new1() return value

Cássio Gabriel <[email protected]>
ALSA: virtio: Validate control metadata from the device

Cássio Gabriel <[email protected]>
ALSA: virtio: Add missing 384 kHz PCM rate mapping

HyeongJun An <[email protected]>
ALSA: usx2y: us144mkii: fix work UAF on disconnect

Stepan Ionichev <[email protected]>
iio: temperature: tmp006: use devm_iio_trigger_register

Liviu Stan <[email protected]>
iio: temperature: ltc2983: Fix reinit_completion() called after conversion start

Liviu Stan <[email protected]>
iio: temperature: ltc2983: Fix n_wires default bypassing rotation check

Pengpeng Hou <[email protected]>
iio: temperature: Build mlx90635 with CONFIG_MLX90635

Stepan Ionichev <[email protected]>
iio: resolver: ad2s1210: notify trigger and clear state on fault read error

Stepan Ionichev <[email protected]>

    iio: proximity: vl53l0x: notify trigger and clear IRQ on error paths

Biren Pandya <[email protected]>
iio: pressure: mpl115: fix runtime PM leak on read error

David Carlier <[email protected]>
iio: pressure: bmp280: zero-init bmp580 trigger handler buffer

Andy Shevchenko <[email protected]>
iio: magnetometer: ak8975: Add missed pm_runtime_put_autosuspend() call

Javier Carrasco <[email protected]>
iio: light: veml6030: fix channel type when pushing events

Stepan Ionichev <[email protected]>
iio: light: tsl2591: return actual error from probe IRQ failure

Joshua Crofts <[email protected]>
iio: light: opt3001: fix missing state reset on timeout

Biren Pandya <[email protected]>
iio: light: gp2ap002: fix runtime PM leak on read error

Alexander A. Klimov <[email protected]>
iio: light: al3320a: read both ALS ADC registers again

Joshua Crofts <[email protected]>
iio: light: al3320a: add missing REGMAP_I2C to Kconfig

Alexander A. Klimov <[email protected]>
iio: light: al3010: read both ALS ADC registers again

Vidhu Sarwal <[email protected]>
iio: light: al3010: fix incorrect scale for the highest gain range

Joshua Crofts <[email protected]>
iio: light: al3010: add missing REGMAP_I2C to Kconfig

Joshua Crofts <[email protected]>
iio: light: al3000a: add missing REGMAP_I2C to Kconfig

Andreas Kempe <[email protected]>
iio: imu: st_lsm6dsx: deselect shub page before reading whoami

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading

Jean-Baptiste Maneyrol <[email protected]>
iio: imu: inv_icm42600: fix timestamp clock period by using lower value

Runyu Xiao <[email protected]>
iio: imu: bmi160: add IRQF_NO_THREAD to data-ready trigger IRQ

Runyu Xiao <[email protected]>
iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ

Stepan Ionichev <[email protected]>
iio: gyro: bmg160: wait full startup time after mode change at probe

Stepan Ionichev <[email protected]>
iio: gyro: bmg160: bail out when bandwidth/filter is not in table

Lars-Peter Clausen <[email protected]>
iio: event: Fix event FIFO reset race

Dan Carpenter <[email protected]>
iio: dac: ad3552r-hs: fix uninitialized data ni ad3552r_hs_write_data_source()

Dan Carpenter <[email protected]>
iio: core: fix uninitialized data in debugfs

Herman van Hazendonk <[email protected]>
iio: common: st_sensors: honour channel endianness in read_axis_data

Maxwell Doose <[email protected]>
iio: chemical: scd30: Cleanup initializations and fix sign-extension bug

Felix Gu <[email protected]>
iio: buffer: hw-consumer: free scan_mask on buffer release

Dan Carpenter <[email protected]>
iio: backend: fix uninitialized data in debugfs

Pengpeng Hou <[email protected]>
iio: adc: ti-ads124s08: Return reset GPIO lookup errors

Guangshuo Li <[email protected]>
iio: adc: ti-ads1119: fix PM reference leak in buffer preenable

Maxwell Doose <[email protected]>
iio: adc: spear: Initialize completion before requesting IRQ

Andy Shevchenko <[email protected]>
iio: adc: nxp-sar-adc: Fix the delay calculation in nxp_sar_adc_wait_for()

Maxwell Doose <[email protected]>
iio: adc: lpc32xx: Initialize completion before requesting IRQ

Radu Sabau <[email protected]>
iio: adc: ad_sigma_delta: fix CS held asserted and state leaks

Radu Sabau <[email protected]>
iio: adc: ad_sigma_delta: fix clear_pending_event for registerless devices

Joshua Crofts <[email protected]>
iio: adc: ad7779: add missing 'select IIO_TRIGGERED_BUFFER' to Kconfig

Jonathan Cameron <[email protected]>

    iio: adc: ad7768-1: Select GPIOLIB

Samuel Moelius <[email protected]>
iio: adc: ad7380: select REGMAP

Arnd Bergmann <[email protected]>
iio: adc: ad4062: add GPIOLIB dependency

Biren Pandya <[email protected]>
iio: accel: kxsd9: fix runtime PM imbalance on write_raw() error

Bryam Vargas <[email protected]>
iio: accel: bmc150: clamp the device-reported FIFO frame count

Griffin Kroah-Hartman <[email protected]>
usb: gadget: function: rndis: add length check for header

Griffin Kroah-Hartman <[email protected]>
usb: gadget: function: rndis: add length check to response query

Po-Hao Huang <[email protected]>
wifi: rtw89: correct drop logic for malformed AMPDU frames

Pawan Gupta <[email protected]>
bpf: Prefer dirty packs for eBPF allocations

Pawan Gupta <[email protected]>
bpf: Prefer packs that won't trigger an IBPB flush on allocation

Pawan Gupta <[email protected]>
bpf: Skip redundant IBPB in pack allocator

Pawan Gupta <[email protected]>
bpf: Restrict JIT predictor flush to cBPF

Pawan Gupta <[email protected]>
x86/bugs: Enable IBPB flush on BPF JIT allocation

Pawan Gupta <[email protected]>
bpf: Support for hardening against JIT spraying

Taeyang Lee <[email protected]>
perf/core: Detach event groups during remove_on_exec

Sebastian Andrzej Siewior <[email protected]>
futex/requeue: Revert "Prevent NULL pointer dereference in remove_waiter() on self-deadlock""

Alice Ryhl <[email protected]>
rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER

Gary Guo <[email protected]>
rust: doctest: fix incorrect pattern in replacement

Haoze Xie <[email protected]>
rust: block: fix GenDisk cleanup paths

Danilo Krummrich <[email protected]>
rust: pci: use 'static lifetime for PCI BAR resource names

Alice Ryhl <[email protected]>
rust: kasan: KASAN+RUST requires clang

Miguel Ojeda <[email protected]>
rust: cpufreq: clean new clippy::map_or_identity lint for Rust 1.98.0

Huacai Chen <[email protected]>
LoongArch: Add PIO for early access before ACPI PCI root register

HyeongJun An <[email protected]>
platform/x86: intel-hid: Protect ACPI notify handler against recursion

Rafael J. Wysocki <[email protected]>
ACPI: NFIT: core: Fix acpi_nfit_init() error cleanup

Rafael J. Wysocki <[email protected]>
ACPI: NFIT: core: Fix possible NULL pointer dereference

Jeremy Linton <[email protected]>
ACPI: CPPC: Suppress UBSAN warning caused by field misuse

Carlos López <[email protected]>
KVM: x86: Unconditionally recompute CR8 intercept on PPR update

Sean Christopherson <[email protected]>
KVM: VMX: Grab vmcs12 on CR8 interception update iff vCPU is in guest mode

Sean Christopherson <[email protected]>
KVM: x86: Move update_cr8_intercept() to lapic.c

Florian Fainelli <[email protected]>
perf trace beauty fcntl: Fix build with older kernel headers

Randy Dunlap <[email protected]>
slab: recognize @GFP parameter as optional in kernel-doc

Pedro Falcato <[email protected]>
mm/khugepaged: write all dirty file folios when collapsing

Xingquan Liu <[email protected]>
net/sched: dualpi2: fix GSO backlog accounting

Kiryl Shutsemau <[email protected]>
userfaultfd: gate must_wait writability check on pte_present()

Miguel Ojeda <[email protected]>
rust: str: clean unused import for Rust >= 1.98

Miguel Ojeda <[email protected]>
rust: str: use the "kernel vertical" imports style

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

Diffstat:

 Documentation/crypto/userspace-if.rst              |  31 +-
 Documentation/sound/alsa-configuration.rst         |   6 +
 MAINTAINERS                                        |   1 -
 Makefile                                           |   7 +-
 arch/arm64/include/asm/kvm_hyp.h                   |   1 +
 arch/arm64/kernel/entry-fpsimd.S                   |   8 +-
 arch/arm64/kvm/arm.c                               |   2 +
 arch/arm64/kvm/hyp/nvhe/hyp-main.c                 |  12 +
 arch/arm64/kvm/nested.c                            |  40 +-
 arch/arm64/net/bpf_jit_comp.c                      |   4 +-
 arch/loongarch/configs/loongson32_defconfig        |   1 -
 arch/loongarch/configs/loongson64_defconfig        |   1 -
 arch/loongarch/include/asm/acpi.h                  |   2 +
 arch/loongarch/kernel/acpi.c                       |  28 +
 arch/loongarch/kernel/setup.c                      |   2 +
 arch/loongarch/kvm/intc/eiointc.c                  |   6 +
 arch/loongarch/kvm/intc/ipi.c                      |   2 +
 arch/loongarch/kvm/intc/pch_pic.c                  |   2 +
 arch/loongarch/net/bpf_jit.c                       |   5 +-
 arch/loongarch/pci/acpi.c                          |   2 +
 arch/powerpc/net/bpf_jit_comp.c                    |   4 +-
 arch/riscv/boot/dts/sophgo/sg2042.dtsi             |   4 +
 arch/riscv/include/asm/pgtable.h                   |  10 +
 arch/riscv/kernel/entry.S                          |   7 +-
 arch/riscv/net/bpf_jit_comp64.c                    |   2 +-
 arch/riscv/net/bpf_jit_core.c                      |   3 +-
 arch/s390/Kconfig                                  |   1 -
 arch/s390/include/asm/asm-extable.h                |   4 -
 arch/s390/include/asm/word-at-a-time.h             |  22 -
 arch/s390/mm/extable.c                             |  18 -
 arch/x86/events/intel/uncore_snb.c                 |   7 -
 arch/x86/include/asm/nospec-branch.h               |   4 +
 arch/x86/kernel/cpu/bugs.c                         |  50 +-
 arch/x86/kernel/cpu/resctrl/monitor.c              |   5 +
 arch/x86/kvm/lapic.c                               |  49 +-
 arch/x86/kvm/lapic.h                               |   3 +-
 arch/x86/kvm/svm/avic.c                            |  47 +-
 arch/x86/kvm/svm/sev.c                             |  10 +-
 arch/x86/kvm/svm/svm.c                             |   3 +
 arch/x86/kvm/vmx/pmu_intel.c                       |   6 +-
 arch/x86/kvm/vmx/tdx.c                             |  16 +-
 arch/x86/kvm/vmx/vmx.c                             |  44 +-
 arch/x86/kvm/x86.c                                 |  38 +-
 arch/x86/mm/init_64.c                              |  40 +-
 arch/x86/net/bpf_jit_comp.c                        |   5 +-
 block/bdev.c                                       |   8 +-
 block/partitions/aix.c                             |   9 +
 block/partitions/of.c                              |   5 +-
 crypto/af_alg.c                                    |  69 +--
 crypto/algif_aead.c                                |   8 +-
 crypto/asymmetric_keys/x509_loader.c               |   2 +-
 crypto/chacha20poly1305.c                          |  11 +-
 crypto/df_sp80090a.c                               |   7 +-
 crypto/drbg.c                                      |  16 +-
 crypto/ecc.c                                       |  31 +-
 crypto/krb5/krb5_api.c                             |   2 +-
 crypto/pcrypt.c                                    |   4 +
 drivers/acpi/cppc_acpi.c                           |  11 +-
 drivers/acpi/nfit/core.c                           |  21 +-
 drivers/android/binder.c                           |  19 +-
 drivers/android/binder/allocation.rs               |   5 +-
 drivers/android/binder/error.rs                    |  13 +-
 drivers/android/binder/freeze.rs                   |  11 +-
 drivers/android/binder/node.rs                     |  10 +-
 drivers/android/binder/process.rs                  |  18 +-
 drivers/android/binder/rust_binder_events.c        |   7 +-
 drivers/android/binder/stats.rs                    |   4 +-
 drivers/android/binder/thread.rs                   |  65 ++-
 drivers/android/binder/transaction.rs              |  15 +-
 drivers/base/firmware_loader/sysfs_upload.c        |   8 +-
 drivers/bluetooth/btmtksdio.c                      |   2 +-
 drivers/bluetooth/btnxpuart.c                      |   6 +
 drivers/bluetooth/btusb.c                          |  39 +-
 drivers/bluetooth/hci_ldisc.c                      |  14 +-
 drivers/char/hw_random/jh7110-trng.c               |  13 +-
 drivers/char/hw_random/virtio-rng.c                |  23 +-
 drivers/clocksource/timer-tegra186.c               |   3 +-
 drivers/cpufreq/cpufreq.c                          |   2 +
 drivers/cpufreq/intel_pstate.c                     |   6 +-
 drivers/cpufreq/pcc-cpufreq.c                      |   2 +
 drivers/cpufreq/qcom-cpufreq-hw.c                  |   1 -
 drivers/crypto/Kconfig                             |   2 -
 drivers/crypto/Makefile                            |   1 -
 drivers/crypto/amcc/crypto4xx_core.c               |  88 ----
 drivers/crypto/amcc/crypto4xx_core.h               |   4 -
 drivers/crypto/amcc/crypto4xx_reg_def.h            |  11 -
 drivers/crypto/amlogic/amlogic-gxl-core.c          |   2 +-
 drivers/crypto/atmel-sha204a.c                     |  27 +-
 drivers/crypto/caam/caamalg.c                      |  12 +-
 drivers/crypto/caam/caamalg_qi.c                   |  12 +-
 drivers/crypto/caam/caamalg_qi2.c                  |  12 +-
 drivers/crypto/caam/caamhash.c                     |   4 +-
 drivers/crypto/caam/key_gen.c                      |   4 +-
 drivers/crypto/ccp/sev-dev.c                       |  70 +--
 drivers/crypto/hisilicon/Kconfig                   |   1 -
 drivers/crypto/hisilicon/trng/trng.c               | 296 +----------
 drivers/crypto/intel/qat/qat_420xx/adf_drv.c       |   2 -
 drivers/crypto/intel/qat/qat_4xxx/adf_drv.c        |   2 -
 drivers/crypto/intel/qat/qat_6xxx/adf_drv.c        |   2 -
 drivers/crypto/intel/qat/qat_c3xxx/adf_drv.c       |   1 -
 drivers/crypto/intel/qat/qat_c3xxxvf/adf_drv.c     |   1 -
 drivers/crypto/intel/qat/qat_c62x/adf_drv.c        |   1 -
 drivers/crypto/intel/qat/qat_c62xvf/adf_drv.c      |   1 -
 .../intel/qat/qat_common/adf_accel_devices.h       |   2 +
 drivers/crypto/intel/qat/qat_common/adf_aer.c      | 109 ++--
 .../crypto/intel/qat/qat_common/adf_common_drv.h   |   3 +
 drivers/crypto/intel/qat/qat_common/adf_init.c     |  18 +
 drivers/crypto/intel/qat/qat_common/adf_isr.c      |  39 ++
 drivers/crypto/intel/qat/qat_common/adf_sriov.c    |  32 +-
 .../crypto/intel/qat/qat_common/qat_asym_algs.c    |  10 +-
 drivers/crypto/intel/qat/qat_dh895xcc/adf_drv.c    |   1 -
 drivers/crypto/intel/qat/qat_dh895xccvf/adf_drv.c  |   1 -
 drivers/crypto/loongson/Kconfig                    |   5 -
 drivers/crypto/loongson/Makefile                   |   1 -
 drivers/crypto/loongson/loongson-rng.c             | 209 --------
 drivers/crypto/talitos.c                           | 561 +++++++++++----------
 drivers/crypto/talitos.h                           |  12 +
 drivers/crypto/tegra/tegra-se-main.c               |   2 +-
 drivers/dma-buf/udmabuf.c                          |   9 +-
 drivers/edac/i10nm_base.c                          |  14 +-
 drivers/fpga/dfl-afu-main.c                        |   3 +
 drivers/gpio/gpio-eic-sprd.c                       |   8 +-
 drivers/gpio/gpio-sch.c                            |  32 +-
 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.c      |  31 +-
 drivers/hid/hid-appleir.c                          |  45 +-
 drivers/hid/hid-goodix-spi.c                       |   3 +
 drivers/hid/hid-lenovo-go.c                        |   9 +
 drivers/hid/hid-letsketch.c                        |  36 +-
 drivers/hid/hid-lg-g15.c                           |  16 +
 drivers/hid/hid-logitech-dj.c                      |   9 +-
 drivers/hid/hid-multitouch.c                       |  32 +-
 drivers/hid/hid-sensor-hub.c                       |  77 ++-
 drivers/hid/uhid.c                                 |   8 +-
 drivers/hid/usbhid/hid-pidff.c                     |   2 +-
 drivers/hid/wacom_sys.c                            |  20 +-
 drivers/hwtracing/coresight/coresight-etb10.c      |   6 +-
 drivers/hwtracing/coresight/ultrasoc-smb.c         |   1 +
 drivers/i2c/busses/i2c-davinci.c                   |   4 +-
 drivers/i2c/busses/i2c-i801.c                      |   2 +-
 drivers/i2c/busses/i2c-imx-lpi2c.c                 |  15 +-
 drivers/i2c/busses/i2c-mpc.c                       |   2 +-
 drivers/i2c/busses/i2c-stm32f7.c                   |   9 +-
 drivers/i2c/i2c-core-base.c                        |  81 +--
 drivers/iio/accel/bmc150-accel-core.c              |   2 +
 drivers/iio/accel/kxsd9.c                          |   5 +-
 drivers/iio/adc/Kconfig                            |   4 +
 drivers/iio/adc/ad_sigma_delta.c                   |  39 +-
 drivers/iio/adc/lpc32xx_adc.c                      |   4 +-
 drivers/iio/adc/nxp-sar-adc.c                      |   4 +-
 drivers/iio/adc/spear_adc.c                        |   3 +-
 drivers/iio/adc/ti-ads1119.c                       |   6 +-
 drivers/iio/adc/ti-ads124s08.c                     |   3 +-
 drivers/iio/buffer/industrialio-hw-consumer.c      |   2 +
 drivers/iio/chemical/scd30_core.c                  |  19 +-
 drivers/iio/common/st_sensors/st_sensors_core.c    |  23 +-
 drivers/iio/dac/ad3552r-hs.c                       |   2 +-
 drivers/iio/gyro/bmg160_core.c                     |  16 +-
 drivers/iio/imu/adis_trigger.c                     |   2 +-
 drivers/iio/imu/bmi160/bmi160_core.c               |   3 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c  |   4 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |   9 +-
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |   1 +
 drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c   |   4 +-
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c       |  21 +-
 drivers/iio/industrialio-backend.c                 |   2 +-
 drivers/iio/industrialio-core.c                    |   2 +-
 drivers/iio/industrialio-event.c                   |   5 +-
 drivers/iio/light/Kconfig                          |   3 +
 drivers/iio/light/al3010.c                         |  10 +-
 drivers/iio/light/al3320a.c                        |   8 +-
 drivers/iio/light/gp2ap002.c                       |   2 +-
 drivers/iio/light/opt3001.c                        |   6 +-
 drivers/iio/light/tsl2591.c                        |   6 +-
 drivers/iio/light/veml6030.c                       |   8 +-
 drivers/iio/magnetometer/ak8975.c                  |   1 +
 drivers/iio/pressure/bmp280-core.c                 |   2 +-
 drivers/iio/pressure/mpl115.c                      |   4 +-
 drivers/iio/proximity/vl53l0x-i2c.c                |   7 +-
 drivers/iio/resolver/ad2s1210.c                    |   2 +-
 drivers/iio/temperature/Makefile                   |   2 +-
 drivers/iio/temperature/ltc2983.c                  |   5 +-
 drivers/iio/temperature/tmp006.c                   |   2 +-
 drivers/infiniband/core/addr.c                     |   2 +-
 drivers/infiniband/sw/siw/siw_qp_rx.c              |   9 +
 drivers/infiniband/ulp/rtrs/rtrs-srv.c             |   5 +-
 drivers/input/joystick/iforce/iforce-packets.c     |  18 +-
 drivers/input/joystick/maplecontrol.c              |   3 +-
 drivers/input/keyboard/maple_keyb.c                |   4 +-
 drivers/input/mouse/elan_i2c_core.c                |  36 +-
 drivers/input/mouse/maplemouse.c                   |   9 +-
 drivers/input/rmi4/rmi_bus.c                       |   4 +-
 drivers/input/rmi4/rmi_f30.c                       |   2 +-
 drivers/input/rmi4/rmi_f3a.c                       |   2 +-
 drivers/input/serio/gscps2.c                       |   1 +
 drivers/input/touchscreen/ads7846.c                |   5 +-
 drivers/input/touchscreen/goodix.c                 |   3 +-
 drivers/input/touchscreen/mms114.c                 |  26 +-
 drivers/input/touchscreen/touchwin.c               |  15 +-
 drivers/iommu/amd/iommu.c                          |   3 +-
 drivers/iommu/intel/iommu.h                        |  11 +
 drivers/iommu/intel/svm.c                          |  12 +-
 drivers/iommu/iommufd/driver.c                     |  13 +-
 drivers/iommu/iommufd/eventq.c                     |  36 +-
 drivers/iommu/iommufd/hw_pagetable.c               |  11 +-
 drivers/iommu/iommufd/iommufd_private.h            |   2 +-
 drivers/md/dm-ioctl.c                              |   5 +-
 .../media/platform/mediatek/jpeg/mtk_jpeg_core.c   |   3 +-
 .../media/platform/nxp/imx8-isi/imx8-isi-core.c    |   2 +-
 drivers/mfd/cros_ec_dev.c                          |   3 +-
 drivers/net/usb/kalmia.c                           |   8 +
 drivers/net/wireless/mediatek/mt76/mt7921/main.c   |   3 +
 drivers/net/wireless/mediatek/mt76/mt7925/main.c   |   3 +
 drivers/net/wireless/realtek/rtw89/core.c          |   3 +-
 drivers/net/wireless/realtek/rtw89/mac80211.c      |   3 +-
 drivers/ntb/hw/epf/ntb_hw_epf.c                    |  14 +-
 drivers/nvme/host/multipath.c                      |   6 +
 drivers/nvme/target/discovery.c                    |  23 +-
 drivers/nvme/target/fabrics-cmd-auth.c             |  15 +-
 drivers/nvme/target/rdma.c                         |   6 +-
 drivers/opp/of.c                                   |   3 +-
 drivers/pci/controller/dwc/pci-imx6.c              |  65 ++-
 drivers/pci/controller/dwc/pcie-qcom.c             |   6 +
 drivers/pci/controller/pci-host-common.c           |   4 +
 drivers/pci/controller/pci-loongson.c              |  36 ++
 drivers/pci/controller/pcie-altera.c               |  36 +-
 drivers/pci/controller/pcie-mediatek.c             |  65 ++-
 drivers/pci/iov.c                                  |   6 +
 drivers/pci/quirks.c                               |  51 +-
 drivers/pci/rebar.c                                |   6 +
 drivers/perf/arm-cmn.c                             |  23 +-
 drivers/platform/x86/intel/hid.c                   |   9 +
 drivers/regulator/scmi-regulator.c                 |   4 +-
 drivers/spi/spi-fsl-lpspi.c                        |  18 +-
 drivers/staging/media/atomisp/pci/sh_css.c         |   6 +-
 drivers/staging/media/ipu3/ipu3-css-params.c       |   8 +-
 drivers/staging/media/ipu7/ipu7.c                  |  22 +-
 drivers/staging/rtl8723bs/core/rtw_ieee80211.c     |  15 +
 drivers/staging/rtl8723bs/core/rtw_mlme_ext.c      |  20 +-
 drivers/staging/rtl8723bs/core/rtw_wlan_util.c     |  23 +-
 drivers/staging/rtl8723bs/os_dep/ioctl_cfg80211.c  |   8 +
 drivers/staging/rtl8723bs/os_dep/xmit_linux.c      |   6 +-
 drivers/staging/vme_user/vme_fake.c                |   8 +
 drivers/staging/vme_user/vme_tsi148.c              |   8 +
 drivers/staging/vme_user/vme_user.c                |  22 +
 drivers/tty/serial/8250/8250_mid.c                 |  13 +-
 drivers/tty/vt/keyboard.c                          |  12 +-
 drivers/usb/cdns3/cdnsp-mem.c                      |   2 +
 drivers/usb/class/cdc-acm.c                        |   3 +
 drivers/usb/common/ulpi.c                          |  23 +-
 drivers/usb/core/quirks.c                          |   6 +
 drivers/usb/dwc3/core.c                            |   4 +-
 drivers/usb/dwc3/dwc3-meson-g12a.c                 |  14 +-
 drivers/usb/dwc3/gadget.c                          |  43 +-
 drivers/usb/fotg210/fotg210-hcd.c                  |   6 +-
 drivers/usb/gadget/composite.c                     |   5 +-
 drivers/usb/gadget/function/f_fs.c                 |   9 +-
 drivers/usb/gadget/function/f_printer.c            |   3 +-
 drivers/usb/gadget/function/rndis.c                |  20 +-
 drivers/usb/gadget/udc/core.c                      |  29 +-
 drivers/usb/host/ehci-sched.c                      |  11 +-
 drivers/usb/host/sl811-hcd.c                       |   1 +
 drivers/usb/host/xhci-sideband.c                   |   2 +
 drivers/usb/host/xhci.c                            |  11 +-
 drivers/usb/misc/chaoskey.c                        |   1 -
 drivers/usb/misc/idmouse.c                         |  45 +-
 drivers/usb/misc/iowarrior.c                       |  61 +--
 drivers/usb/misc/ldusb.c                           |  38 +-
 drivers/usb/misc/legousbtower.c                    |  37 +-
 drivers/usb/misc/usbio.c                           |   8 +-
 drivers/usb/misc/uss720.c                          |   5 +-
 drivers/usb/mtu3/mtu3_gadget.c                     |   1 +
 drivers/usb/serial/digi_acceleport.c               |  43 +-
 drivers/usb/serial/keyspan_pda.c                   |   2 +-
 drivers/usb/serial/option.c                        |  16 +
 drivers/usb/storage/ene_ub6250.c                   |   3 +-
 drivers/usb/storage/usb.c                          |   2 +-
 drivers/usb/typec/anx7411.c                        |   4 +-
 drivers/usb/typec/class.c                          |   1 +
 drivers/usb/typec/mux.c                            |  13 +-
 drivers/usb/typec/mux/ps883x.c                     |   6 +-
 drivers/usb/typec/tcpm/tcpci_rt1711h.c             |  13 +-
 drivers/usb/typec/tcpm/tcpm.c                      |   9 +-
 drivers/usb/typec/ucsi/displayport.c               |   7 +-
 drivers/usb/typec/ucsi/ucsi.c                      |  20 +
 drivers/usb/typec/ucsi/ucsi.h                      |   1 +
 drivers/usb/typec/ucsi/ucsi_acpi.c                 |  10 +-
 drivers/usb/typec/ucsi/ucsi_ccg.c                  |   2 +-
 drivers/usb/usbip/vudc.h                           |   1 -
 drivers/usb/usbip/vudc_dev.c                       |   4 +-
 drivers/vfio/debugfs.c                             |   1 +
 drivers/vfio/pci/mlx5/cmd.h                        |  15 +-
 drivers/vfio/pci/vfio_pci_core.c                   |  37 +-
 drivers/vfio/vfio_main.c                           |  11 +-
 drivers/virtio/virtio_mmio.c                       |  26 +-
 drivers/virtio/virtio_pci_common.c                 |  10 +-
 drivers/watchdog/apple_wdt.c                       |   1 +
 fs/btrfs/btrfs_inode.h                             |   2 +
 fs/btrfs/direct-io.c                               |  60 ++-
 fs/btrfs/extent-tree.c                             |  12 +-
 fs/btrfs/file.c                                    |  25 +-
 fs/btrfs/inode.c                                   |  67 ++-
 fs/btrfs/ordered-data.c                            |  12 +
 fs/btrfs/ordered-data.h                            |   2 +
 fs/btrfs/reflink.c                                 |   4 +-
 fs/exfat/dir.c                                     |  63 ++-
 fs/exfat/exfat_fs.h                                |   5 +-
 fs/exfat/namei.c                                   |  89 +++-
 fs/fs-writeback.c                                  |  31 +-
 fs/fuse/cuse.c                                     |   4 +-
 fs/fuse/dev.c                                      |  66 ++-
 fs/fuse/dev_uring.c                                |  93 ++--
 fs/fuse/dev_uring_i.h                              |  10 +-
 fs/fuse/dir.c                                      |  36 +-
 fs/fuse/fuse_dev_i.h                               |   1 +
 fs/fuse/notify.c                                   | 434 ++++++++++++++++
 fs/fuse/readdir.c                                  |  85 +++-
 fs/hfs/bnode.c                                     |   4 +-
 fs/hfsplus/bnode.c                                 |   2 +
 fs/hfsplus/hfsplus_fs.h                            |   2 +-
 fs/isofs/rock.c                                    |  11 +
 fs/libfs.c                                         |   1 +
 fs/nfs/dir.c                                       |   2 +
 fs/nilfs2/segment.c                                |  22 +
 fs/ntfs/index.c                                    |   5 +-
 fs/ntfs3/fslog.c                                   |  20 +-
 fs/proc/array.c                                    |   6 +
 fs/proc/base.c                                     | 162 +++---
 fs/proc/fd.c                                       |  25 +-
 fs/proc/internal.h                                 |   2 +-
 fs/proc/namespaces.c                               |  12 +
 fs/resctrl/monitor.c                               |  37 +-
 fs/smb/client/cifs_swn.c                           | 316 ++++++++++--
 fs/smb/client/cifsacl.c                            |   2 +-
 fs/smb/client/file.c                               |   2 +-
 fs/smb/client/inode.c                              |   3 +-
 fs/smb/client/smb2misc.c                           |  32 +-
 fs/smb/client/smb2ops.c                            |  18 +-
 fs/smb/client/smb2pdu.c                            |  22 +-
 fs/smb/client/trace.h                              |   2 +
 fs/smb/server/auth.c                               |  20 +-
 fs/smb/server/smb2pdu.c                            | 117 +++--
 fs/smb/server/vfs.c                                |  20 +-
 fs/smb/server/vfs_cache.c                          |  28 +-
 fs/smb/server/vfs_cache.h                          |   3 +
 fs/udf/balloc.c                                    |   5 +-
 fs/udf/super.c                                     |  11 +-
 fs/userfaultfd.c                                   |  20 +
 fs/xfs/libxfs/xfs_ag.c                             |  10 +-
 fs/xfs/libxfs/xfs_ag.h                             |   2 +-
 fs/xfs/libxfs/xfs_bmap_btree.h                     |   2 +-
 fs/xfs/libxfs/xfs_dquot_buf.c                      |  14 +-
 fs/xfs/libxfs/xfs_exchmaps.c                       |   2 +-
 fs/xfs/xfs_dquot.c                                 |  16 +-
 fs/xfs/xfs_fsops.c                                 |   2 +-
 fs/xfs/xfs_iomap.c                                 |   2 +-
 fs/xfs/xfs_log_recover.c                           |   6 +-
 fs/xfs/xfs_qm.c                                    |   5 +-
 fs/xfs/xfs_rtalloc.c                               |   8 +-
 include/asm-generic/rqspinlock.h                   |  14 +-
 include/crypto/drbg.h                              |  18 +-
 include/crypto/internal/drbg.h                     |  18 -
 include/linux/bpf_lsm.h                            |   4 +
 include/linux/damon.h                              |   8 +-
 include/linux/filter.h                             |  15 +-
 include/linux/fs.h                                 |   5 +
 include/linux/glob.h                               |   1 +
 include/linux/hid-sensor-hub.h                     |  25 +
 include/linux/kvm_host.h                           |   3 +-
 include/linux/page_ext.h                           |  19 +-
 include/linux/slab.h                               |   6 +-
 include/linux/sunrpc/svc_rdma.h                    |   1 +
 include/linux/vfio_pci_core.h                      |  15 +-
 include/net/bluetooth/hci_core.h                   |   1 +
 include/net/bluetooth/l2cap.h                      |   1 +
 include/net/netfilter/nf_flow_table.h              |   2 +
 include/net/tcp_ao.h                               |   1 +
 include/sound/hda_codec.h                          |   1 +
 init/Kconfig                                       |   1 +
 io_uring/io-wq.c                                   |   2 +-
 io_uring/nop.c                                     |   8 +-
 io_uring/rw.c                                      |  12 +-
 kernel/audit.c                                     |  21 +-
 kernel/audit_fsnotify.c                            |   4 -
 kernel/bpf/bpf_inode_storage.c                     |   9 +
 kernel/bpf/btf.c                                   |   9 +-
 kernel/bpf/cgroup.c                                |   2 +-
 kernel/bpf/core.c                                  |  68 ++-
 kernel/bpf/devmap.c                                |   7 +
 kernel/bpf/dispatcher.c                            |   2 +-
 kernel/bpf/lpm_trie.c                              |   8 +-
 kernel/bpf/verifier.c                              |  15 +-
 kernel/events/core.c                               |  19 +-
 kernel/futex/requeue.c                             |   6 -
 kernel/liveupdate/luo_session.c                    |   4 +
 kernel/module/decompress.c                         |   2 +
 kernel/sched/features.h                            |   8 +
 kernel/time/jiffies.c                              |  11 +-
 kernel/time/posix-cpu-timers.c                     |   1 +
 kernel/time/timekeeping.c                          |   7 +-
 kernel/trace/trace_events_filter.c                 |   6 +-
 kernel/trace/trace_functions.c                     |   8 +-
 lib/debugobjects.c                                 |  17 +
 lib/glob.c                                         |  31 +-
 lib/test_hmm.c                                     |   4 +-
 mm/damon/ops-common.c                              |   1 +
 mm/filemap.c                                       |   2 +-
 mm/khugepaged.c                                    |  41 +-
 mm/madvise.c                                       |   3 +-
 mm/mincore.c                                       |   3 +-
 mm/mmap.c                                          |   2 +-
 mm/shrinker.c                                      |  13 +-
 mm/shrinker_debug.c                                |  14 +-
 mm/slub.c                                          |  18 +-
 mm/swap_cgroup.c                                   |   2 +
 mm/swapfile.c                                      |   1 +
 net/6lowpan/nhc.c                                  |   2 +-
 net/bluetooth/6lowpan.c                            |  18 +-
 net/bluetooth/af_bluetooth.c                       |  17 +-
 net/bluetooth/bnep/core.c                          |  27 +-
 net/bluetooth/hci_conn.c                           |  21 +-
 net/bluetooth/hci_sync.c                           | 137 ++++-
 net/bluetooth/iso.c                                |  13 +-
 net/bluetooth/l2cap_core.c                         |  80 +--
 net/bluetooth/l2cap_sock.c                         |   4 +-
 net/bluetooth/mgmt.c                               |   3 +
 net/bridge/netfilter/ebtables.c                    |  12 +-
 net/core/netpoll.c                                 |   9 +-
 net/ipv4/igmp.c                                    |   1 +
 net/ipv4/sysctl_net_ipv4.c                         |  10 +-
 net/ipv4/tcp_ao.c                                  |   5 +-
 net/ipv4/tcp_output.c                              |   4 +-
 net/ipv6/netfilter/nf_conntrack_reasm.c            |   2 +-
 net/key/af_key.c                                   |   1 +
 net/netfilter/ipset/ip_set_core.c                  |   8 +-
 net/netfilter/nf_conntrack_netlink.c               |   2 +-
 net/netfilter/nf_flow_table_core.c                 |  20 +-
 net/netfilter/nf_flow_table_offload.c              |  22 +-
 net/netfilter/nfnetlink_log.c                      |  26 +-
 net/netfilter/nfnetlink_queue.c                    |  16 +-
 net/netfilter/xt_u32.c                             |  16 +-
 net/sched/sch_dualpi2.c                            |  11 +-
 net/sunrpc/xprtrdma/svc_rdma_recvfrom.c            |   4 +-
 net/sunrpc/xprtrdma/svc_rdma_rw.c                  | 229 +--------
 net/sunrpc/xprtrdma/svc_rdma_sendto.c              |   6 +-
 net/sunrpc/xprtrdma/svc_rdma_transport.c           |  30 +-
 net/tipc/bcast.c                                   |  22 +-
 net/tipc/bcast.h                                   |   2 +-
 net/tipc/node.c                                    |  15 +-
 rust/kernel/block/mq/gen_disk.rs                   |  20 +-
 rust/kernel/cpufreq.rs                             |   2 +-
 rust/kernel/pci/io.rs                              |   6 +-
 rust/kernel/str.rs                                 |  23 +-
 scripts/rustdoc_test_builder.rs                    |  16 +-
 security/bpf/hooks.c                               |   3 +
 security/landlock/domain.c                         |   9 +-
 security/landlock/domain.h                         |   5 +-
 security/landlock/net.c                            |   1 +
 sound/aoa/fabrics/layout.c                         |   6 +
 sound/core/compress_offload.c                      |  13 +-
 sound/core/seq/seq_memory.c                        |   2 +-
 sound/firewire/isight.c                            |   3 +-
 sound/hda/codecs/hdmi/hdmi.c                       |   9 +-
 sound/hda/codecs/realtek/alc269.c                  |   1 +
 sound/hda/codecs/side-codecs/cs35l41_hda.c         |  77 ++-
 sound/hda/codecs/side-codecs/cs35l41_hda.h         |   5 +
 sound/hda/common/jack.c                            |   6 +
 sound/isa/gus/gus_pcm.c                            |   2 +
 sound/pci/cmipci.c                                 |   6 +
 sound/pci/es1938.c                                 |   2 +
 sound/pci/ice1712/aureon.c                         |   2 +
 sound/pci/ice1712/ice1712.c                        |   8 +
 sound/pci/ice1712/ice1724.c                        |   6 +
 sound/pci/ymfpci/ymfpci_main.c                     |   6 +
 sound/usb/caiaq/input.c                            |   2 +-
 sound/usb/endpoint.c                               |  10 +-
 sound/usb/mixer_quirks.c                           | 102 ++--
 sound/usb/mixer_scarlett.c                         |   4 +-
 sound/usb/mixer_us16x08.c                          | 127 +++--
 sound/usb/quirks.c                                 |   3 +
 sound/usb/usbaudio.h                               |   8 +
 sound/usb/usx2y/us144mkii.c                        |  17 +-
 sound/usb/usx2y/us144mkii_capture.c                |   2 +-
 sound/virtio/virtio_kctl.c                         |  50 ++
 sound/virtio/virtio_pcm.c                          |   3 +-
 sound/virtio/virtio_pcm_ops.c                      |   3 +-
 tools/mm/slabinfo.c                                |   6 +-
 tools/perf/trace/beauty/fcntl.c                    |  16 +
 tools/testing/selftests/landlock/audit.h           | 140 +++--
 tools/testing/selftests/landlock/audit_test.c      |   6 +-
 tools/testing/selftests/landlock/net_test.c        |  62 +++
 tools/testing/selftests/landlock/ptrace_test.c     |   1 +
 .../selftests/landlock/scoped_abstract_unix_test.c |   1 +
 tools/testing/selftests/liveupdate/liveupdate.c    |  42 ++
 tools/testing/selftests/mm/droppable.c             |  48 +-
 tools/testing/selftests/mm/ksft_process_madv.sh    |   2 +-
 tools/testing/selftests/mm/pagemap_ioctl.c         |  12 +-
 tools/usb/usbip/libsrc/usbip_common.c              |   2 +
 tools/usb/usbip/libsrc/usbip_device_driver.c       |   4 +
 tools/usb/usbip/libsrc/vhci_driver.c               |   1 +
 virt/kvm/guest_memfd.c                             |  14 +-
 virt/kvm/kvm_mm.h                                  |   7 +-
 501 files changed, 5826 insertions(+), 3378 deletions(-)
author maintainer
#1 lore raw

PATCH 1/518 rust: str: use the "kernel vertical" imports style

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

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

From: Miguel Ojeda <[email protected]>

[ Upstream commit 724a93a9f6033800b02a3530dbcb464638448e7f ]

Convert the imports to use the "kernel vertical" imports style [1].

No functional changes intended.

Stable-dep-of: 3fff4271809b ("rust: str: clean unused import for Rust >= 1.98")

---
 rust/kernel/str.rs | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)
rust/kernel/str.rs +19 -5
index 8311d91549e15e..a7fccd4c4f3b18 100644
@@ -3,14 +3,28 @@
 //! String representations.
 
 use crate::{
-    alloc::{flags::*, AllocError, KVec},
-    error::{to_result, Result},
-    fmt::{self, Write},
-    prelude::*,
+    alloc::{
+        flags::*,
+        AllocError,
+        KVec, //
+    },
+    error::{
+        to_result,
+        Result, //
+    },
+    fmt::{
+        self,
+        Write, //
+    },
+    prelude::*, //
 };
 use core::{
     marker::PhantomData,
-    ops::{Deref, DerefMut, Index},
+    ops::{
+        Deref,
+        DerefMut,
+        Index, //
+    }, //
 };
 
 pub use crate::prelude::CStr;
Signature · 1 line
2.53.0
author maintainer
#2 lore raw

PATCH 2/518 rust: str: clean unused import for Rust >= 1.98

In reply to Greg Kroah-Hartman

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

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

From: Miguel Ojeda <[email protected]>

[ Upstream commit 3fff4271809b57182c4011811e96556bdd4cb2f9 ]

Starting with Rust 1.98.0 (expected 2026-08-20), the compiler has changed how the resolution algorithm works [1] in upstream commit c4d84db5f184 ("Resolver: Batched import resolution."), and it now spots:

    error: unused import: `flags::*`
     --> rust/kernel/str.rs:7:9
      |
    7 |         flags::*,
      |         ^^^^^^^^
      |
      = note: `-D unused-imports` implied by `-D warnings`
      = help: to override `-D warnings` add `#[allow(unused_imports)]`

It happens to not be needed because the prelude::* already provides the flags.

Thus clean it up.

---
 rust/kernel/str.rs | 1 -
 1 file changed, 1 deletion(-)
rust/kernel/str.rs +0 -1
index a7fccd4c4f3b18..4517c1bc547afb 100644
@@ -4,7 +4,6 @@
 
 use crate::{
     alloc::{
-        flags::*,
         AllocError,
         KVec, //
     },
Signature · 1 line
2.53.0
author maintainer
#3 lore raw

PATCH 3/518 userfaultfd: gate must_wait writability check on pte_present()

In reply to Greg Kroah-Hartman

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

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

From: Kiryl Shutsemau <[email protected]>

[ Upstream commit 8e80af52db652fbc41320eee45a4f73bc029faf2 ]

userfaultfd_must_wait() and userfaultfd_huge_must_wait() read the PTE without taking the page table lock and then apply pte_write() / huge_pte_write() to it. Those accessors decode bits from the present encoding only; on a swap or migration entry they read the offset bits that happen to share the same position and return an undefined result.

The intent of the check is "is this fault still WP-blocked?". A non-marker swap entry means the page is in transit -- the userfault context the original fault delivered against is no longer the same, and the swap-in or migration completion path will re-deliver a fresh fault if userspace still needs to handle it. Worst case under the current code the garbage write bit says "wait", and the thread stays asleep until a UFFDIO_WAKE that may never arrive.

Gate the writability check on pte_present() so the lockless re-check only inspects present-PTE bits when the entry is actually present. The non-present, non-marker case returns "don't wait" and lets the fault path retry.

Fixes 369cd2121be4 ("userfaultfd: hugetlbfs: userfaultfd_huge_must_wait for hugepmd ranges")
Fixes 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl")
Cc David Hildenbrand <[email protected]>
Cc Michal Hocko <[email protected]>
Cc Mike Rapoport <[email protected]>
Cc Peter Xu <[email protected]>
Cc Suren Baghdasaryan <[email protected]>
Cc Vlastimil Babka <[email protected]>
Cc Balbir Singh <[email protected]>

[ kas: apply to fs/userfaultfd.c; these checks moved to mm/userfaultfd.c
only after 7.1, the change is otherwise identical to upstream ]

---
 fs/userfaultfd.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
fs/userfaultfd.c +20 -0
index 390e4b7d9cb9fa..dba1172436b745 100644
@@ -253,6 +253,15 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
 	/* UFFD PTE markers require userspace to resolve the fault. */
 	if (pte_is_uffd_marker(pte))
 		return true;
+	/*
+	 * Concurrent migration may have replaced the present PTE with a
+	 * non-marker swap entry between fault delivery and this lockless
+	 * re-check. huge_pte_write() on a swap entry decodes random offset
+	 * bits, so gate it on pte_present(). The migration completion path
+	 * will re-deliver the fault if it still needs userspace.
+	 */
+	if (!pte_present(pte))
+		return false;
 	/*
 	 * If VMA has UFFD WP faults enabled and WP fault, wait for userspace to
 	 * resolve the fault.
@@ -339,6 +348,17 @@ static inline bool userfaultfd_must_wait(struct userfaultfd_ctx *ctx,
 	/* UFFD PTE markers require userspace to resolve the fault. */
 	if (pte_is_uffd_marker(ptent))
 		goto out;
+	/*
+	 * Concurrent swap-out / migration may have replaced the present PTE
+	 * with a non-marker swap entry between fault delivery and this
+	 * lockless re-check. pte_write() on a swap entry decodes random
+	 * offset bits, so gate it on pte_present(). The page-in path will
+	 * re-deliver the fault if it still needs userspace.
+	 */
+	if (!pte_present(ptent)) {
+		ret = false;
+		goto out;
+	}
 	/*
 	 * If VMA has UFFD WP faults enabled and WP fault, wait for userspace to
 	 * resolve the fault.
Signature · 1 line
2.53.0
author maintainer
#4 lore raw

PATCH 4/518 net/sched: dualpi2: fix GSO backlog accounting

In reply to Greg Kroah-Hartman

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

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

From: Xingquan Liu <[email protected]>

commit 05ed733b65ab977dd931e7f7ac0f62fdb81205c2 upstream.

When DualPI2 splits a GSO skb into N segments, it propagates N additional packets to its parent before returning NET_XMIT_SUCCESS. The parent then accounts for the original skb once more, leaving its qlen one larger than the number of packets actually queued.

With QFQ as the parent, after all real packets are dequeued, QFQ still has a non-zero qlen while its in-service aggregate has no active classes. qfq_choose_next_agg() returns NULL and qfq_dequeue() passes the result to qfq_peek_skb(), causing a NULL pointer dereference.

Follow the same pattern used by tbf_segment() and taprio: count only successfully queued segments, propagate the difference between the original skb and those segments, and return NET_XMIT_SUCCESS whenever at least one segment was queued.

---
 net/sched/sch_dualpi2.c |   11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)
net/sched/sch_dualpi2.c +5 -6
@@ -461,7 +461,7 @@ static int dualpi2_qdisc_enqueue(struct
 		if (IS_ERR_OR_NULL(nskb))
 			return qdisc_drop(skb, sch, to_free);
 
-		cnt = 1;
+		cnt = 0;
 		byte_len = 0;
 		orig_len = qdisc_pkt_len(skb);
 		skb_list_walk_safe(nskb, nskb, next) {
@@ -488,16 +488,15 @@ static int dualpi2_qdisc_enqueue(struct
 				byte_len += nskb->len;
 			}
 		}
-		if (cnt > 1) {
+		if (cnt > 0) {
 			/* The caller will add the original skb stats to its
 			 * backlog, compensate this if any nskb is enqueued.
 			 */
-			--cnt;
-			byte_len -= orig_len;
+			qdisc_tree_reduce_backlog(sch, 1 - cnt,
+						  orig_len - byte_len);
 		}
-		qdisc_tree_reduce_backlog(sch, -cnt, -byte_len);
 		consume_skb(skb);
-		return err;
+		return cnt > 0 ? NET_XMIT_SUCCESS : err;
 	}
 	return dualpi2_enqueue_skb(skb, sch, to_free);
 }
author maintainer
#5 lore raw

PATCH 5/518 mm/khugepaged: write all dirty file folios when collapsing

In reply to Greg Kroah-Hartman

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

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

From: Pedro Falcato <[email protected]>

[There is no upstream commit, as this code was removed by upstream
commit 044925f9b565 ("mm: fs: remove filemap_nr_thps*() functions and their users")]

As-is, khugepaged and writable-file opening exclude each other. A file cannot be open writeable and have THPs (because the filesystem is not aware of them). khugepaged will never collapse file pages for files that are opened writeable. On an open(O_RDWR/O_WRONLY), the page cache for that particular file is dropped. This is fine because nothing could've been dirtied.

However, there is an edge-case: collapse_file() might not be able to coexist with concurrent writers, but it can coexist with dirty folios (from previous writers). Therefore, the following can happen:

open(file, O_RDWR)
write(file)
close(file)
madvise(file_mapping, MADV_COLLAPSE, some non-dirty range) open(file, O_RDWR)
nr_thps > 0
truncate_inode_pages()

    /* THPs are cleared out, but so are the dirty folios */

When this edge-case happens, there is data loss, as the dirty folios are fully discarded.

Fix it by fully writing back the page cache (and waiting) when collapsing file THPs. Doing so provides the guarantee that no dirty folio will be observed while there are active THPs. To fully ensure this is safe, the invalidate_lock needs to be held while doing the writeout, so that do_dentry_open()'s page cache truncation excludes this write-and-wait.

As a side effect, move the nr_thps counter bumping outside the i_pages lock. This is correct since the counter itself is an atomic_t and the producer <-> consumer correctness is provided by a full memory barrier:
smp_mb() in collapse_file()/memory barrier implied by full ordering in get_write_access() -> atomic_inc_unless_negative().

---
 mm/khugepaged.c | 39 +++++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 14 deletions(-)
mm/khugepaged.c +25 -14
index b8452dbdb043f8..d6e04041f5dc11 100644
@@ -2094,32 +2094,43 @@ static enum scan_result collapse_file(struct mm_struct *mm, unsigned long addr,
 		goto xa_unlocked;
 	}
 
-	if (!is_shmem) {
+xa_locked:
+	xas_unlock_irq(&xas);
+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.
+	 */
+	try_to_unmap_flush();
+
+	if (result == SCAN_SUCCEED && !is_shmem && !mapping_large_folio_support(mapping)) {
+		/*
+		 * invalidate_lock as shared excludes against concurrent opens
+		 * in do_dentry_open() truncating the page cache. This is
+		 * particularly important if there are dirty folios in transit.
+		 */
+		filemap_invalidate_lock_shared(mapping);
 		filemap_nr_thps_inc(mapping);
 		/*
 		 * Paired with the fence in do_dentry_open() -> get_write_access()
 		 * to ensure i_writecount is up to date and the update to nr_thps
 		 * is visible. Ensures the page cache will be truncated if the
-		 * file is opened writable.
+		 * file is opened writable. If collapse looks to be successful,
+		 * flush any dirty pages out the page cache. With the nr_thps
+		 * incremented, there won't be any new writers (nor new dirties).
 		 */
 		smp_mb();
-		if (inode_is_open_for_write(mapping->host)) {
+		if (inode_is_open_for_write(mapping->host) || filemap_write_and_wait(mapping)) {
 			result = SCAN_FAIL;
 			filemap_nr_thps_dec(mapping);
+			filemap_invalidate_unlock_shared(mapping);
+			goto rollback;
 		}
+		filemap_invalidate_unlock_shared(mapping);
 	}
 
-xa_locked:
-	xas_unlock_irq(&xas);
-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.
-	 */
-	try_to_unmap_flush();
-
 	if (result == SCAN_SUCCEED && nr_none &&
 	    !shmem_charge(mapping->host, nr_none))
 		result = SCAN_FAIL;
Signature · 1 line
2.53.0
author maintainer
#6 lore raw

PATCH 6/518 slab: recognize @GFP parameter as optional in kernel-doc

In reply to Greg Kroah-Hartman

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

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

From: Randy Dunlap <[email protected]>

commit 7b5f5865fb11e60edd03c5e063e2d228b7062317 upstream.

Since the @GFP parameter in kmalloc_obj() etc. is now optional, change the kernel-doc to indicate that it is optional. This avoids kernel-doc warnings:

WARNING: include/linux/slab.h:1101 Excess function parameter 'GFP' description in 'kmalloc_obj'
WARNING: include/linux/slab.h:1113 Excess function parameter 'GFP' description in 'kmalloc_objs'
WARNING: include/linux/slab.h:1128 Excess function parameter 'GFP' description in 'kmalloc_flex'
Fixes e19e1b480ac7 ("add default_gfp() helper macro and use it in the new *alloc_obj() helpers")
---
 include/linux/slab.h |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
include/linux/slab.h +3 -3
@@ -1000,7 +1000,7 @@ void *kmalloc_nolock_noprof(size_t size,
 /**
  * kmalloc_obj - Allocate a single instance of the given type
  * @VAR_OR_TYPE: Variable or type to allocate.
- * @GFP: GFP flags for the allocation.
+ * @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
  *
  * Returns: newly allocated pointer to a @VAR_OR_TYPE on success, or NULL
  * on failure.
@@ -1012,7 +1012,7 @@ void *kmalloc_nolock_noprof(size_t size,
  * kmalloc_objs - Allocate an array of the given type
  * @VAR_OR_TYPE: Variable or type to allocate an array of.
  * @COUNT: How many elements in the array.
- * @GFP: GFP flags for the allocation.
+ * @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
  *
  * Returns: newly allocated pointer to array of @VAR_OR_TYPE on success,
  * or NULL on failure.
@@ -1025,7 +1025,7 @@ void *kmalloc_nolock_noprof(size_t size,
  * @VAR_OR_TYPE: Variable or type to allocate (with its flex array).
  * @FAM: The name of the flexible array member of the structure.
  * @COUNT: How many flexible array member elements are desired.
- * @GFP: GFP flags for the allocation.
+ * @...: optional GFP flags for the allocation (GFP_KERNEL when not specified).
  *
  * Returns: newly allocated pointer to @VAR_OR_TYPE on success, NULL on
  * failure. If @FAM has been annotated with __counted_by(), the allocation
author maintainer
#7 lore raw

PATCH 7/518 perf trace beauty fcntl: Fix build with older kernel headers

In reply to Greg Kroah-Hartman

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

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

From: Florian Fainelli <[email protected]>

commit 7ee7f48413c42b90230de4a8e40898b757bc8e82 upstream.

Toolchains with older kernel headers that do not include upstream commit c75b1d9421f80f41 ("fs: add fcntl() interface for setting/getting write life time hints") will now fail to build perf due to missing definitions for F_GET_RW_HINT/F_SET_RW_HINT/F_GET_FILE_RW_HINT/F_SET_FILE_RW_HINT.

Provide a fallback definition for these when they are not already defined.

Fixes 9c47f66748381ecb ("perf trace beauty fcntl: Basic 'arg' beautifier")
Cc Adrian Hunter <[email protected]>
Cc Alexander Shishkin <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc James Clark <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mark Rutland <[email protected]>
Cc Markus Mayer <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Peter Zijlstra <[email protected]>
---
 tools/perf/trace/beauty/fcntl.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
tools/perf/trace/beauty/fcntl.c +16 -0
@@ -9,6 +9,22 @@
 #include <linux/kernel.h>
 #include <linux/fcntl.h>
 
+#ifndef F_GET_RW_HINT
+#define F_GET_RW_HINT		(F_LINUX_SPECIFIC_BASE + 11)
+#endif
+
+#ifndef F_SET_RW_HINT
+#define F_SET_RW_HINT		(F_LINUX_SPECIFIC_BASE + 12)
+#endif
+
+#ifndef F_GET_FILE_RW_HINT
+#define F_GET_FILE_RW_HINT	(F_LINUX_SPECIFIC_BASE + 13)
+#endif
+
+#ifndef F_SET_FILE_RW_HINT
+#define F_SET_FILE_RW_HINT	(F_LINUX_SPECIFIC_BASE + 14)
+#endif
+
 static size_t fcntl__scnprintf_getfd(unsigned long val, char *bf, size_t size, bool show_prefix)
 {
 	return val ? scnprintf(bf, size, "%s", "0") :
author maintainer
#8 lore raw

PATCH 8/518 KVM: x86: Move update_cr8_intercept() to lapic.c

In reply to Greg Kroah-Hartman

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

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

From: Sean Christopherson <[email protected]>

[ Upstream Commit c7722e5e1daeeabbd9f969554d52bb7158120b27 ]

Move update_cr8_intercept() to lapic.c so that it's globally visible in anticipation of extracting most of the register-specific code out of x86.c and into a new compilation unit. Opportunistically prefix the helper kvm_lapic_ to make its role/scope more obvious.

No functional change intended.

---
 arch/x86/kvm/lapic.c |   26 ++++++++++++++++++++++++++
 arch/x86/kvm/lapic.h |    1 +
 arch/x86/kvm/x86.c   |   34 +++-------------------------------
 3 files changed, 30 insertions(+), 31 deletions(-)
arch/x86/kvm/lapic.c +26 -0
@@ -2744,6 +2744,32 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *v
 	return (tpr & 0xf0) >> 4;
 }
 
+void kvm_lapic_update_cr8_intercept(struct kvm_vcpu *vcpu)
+{
+	int max_irr, tpr;
+
+	if (!kvm_x86_ops.update_cr8_intercept)
+		return;
+
+	if (!lapic_in_kernel(vcpu))
+		return;
+
+	if (vcpu->arch.apic->apicv_active)
+		return;
+
+	if (!vcpu->arch.apic->vapic_addr)
+		max_irr = kvm_lapic_find_highest_irr(vcpu);
+	else
+		max_irr = -1;
+
+	if (max_irr != -1)
+		max_irr >>= 4;
+
+	tpr = kvm_lapic_get_cr8(vcpu);
+
+	kvm_x86_call(update_cr8_intercept)(vcpu, tpr, max_irr);
+}
+
 static void __kvm_apic_set_base(struct kvm_vcpu *vcpu, u64 value)
 {
 	u64 old_value = vcpu->arch.apic_base;
arch/x86/kvm/lapic.h +1 -0
@@ -100,6 +100,7 @@ int kvm_apic_accept_events(struct kvm_vc
 void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event);
 u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8);
+void kvm_lapic_update_cr8_intercept(struct kvm_vcpu *vcpu);
 void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu);
 void kvm_apic_set_version(struct kvm_vcpu *vcpu);
 void kvm_apic_after_set_mcg_cap(struct kvm_vcpu *vcpu);
arch/x86/kvm/x86.c +3 -31
@@ -128,7 +128,6 @@ static u64 __read_mostly efer_reserved_b
 				    KVM_X2APIC_ENABLE_SUPPRESS_EOI_BROADCAST	| \
 				    KVM_X2APIC_DISABLE_SUPPRESS_EOI_BROADCAST)
 
-static void update_cr8_intercept(struct kvm_vcpu *vcpu);
 static void process_nmi(struct kvm_vcpu *vcpu);
 static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
 static void store_regs(struct kvm_vcpu *vcpu);
@@ -5340,7 +5339,7 @@ static int kvm_vcpu_ioctl_set_lapic(stru
 	r = kvm_apic_set_state(vcpu, s);
 	if (r)
 		return r;
-	update_cr8_intercept(vcpu);
+	kvm_lapic_update_cr8_intercept(vcpu);
 
 	return 0;
 }
@@ -10595,33 +10594,6 @@ static void post_kvm_run_save(struct kvm
 		kvm_run->flags |= KVM_RUN_X86_GUEST_MODE;
 }
 
-static void update_cr8_intercept(struct kvm_vcpu *vcpu)
-{
-	int max_irr, tpr;
-
-	if (!kvm_x86_ops.update_cr8_intercept)
-		return;
-
-	if (!lapic_in_kernel(vcpu))
-		return;
-
-	if (vcpu->arch.apic->apicv_active)
-		return;
-
-	if (!vcpu->arch.apic->vapic_addr)
-		max_irr = kvm_lapic_find_highest_irr(vcpu);
-	else
-		max_irr = -1;
-
-	if (max_irr != -1)
-		max_irr >>= 4;
-
-	tpr = kvm_lapic_get_cr8(vcpu);
-
-	kvm_x86_call(update_cr8_intercept)(vcpu, tpr, max_irr);
-}
-
-
 int kvm_check_nested_events(struct kvm_vcpu *vcpu)
 {
 	if (kvm_test_request(KVM_REQ_TRIPLE_FAULT, vcpu)) {
@@ -11362,7 +11334,7 @@ static int vcpu_enter_guest(struct kvm_v
 			kvm_x86_call(enable_irq_window)(vcpu);
 
 		if (kvm_lapic_enabled(vcpu)) {
-			update_cr8_intercept(vcpu);
+			kvm_lapic_update_cr8_intercept(vcpu);
 			kvm_lapic_sync_to_vapic(vcpu);
 		}
 	}
@@ -12511,7 +12483,7 @@ static int __set_sregs_common(struct kvm
 	kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
 	kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
 
-	update_cr8_intercept(vcpu);
+	kvm_lapic_update_cr8_intercept(vcpu);
 
 	/* Older userspace won't unhalt the vcpu on reset. */
 	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
author maintainer
#9 lore raw

PATCH 9/518 KVM: VMX: Grab vmcs12 on CR8 interception update iff vCPU is in guest mode

In reply to Greg Kroah-Hartman

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

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

From: Sean Christopherson <[email protected]>

[ Upstream commit 7ef78d71ca713d8c00f7c34ddcf276c808143f77 ]

When updating CR8 intercepts, get vmcs12 if and only if the vCPU is in guest mode so that a future change can have update CR8 intercepts during vCPU creation, without running afoul of get_vmcs12()'s lockdep assertion.

  ------------[ cut here ]------------
  debug_locks && !(lock_is_held(&(&vcpu->mutex)->dep_map) || !refcount_read(&vcpu->kvm->users_count))
  WARNING: arch/x86/kvm/vmx/nested.h:61 at get_vmcs12 arch/x86/kvm/vmx/nested.h:60 [inline], CPU#0: syz.2.19/5879
  WARNING: arch/x86/kvm/vmx/nested.h:61 at vmx_update_cr8_intercept+0x3de/0x4e0 arch/x86/kvm/vmx/vmx.c:6879, CPU#0: syz.2.19/5879
  Modules linked in:
  CPU: 0 UID: 0 PID: 5879 Comm: syz.2.19 Not tainted syzkaller #0 PREEMPT(full)
  Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
  RIP: 0010:get_vmcs12 arch/x86/kvm/vmx/nested.h:60 [inline]
  RIP: 0010:vmx_update_cr8_intercept+0x3de/0x4e0 arch/x86/kvm/vmx/vmx.c:6879
  Call Trace:
   <TASK>
   apic_update_ppr arch/x86/kvm/lapic.c:984 [inline]
   kvm_lapic_reset+0x1c24/0x2980 arch/x86/kvm/lapic.c:3023
   kvm_vcpu_reset+0x44c/0x1bf0 arch/x86/kvm/x86.c:12986
   kvm_arch_vcpu_create+0x746/0x8b0 arch/x86/kvm/x86.c:12847
   kvm_vm_ioctl_create_vcpu+0x428/0x930 virt/kvm/kvm_main.c:4201
   kvm_vm_ioctl+0x893/0xd50 virt/kvm/kvm_main.c:5159
   vfs_ioctl fs/ioctl.c:51 [inline]
   __do_sys_ioctl fs/ioctl.c:597 [inline]
   __se_sys_ioctl+0xfc/0x170 fs/ioctl.c:583
   do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
   do_syscall_64+0x174/0x580 arch/x86/entry/syscall_64.c:94
   entry_SYSCALL_64_after_hwframe+0x77/0x7f
   </TASK>

No functional change intended.

Message-ID: <[email protected]>

---
 arch/x86/kvm/vmx/vmx.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
arch/x86/kvm/vmx/vmx.c +1 -2
@@ -6855,11 +6855,10 @@ int vmx_handle_exit(struct kvm_vcpu *vcp
 
 void vmx_update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr)
 {
-	struct vmcs12 *vmcs12 = get_vmcs12(vcpu);
 	int tpr_threshold;
 
 	if (is_guest_mode(vcpu) &&
-		nested_cpu_has(vmcs12, CPU_BASED_TPR_SHADOW))
+	    nested_cpu_has(get_vmcs12(vcpu), CPU_BASED_TPR_SHADOW))
 		return;
 
 	guard(vmx_vmcs01)(vcpu);
author maintainer
#10 lore raw

PATCH 10/518 KVM: x86: Unconditionally recompute CR8 intercept on PPR update

In reply to Greg Kroah-Hartman

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

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

From: "Carlos L�pez" <[email protected]>

[ Upstream commit bb365a506b1e6fb050c0fceaad354fe395385ef0 ]

The TPR_THRESHOLD field in the VMCS is used by VMX to induce VM exits when the guest's virtual TPR falls under the specified threshold, allowing KVM to inject previously masked interrupts.

KVM handles these VM exits in handle_tpr_below_threshold(). Commit eb90f3417a0c ("KVM: vmx: speed up TPR below threshold vmexits") optimized this function by calling apic_update_ppr() instead of raising KVM_REQ_EVENT. apic_update_ppr() then raises KVM_REQ_EVENT if there is a pending, deliverable interrupt.

However, if there are no new interrupts pending, apic_update_ppr() does not issue the request. Thus, kvm_lapic_update_cr8_intercept() and vmx_update_cr8_intercept() are not called before VM entry, which results in a high, stale TPR_THRESHOLD. This is problematic due to the following sentence in 28.2.1.1 "VM-Execution Control Fields" in the SDM:

The following check is performed if the “use TPR shadow” VM-execution control is 1 and the “virtualize APIC accesses” and “virtual-interrupt delivery” VM-execution controls are both 0: the value of bits 3:0 of the TPR threshold VM-execution control field should not be greater than the value of bits 7:4 of VTPR.

This error condition is typically not observed when KVM runs on a bare metal system because modern processors support APICv, which enables virtual-interrupt delivery, and which KVM uses when possible. This causes the processor to no longer generate TPR-below-threshold exits and to no longer check TPR_THRESHOLD on entry. However, when running on older platforms, or under nested virtualization on a hypervisor that does not support virtual-interrupt delivery and enforces this check (like Hyper-V) this can cause a VM entry failure with hardware error 0x7, as seen in [1].

Call kvm_lapic_update_cr8_intercept() if apic_update_ppr() does not find a deliverable interrupt (and thus does not raise KVM_REQ_EVENT). Remove calls to kvm_lapic_update_cr8_intercept() on paths that end up in apic_update_ppr(), as they now become redundant. This ensures that any path that updates the guest's PPR also figures out if KVM needs to wait for a TPR change (using TPR_THRESHOLD on VMX or CR8 intercepts on SVM).

Message-ID: <[email protected]>

---
 arch/x86/kvm/lapic.c |    2 ++
 arch/x86/kvm/x86.c   |    5 +----
 2 files changed, 3 insertions(+), 4 deletions(-)
arch/x86/kvm/lapic.c +2 -0
@@ -980,6 +980,8 @@ static void apic_update_ppr(struct kvm_l
 	if (__apic_update_ppr(apic, &ppr) &&
 	    apic_has_interrupt_for_ppr(apic, ppr) != -1)
 		kvm_make_request(KVM_REQ_EVENT, apic->vcpu);
+	else
+		kvm_lapic_update_cr8_intercept(apic->vcpu);
 }
 
 void kvm_apic_update_ppr(struct kvm_vcpu *vcpu)
arch/x86/kvm/x86.c +1 -4
@@ -5339,7 +5339,6 @@ static int kvm_vcpu_ioctl_set_lapic(stru
 	r = kvm_apic_set_state(vcpu, s);
 	if (r)
 		return r;
-	kvm_lapic_update_cr8_intercept(vcpu);
 
 	return 0;
 }
@@ -12453,8 +12452,6 @@ static int __set_sregs_common(struct kvm
 	kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
 	kvm_x86_call(post_set_cr3)(vcpu, sregs->cr3);
 
-	kvm_set_cr8(vcpu, sregs->cr8);
-
 	*mmu_reset_needed |= vcpu->arch.efer != sregs->efer;
 	kvm_x86_call(set_efer)(vcpu, sregs->efer);
 
@@ -12483,7 +12480,7 @@ static int __set_sregs_common(struct kvm
 	kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR);
 	kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR);
 
-	kvm_lapic_update_cr8_intercept(vcpu);
+	kvm_set_cr8(vcpu, sregs->cr8);
 
 	/* Older userspace won't unhalt the vcpu on reset. */
 	if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 &&
author maintainer
#11 lore raw

PATCH 11/518 ACPI: CPPC: Suppress UBSAN warning caused by field misuse

In reply to Greg Kroah-Hartman

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

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

From: Jeremy Linton <[email protected]>

commit 1b1acf2dada0cc3931bb2cb9ff8832edfbee46a1 upstream.

The definition of reg->access_width changes depending on the reg->space_id type. Type ACPI_ADR_SPACE_PLATFORM_COMM uses access_width to indicate the PCC region, which can result in a UBSAN if the value is greater than 4.

For example:

 UBSAN: shift-out-of-bounds in drivers/acpi/cppc_acpi.c:1090:9
 shift exponent 32 is too large for 32-bit type 'int'
 CPU: 61 UID: 0 PID: 1220 Comm: (udev-worker) Not tainted 7.0.10-201.fc44.aarch64 #1 PREEMPT(lazy)
 Hardware name: To be filled by O.E.M.
 Call trace:
  ...(trimming)
  ubsan_epilogue+0x10/0x48
  __ubsan_handle_shift_out_of_bounds+0xdc/0x1e0
  cpc_write+0x4d0/0x670
  cppc_set_perf+0x18c/0x490
  cppc_cpufreq_cpu_init+0x1c8/0x380 [cppc_cpufreq]
  ... (trimming)

Lets fix this by validating the region type, as well as whether access_width has a value. Then since we are returning bit_width directly for ACPI_ADR_SPACE_PLATFORM_COMM, drop the code correcting the size.

Fixes 2f4a4d63a193 ("ACPI: CPPC: Use access_width over bit_width for system memory accesses")
Cc All applicable <[email protected]>
---
 drivers/acpi/cppc_acpi.c |   11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/acpi/cppc_acpi.c +7 -4
@@ -185,8 +185,13 @@ show_cppc_data(cppc_get_perf_caps, cppc_
 
 show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
 
-/* Check for valid access_width, otherwise, fallback to using bit_width */
-#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
+/*
+ * PCC reuses the access_width field as the subspace id, so only decode access
+ * size for non-PCC registers. Otherwise, use the bit_width.
+ */
+#define GET_BIT_WIDTH(reg) (((reg)->access_width &&				\
+			     (reg)->space_id != ACPI_ADR_SPACE_PLATFORM_COMM) ? \
+			    (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
 
 /* Shift and apply the mask for CPC reads/writes */
 #define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) &				\
@@ -1045,7 +1050,6 @@ static int cpc_read(int cpu, struct cpc_
 		 * by the bit width field; the access size is used to indicate
 		 * the PCC subspace id.
 		 */
-		size = reg->bit_width;
 		vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
 	}
 	else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
@@ -1118,7 +1122,6 @@ static int cpc_write(int cpu, struct cpc
 		 * by the bit width field; the access size is used to indicate
 		 * the PCC subspace id.
 		 */
-		size = reg->bit_width;
 		vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
 	}
 	else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
author maintainer
#12 lore raw

PATCH 12/518 ACPI: NFIT: core: Fix possible NULL pointer dereference

In reply to Greg Kroah-Hartman

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

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

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

commit 027e128abb82788189d6d45b68e3e8e7329b67be upstream.

After commit 9b311b7313d6 ("ACPI: NFIT: Install Notify() handler before getting NFIT table"), acpi_nfit_probe() installs an ACPI notify handler for the NFIT device before checking the presence of the NFIT table. If that table is not there, 0 is returned without allocating the acpi_desc object and setting the driver data pointer of the NFIT device. If the platform firmware triggers an NFIT_NOTIFY_UC_MEMORY_ERROR notification on the NFIT device at that point, acpi_nfit_uc_error_notify() will dereference a NULL pointer.

Prevent that from occurring by adding an acpi_desc check against NULL to acpi_nfit_uc_error_notify().

Fixes 9b311b7313d6 ("ACPI: NFIT: Install Notify() handler before getting NFIT table")
Cc All applicable <[email protected]>
---
 drivers/acpi/nfit/core.c |    3 +++
 1 file changed, 3 insertions(+)
drivers/acpi/nfit/core.c +3 -0
@@ -3460,6 +3460,9 @@ static void acpi_nfit_uc_error_notify(st
 {
 	struct acpi_nfit_desc *acpi_desc = dev_get_drvdata(dev);
 
+	if (!acpi_desc)
+		return;
+
 	if (acpi_desc->scrub_mode == HW_ERROR_SCRUB_ON)
 		acpi_nfit_ars_rescan(acpi_desc, ARS_REQ_LONG);
 	else
author maintainer
#13 lore raw

PATCH 13/518 ACPI: NFIT: core: Fix acpi_nfit_init() error cleanup

In reply to Greg Kroah-Hartman

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

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

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

commit 38bf27511ef41bffebd157ec3eba41fc89ba59cd upstream.

If acpi_nfit_init() fails after adding the acpi_desc object to the acpi_descs list, that object is never removed from that list because the acpi_nfit_shutdown() devm action is not added for the NFIT device in that case. Next, the acpi_nfit_init() failure causes acpi_nfit_probe() to fail, the acpi_desc object is freed, and a dangling pointer is left behind in the acpi_descs. Any subsequent ACPI Machine Check Exception will trigger nfit_handle_mce() which iterates over acpi_descs and so a use-after-free will occur.

Moreover, if acpi_nfit_probe() returns 0 after installing a notify handler for the NFIT device and without allocating the acpi_desc object and setting the NFIT device's driver data pointer, the acpi_desc object will be allocated by acpi_nfit_update_notify() and acpi_nfit_init() will be called to initialize it. Regardless of whether or not acpi_nfit_init() fails in that case, the acpi_nfit_shutdown() devm action is not added for the NFIT device and acpi_desc is never removed from the acpi_descs list. If the acpi_desc object is freed subsequently on driver removal, any subsequent ACPI MCE will lead to a use-after-free like in the previous case.

To address the first issue mentioned above, make acpi_nfit_probe() call acpi_nfit_shutdown() directly on acpi_nfit_init() failures and to address the other one, add a remove callback to the driver and make it call acpi_nfit_shutdown(). Also, since it is now possible to pass NULL to acpi_nfit_shutdown() or the acpi_desc object passed to it may not have been initialized, add checks against NULL for acpi_desc and its nvdimm_bus field to that function and make acpi_nfit_unregister() clear the latter after unregistering the NVDIMM bus.

Fixes a61fe6f7902e ("nfit, tools/testing/nvdimm: unify common init for acpi_nfit_desc")
Fixes fbabd829fe76 ("acpi, nfit: fix module unload vs workqueue shutdown race")
Cc All applicable <[email protected]>
---
 drivers/acpi/nfit/core.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/acpi/nfit/core.c +15 -3
@@ -3069,6 +3069,8 @@ static void acpi_nfit_unregister(void *d
 	struct acpi_nfit_desc *acpi_desc = data;
 
 	nvdimm_bus_unregister(acpi_desc->nvdimm_bus);
+	/* The nvdimm_bus object may have been freed, so clear the pointer. */
+	acpi_desc->nvdimm_bus = NULL;
 }
 
 int acpi_nfit_init(struct acpi_nfit_desc *acpi_desc, void *data, acpi_size sz)
@@ -3309,7 +3311,10 @@ static void acpi_nfit_remove_notify_hand
 void acpi_nfit_shutdown(void *data)
 {
 	struct acpi_nfit_desc *acpi_desc = data;
-	struct device *bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus);
+	struct device *bus_dev;
+
+	if (!acpi_desc || !acpi_desc->nvdimm_bus)
+		return;
 
 	/*
 	 * Destruct under acpi_desc_lock so that nfit_handle_mce does not
@@ -3324,6 +3329,7 @@ void acpi_nfit_shutdown(void *data)
 	mutex_unlock(&acpi_desc->init_mutex);
 	cancel_delayed_work_sync(&acpi_desc->dwork);
 
+	bus_dev = to_nvdimm_bus_dev(acpi_desc->nvdimm_bus);
 	/*
 	 * Bounce the nvdimm bus lock to make sure any in-flight
 	 * acpi_nfit_ars_rescan() submissions have had a chance to
@@ -3406,9 +3412,14 @@ static int acpi_nfit_probe(struct platfo
 				sz - sizeof(struct acpi_table_nfit));
 
 	if (rc)
-		return rc;
+		acpi_nfit_shutdown(acpi_desc);
 
-	return devm_add_action_or_reset(dev, acpi_nfit_shutdown, acpi_desc);
+	return rc;
+}
+
+static void acpi_nfit_remove(struct platform_device *pdev)
+{
+	acpi_nfit_shutdown(platform_get_drvdata(pdev));
 }
 
 static void acpi_nfit_update_notify(struct device *dev, acpi_handle handle)
@@ -3492,6 +3503,7 @@ MODULE_DEVICE_TABLE(acpi, acpi_nfit_ids)
 
 static struct platform_driver acpi_nfit_driver = {
 	.probe = acpi_nfit_probe,
+	.remove = acpi_nfit_remove,
 	.driver = {
 		.name = "acpi-nfit",
 		.acpi_match_table = acpi_nfit_ids,
author maintainer
#14 lore raw

PATCH 14/518 platform/x86: intel-hid: Protect ACPI notify handler against recursion

In reply to Greg Kroah-Hartman

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

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

From: HyeongJun An <[email protected]>

commit c085d82613d5618814b84406c8b2d64f1bc305e7 upstream.

Since commit e2ffcda16290 ("ACPI: OSL: Allow Notify () handlers to run on all CPUs") ACPI notify handlers like the intel-hid notify_handler() may run on multiple CPU cores racing with themselves.

On convertibles and detachables (matched by DMI chassis-type 31 and 32 in dmi_auto_add_switch[]) the SW_TABLET_MODE input device is registered lazily from notify_handler() on the first tablet-mode event, via intel_hid_switches_setup(). When two such events race on different CPUs both can pass the !priv->switches check and register the priv->switches input device twice, resulting in a duplicate sysfs entry and a subsequent NULL pointer dereference.

This is the same class of bug fixed by commit e075c3b13a0a ("platform/x86:
intel-vbtn: Protect ACPI notify handler against recursion") for the sibling intel-vbtn driver.

Protect intel-hid notify_handler() from racing with itself with a mutex to fix this.

---
 drivers/platform/x86/intel/hid.c |    9 +++++++++
 1 file changed, 9 insertions(+)
drivers/platform/x86/intel/hid.c +9 -0
@@ -7,11 +7,13 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/cleanup.h>
 #include <linux/dmi.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/string_choices.h>
 #include <linux/suspend.h>
@@ -230,6 +232,7 @@ static const struct dmi_system_id dmi_au
 };
 
 struct intel_hid_priv {
+	struct mutex mutex; /* Avoid notify_handler() racing with itself */
 	struct input_dev *input_dev;
 	struct input_dev *array;
 	struct input_dev *switches;
@@ -565,6 +568,8 @@ static void notify_handler(acpi_handle h
 	struct key_entry *ke;
 	int err;
 
+	guard(mutex)(&priv->mutex);
+
 	/*
 	 * Some convertible have unreliable VGBS return which could cause incorrect
 	 * SW_TABLET_MODE report, in these cases we enable support when receiving
@@ -720,6 +725,10 @@ static int intel_hid_probe(struct platfo
 		return -ENOMEM;
 	dev_set_drvdata(&device->dev, priv);
 
+	err = devm_mutex_init(&device->dev, &priv->mutex);
+	if (err)
+		return err;
+
 	/* See dual_accel_detect.h for more info on the dual_accel check. */
 	if (enable_sw_tablet_mode == TABLET_SW_AUTO) {
 		if (dmi_check_system(dmi_vgbs_allow_list))
author maintainer
#15 lore raw

PATCH 15/518 LoongArch: Add PIO for early access before ACPI PCI root register

In reply to Greg Kroah-Hartman

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

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

From: Huacai Chen <[email protected]>

commit 6061e65f95713b01f4313cda6637dfe3aa5412b4 upstream.

For ACPI system we suppose the ISA/LPC PIO range is registered together with PCI root bridge. But the fact is there may be some early access to the ISA/LPC PIO range before ACPI PCI root register (most of them are due to abnormal BIOS). Unconditionally register the ISA/LPC PIO range usually causes ACPI PCI root register fail because of the address range confliction. So we add a pair of helpers: acpi_add_early_pio() to add PIO for early access, and acpi_remove_early_pio() to remove PIO before PCI root register. Since acpi_remove_early_pio() may be called multiple times, we add an acpi_pio flag to ensure PIO be removed only once.

---
 arch/loongarch/include/asm/acpi.h |    2 ++
 arch/loongarch/kernel/acpi.c      |   28 ++++++++++++++++++++++++++++
 arch/loongarch/kernel/setup.c     |    2 ++
 arch/loongarch/pci/acpi.c         |    2 ++
 4 files changed, 34 insertions(+)
arch/loongarch/include/asm/acpi.h +2 -0
@@ -38,6 +38,8 @@ static inline bool acpi_has_cpu_in_madt(
 extern struct list_head acpi_wakeup_device_list;
 extern struct acpi_madt_core_pic acpi_core_pic[MAX_CORE_PIC];
 
+extern void acpi_add_early_pio(void);
+extern void acpi_remove_early_pio(void);
 extern int __init parse_acpi_topology(void);
 
 #endif /* !CONFIG_ACPI */
arch/loongarch/kernel/acpi.c +28 -0
@@ -16,6 +16,7 @@
 #include <linux/memblock.h>
 #include <linux/of_fdt.h>
 #include <linux/serial_core.h>
+#include <linux/vmalloc.h>
 #include <asm/io.h>
 #include <asm/numa.h>
 #include <asm/loongson.h>
@@ -59,6 +60,33 @@ void __iomem *acpi_os_ioremap(acpi_physi
 		return ioremap_cache(phys, size);
 }
 
+#define PIO_BASE (unsigned long)PCI_IOBASE
+#define PIO_SIZE ALIGN(ISA_IOSIZE, PAGE_SIZE)
+
+static bool acpi_pio;
+
+/* Add PIO for early access */
+void acpi_add_early_pio(void)
+{
+	if (!acpi_disabled) {
+		acpi_pio = true;
+		vmap_page_range(PIO_BASE, PIO_BASE + PIO_SIZE,
+				LOONGSON_LIO_BASE, pgprot_device(PAGE_KERNEL));
+	}
+}
+
+/* Remove PIO for PCI register */
+void acpi_remove_early_pio(void)
+{
+	if (!acpi_pio)
+		return;
+
+	if (!acpi_disabled) {
+		acpi_pio = false;
+		vunmap_range(PIO_BASE, PIO_BASE + PIO_SIZE);
+	}
+}
+
 #ifdef CONFIG_SMP
 static int set_processor_mask(u32 id, u32 pass)
 {
arch/loongarch/kernel/setup.c +2 -0
@@ -502,6 +502,8 @@ static __init int arch_reserve_pio_range
 {
 	struct device_node *np;
 
+	acpi_add_early_pio();
+
 	for_each_node_by_name(np, "isa") {
 		struct of_range range;
 		struct of_range_parser parser;
arch/loongarch/pci/acpi.c +2 -0
@@ -65,6 +65,8 @@ static int acpi_prepare_root_resources(s
 	struct resource_entry *entry, *tmp;
 	struct acpi_device *device = ci->bridge;
 
+	acpi_remove_early_pio();
+
 	status = acpi_pci_probe_root_resources(ci);
 	if (status > 0) {
 		acpi_evaluate_integer(device->handle, "PCIH", NULL, &pci_h);
author maintainer
#16 lore raw

PATCH 16/518 rust: cpufreq: clean new `clippy::map_or_identity` lint for Rust 1.98.0

In reply to Greg Kroah-Hartman

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

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

From: Miguel Ojeda <[email protected]>

commit 3473e0a219fdb2cb013da0a5d917e66fef052325 upstream.

Starting with Rust 1.98.0 (expected 2026-08-20), Clippy is likely introducing a new lint clippy::map_or_identity [1][2], which currently triggers in a single case:

    warning: expression can be simplified using `Result::unwrap_or()`
        --> rust/kernel/cpufreq.rs:1326:60
         |
    1326 |         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
         |                                                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_or_identity
         = note: `-W clippy::map-or-identity` implied by `-W clippy::all`
         = help: to override `-W clippy::all` add `#[allow(clippy::map_or_identity)]`
    help: consider using `unwrap_or`
         |
    1326 -         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
    1326 +         PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).unwrap_or(0))
         |

The suggestion is valid, thus clean it up.

---
 rust/kernel/cpufreq.rs |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/cpufreq.rs +1 -1
@@ -1323,7 +1323,7 @@ impl<T: Driver> Registration<T> {
         // SAFETY: The C API guarantees that `cpu` refers to a valid CPU number.
         let cpu_id = unsafe { CpuId::from_u32_unchecked(cpu) };
 
-        PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).map_or(0, |f| f))
+        PolicyCpu::from_cpu(cpu_id).map_or(0, |mut policy| T::get(&mut policy).unwrap_or(0))
     }
 
     /// Driver's `update_limit` callback.
author maintainer
#17 lore raw

PATCH 17/518 rust: kasan: KASAN+RUST requires clang

In reply to Greg Kroah-Hartman

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

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

From: Alice Ryhl <[email protected]>

commit 5b271543d0f08e9733d4732721e960e285f6448f upstream.

Kernel KASAN involves passing various llvm/gcc specific arguments to the C and Rust compiler. Since these arguments differ between llvm and gcc, it's not safe to mix an llvm-based rustc with a gcc build when kasan is enabled.

---
 init/Kconfig |    1 +
 1 file changed, 1 insertion(+)
init/Kconfig +1 -0
@@ -2198,6 +2198,7 @@ config RUST
 	depends on !DEBUG_INFO_BTF || (PAHOLE_HAS_LANG_EXCLUDE && !LTO)
 	depends on !CFI || HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC
 	select CFI_ICALL_NORMALIZE_INTEGERS if CFI
+	depends on !KASAN || CC_IS_CLANG
 	depends on !KASAN_SW_TAGS
 	help
 	  Enables Rust support in the kernel.
author maintainer
#18 lore raw

PATCH 18/518 rust: pci: use static lifetime for PCI BAR resource names

In reply to Greg Kroah-Hartman

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

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

From: Danilo Krummrich <[email protected]>

commit e566a9e17f3774c962b6d2522750f227f027edc6 upstream.

pci_request_region() stores the name pointer directly in struct resource; use &'static CStr to ensure the pointer remains valid even if the Bar is leaked.

---
 rust/kernel/pci/io.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
rust/kernel/pci/io.rs +3 -3
index ae78676c927f..3ce21482b079 100644
@@ -153,7 +153,7 @@ pub struct Bar<const SIZE: usize = 0> {
 }
 
 impl<const SIZE: usize> Bar<SIZE> {
-    pub(super) fn new(pdev: &Device, num: u32, name: &CStr) -> Result<Self> {
+    pub(super) fn new(pdev: &Device, num: u32, name: &'static CStr) -> Result<Self> {
         let len = pdev.resource_len(num)?;
         if len == 0 {
             return Err(ENOMEM);
@@ -252,7 +252,7 @@ impl Device<device::Bound> {
     pub fn iomap_region_sized<'a, const SIZE: usize>(
         &'a self,
         bar: u32,
-        name: &'a CStr,
+        name: &'static CStr,
     ) -> impl PinInit<Devres<Bar<SIZE>>, Error> + 'a {
         Devres::new(self.as_ref(), Bar::<SIZE>::new(self, bar, name))
     }
@@ -261,7 +261,7 @@ pub fn iomap_region_sized<'a, const SIZE: usize>(
     pub fn iomap_region<'a>(
         &'a self,
         bar: u32,
-        name: &'a CStr,
+        name: &'static CStr,
     ) -> impl PinInit<Devres<Bar>, Error> + 'a {
         self.iomap_region_sized::<0>(bar, name)
     }
Signature · 1 line
2.55.0
author maintainer
#19 lore raw

PATCH 19/518 rust: block: fix GenDisk cleanup paths

In reply to Greg Kroah-Hartman

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

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

From: Haoze Xie <[email protected]>

commit 2957771379fa335103a4b539db57bb2271e12142 upstream.

GenDiskBuilder::build() still has fallible work after __blk_mq_alloc_disk(), but its error path only recovers the foreign queue data. That leaks the temporary gendisk and request_queue until later teardown. If the caller moved the last Arc<TagSet<T>> into build(), the leaked queue can retain blk-mq state after the tag set is dropped.

Fix the pre-registration failure path by dropping the temporary gendisk reference with put_disk() before recovering queue_data, so disk_release() can tear down the owned queue.

Also pair GenDisk::drop() with put_disk() after del_gendisk(). Once a Rust GenDisk has been added with device_add_disk(), del_gendisk() only unregisters it; the final gendisk reference still has to be dropped to complete the release path.

---
 rust/kernel/block/mq/gen_disk.rs |   20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)
rust/kernel/block/mq/gen_disk.rs +19 -1
@@ -150,6 +150,19 @@ impl GenDiskBuilder {
         // SAFETY: `gendisk` is a valid pointer as we initialized it above
         unsafe { (*gendisk).fops = &TABLE };
 
+        let cleanup_failure = ScopeGuard::new_with_data((gendisk, data), |(gendisk, data)| {
+            // SAFETY: `gendisk` came from `__blk_mq_alloc_disk()` above and
+            // has not been added to the VFS on this cleanup path.
+            unsafe { bindings::put_disk(gendisk) };
+            // SAFETY: `data` came from `into_foreign()` above and has not been
+            // converted back on this cleanup path.
+            drop(unsafe { T::QueueData::from_foreign(data) });
+        });
+
+        // The failure guard now owns both pieces of cleanup; the early guard
+        // must not run on this path anymore.
+        recover_data.dismiss();
+
         let mut writer = NullTerminatedFormatter::new(
             // SAFETY: `gendisk` points to a valid and initialized instance. We
             // have exclusive access, since the disk is not added to the VFS
@@ -172,7 +185,7 @@ impl GenDiskBuilder {
             },
         )?;
 
-        recover_data.dismiss();
+        cleanup_failure.dismiss();
 
         // INVARIANT: `gendisk` was initialized above.
         // INVARIANT: `gendisk` was added to the VFS via `device_add_disk` above.
@@ -215,6 +228,11 @@ impl<T: Operations> Drop for GenDisk<T>
         // to the VFS.
         unsafe { bindings::del_gendisk(self.gendisk) };
 
+        // SAFETY: By type invariant, `self.gendisk` was added to the VFS, so
+        // `put_disk()` must follow `del_gendisk()` to drop the final gendisk
+        // reference and trigger the remaining release path.
+        unsafe { bindings::put_disk(self.gendisk) };
+
         // SAFETY: `queue.queuedata` was created by `GenDiskBuilder::build` with
         // a call to `ForeignOwnable::into_foreign` to create `queuedata`.
         // `ForeignOwnable::from_foreign` is only called here.
author maintainer
#20 lore raw

PATCH 20/518 rust: doctest: fix incorrect pattern in replacement

In reply to Greg Kroah-Hartman

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

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

From: Gary Guo <[email protected]>

commit ac4d1caa82d487e7ed46d0597da1adc9c1a51c70 upstream.

The -> Result<(), impl core::fmt::Debug> string is generated by rustdoc and by adding "::" into the string it no longer finds anything, making the line useless.

Remove the "::" in the pattern. Omit it in the replacement too, for consistency with upstream rustdoc.

Fixes de7cd3e4d638 ("rust: use absolute paths in macros referencing core and kernel")

[ Added link in code comment to rustdoc's 1.87 PR that fully qualified
it for context. Improved comments for consistency. Reworded to drop changelog and to fix typo. - Miguel ]

---
 scripts/rustdoc_test_builder.rs |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
scripts/rustdoc_test_builder.rs +10 -6
@@ -28,7 +28,7 @@ fn main() {
     //
     // ```
     // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_28_0() {
-    // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl ::core::fmt::Debug> {
+    // fn main() { #[allow(non_snake_case)] fn _doctest_main_rust_kernel_file_rs_37_0() -> Result<(), impl core::fmt::Debug> {
     // ```
     //
     // It should be unlikely that doctest code matches such lines (when code is formatted properly).
@@ -47,12 +47,16 @@ fn main() {
         })
         .expect("No test function found in `rustdoc`'s output.");
 
-    // Qualify `Result` to avoid the collision with our own `Result` coming from the prelude.
+    // Replicate `rustdoc` 1.87+ behaviour [1] by fully qualifying `Result` to avoid the collision
+    // with our own `Result` coming from the prelude.
+    //
+    // [1]: https://github.com/rust-lang/rust/pull/137807
+    //
+    // TODO: Remove this when MSRV is bumped above 1.87.
     let body = body.replace(
-        &format!("{rustdoc_function_name}() -> Result<(), impl ::core::fmt::Debug> {{"),
-        &format!(
-            "{rustdoc_function_name}() -> ::core::result::Result<(), impl ::core::fmt::Debug> {{"
-        ),
+        &format!("{rustdoc_function_name}() -> Result<(), impl core::fmt::Debug> {{"),
+        // This intentionally does not use absolute paths to match `rustdoc` 1.87 behaviour.
+        &format!("{rustdoc_function_name}() -> core::result::Result<(), impl core::fmt::Debug> {{"),
     );
 
     // For tests that get generated with `Result`, like above, `rustdoc` generates an `unwrap()` on
author maintainer
#21 lore raw

PATCH 21/518 rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER

In reply to Greg Kroah-Hartman

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

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

From: Alice Ryhl <[email protected]>

commit 191f49f1e38b1c10eb44b0f967c6175c884ef7db upstream.

Due to a rustc bug, the -Cforce-frame-pointers=y flag only emits the frame-pointer annotation for functions, but not for the module. This means that functions generated by the LLVM backend such as 'asan.module_ctor' do not receive the frame-pointer annotation.

This is likely to lead to broken backtraces and may also cause issues with ftrace if these features are used with functions generated by the LLVM backend.

Thus, use -Zllvm_module_flag to work around this rustc bug if using a rustc without the fix.

[ The fix [1] has landed for Rust 1.98.0 (expected release on
2026-08-20). - Miguel ]

Cc [email protected] # 6.12.y and later (flag not available in pinned Rust in older LTSs).
Fixes 2f7ab1267dc9 ("Kbuild: add Rust support")

[ - Adjusted Cc: stable@ as discussed.

- Added comment with link to the PR, similar to what we did in commit ac35b5580ace ("rust: arm64: set uwtable llvm module flag for CONFIG_UNWIND_TABLES").

- Miguel ]

---
 Makefile |    3 +++
 1 file changed, 3 insertions(+)
Makefile +3 -0
@@ -959,6 +959,9 @@ KBUILD_CFLAGS += $(stackp-flags-y)
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS	+= -fno-omit-frame-pointer -fno-optimize-sibling-calls
 KBUILD_RUSTFLAGS += -Cforce-frame-pointers=y
+# Work around rustc bug on compilers without
+# https://github.com/rust-lang/rust/pull/156980.
+KBUILD_RUSTFLAGS += $(if $(call rustc-min-version,109800),,-Zllvm_module_flag=frame-pointer:u32:2:max)
 else
 # Some targets (ARM with Thumb2, for example), can't be built with frame
 # pointers.  For those, we don't have FUNCTION_TRACER automatically
#22 lore raw

Re: [PATCH 7.1 021/518] rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER

Quoted 10 lines · Greg Kroah-Hartman

[ - Adjusted Cc: stable@ as discussed.

- Added comment with link to the PR, similar to what we did in commit ac35b5580ace ("rust: arm64: set uwtable llvm module flag for CONFIG_UNWIND_TABLES").

- Miguel ]

Something strange happened here... :)

It seems your SoB got interleaved with my [ ] comment.

Cheers,
Miguel

author maintainer
#23 lore raw

Re: [PATCH 7.1 021/518] rust: Kbuild: set frame-pointer llvm module flag for CONFIG_FRAME_POINTER

Quoted 10 lines · Miguel Ojeda
Quoted 8 lines · Greg Kroah-Hartman

[ - Adjusted Cc: stable@ as discussed.

- Added comment with link to the PR, similar to what we did in commit ac35b5580ace ("rust: arm64: set uwtable llvm module flag for CONFIG_UNWIND_TABLES").

Quoted 6 lines
Quoted 2 lines

- Miguel ]

Something strange happened here... :)

It seems your SoB got interleaved with my [ ] comment.

Yeah, my tool found the first blank line after the s-o-b area and added it there. Thanks, I've fixed it up now on all of these.

greg k-h

author maintainer
#24 lore raw

PATCH 22/518 futex/requeue: Revert "Prevent NULL pointer dereference in remove_waiter() on self-deadlock""

In reply to Greg Kroah-Hartman

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

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

From: Sebastian Andrzej Siewior <[email protected]>

commit 39def6d250d370298f86c116f4ac60093cefadaa upstream.

The commit cited below should not have been merged. It attemted to fix an existing problem ansd thereby introduced new problems by keeping the pi_state in state Q_REQUEUE_PI_IN_PROGRESS and leaking it.

Based on the commit description the intention was to handle the case when task_blocks_on_rt_mutex() returns -EDEADLK and the following remove_waiter() dereferences the NULL pointer in waiter->task.

That is already handled by Davidlohr in commit 40a25d59e85b3 ("locking/rtmutex: Skip remove_waiter() when waiter is not enqueued") and requires no further acting.

Revert the commit breaking the "waiter == owner" case again.

---
 kernel/futex/requeue.c |    6 ------
 1 file changed, 6 deletions(-)
kernel/futex/requeue.c +0 -6
@@ -643,12 +643,6 @@ retry_private:
 				continue;
 			}
 
-			/* Self-deadlock: non-top waiter already owns the PI futex. */
-			if (rt_mutex_owner(&pi_state->pi_mutex) == this->task) {
-				ret = -EDEADLK;
-				break;
-			}
-
 			ret = rt_mutex_start_proxy_lock(&pi_state->pi_mutex,
 							this->rt_waiter,
 							this->task);
author maintainer
#25 lore raw

PATCH 23/518 perf/core: Detach event groups during remove_on_exec

In reply to Greg Kroah-Hartman

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

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

From: Taeyang Lee <[email protected]>

[ Upstream commit 037a3c43edfb597665dd34457cd22b14692f2ba3 ]

perf_event_remove_on_exec() removes events by calling perf_event_exit_event(). For top-level events, this removes the event from the context with DETACH_EXIT only.

This can leave inconsistent group state when a removed event is a group leader and the group contains siblings without remove_on_exec. If the group was active, the surviving siblings can remain active and attached to the removed leader's sibling list, but are no longer represented by a valid group leader on the PMU context active lists.

A later close of the removed leader uses DETACH_GROUP and can promote the still-active siblings from this stale group state. The next schedule-in can then add an already-linked active_list entry again, corrupting the PMU context active list.

With DEBUG_LIST enabled, this is caught as a list_add double-add in merge_sched_in().

Fix this by detaching group relationships when remove_on_exec removes an event. This preserves the existing task-exit and revoke behavior, while ensuring surviving siblings are ungrouped before the removed event leaves the context.

Fixes 2e498d0a74e5 ("perf: Add support for event removal on exec")
---
 kernel/events/core.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
kernel/events/core.c +9 -8
index 7935d5663944ee..bab0f3bd4fa8d8 100644
@@ -4728,7 +4728,7 @@ static void perf_remove_from_owner(struct perf_event *event);
 static void perf_event_exit_event(struct perf_event *event,
 				  struct perf_event_context *ctx,
 				  struct task_struct *task,
-				  bool revoke);
+				  unsigned long detach_flags);
 
 /*
  * Removes all events from the current task that have been marked
@@ -4755,7 +4755,7 @@ static void perf_event_remove_on_exec(struct perf_event_context *ctx)
 
 		modified = true;
 
-		perf_event_exit_event(event, ctx, ctx->task, false);
+		perf_event_exit_event(event, ctx, ctx->task, DETACH_GROUP);
 	}
 
 	raw_spin_lock_irqsave(&ctx->lock, flags);
@@ -12900,7 +12900,7 @@ static void __pmu_detach_event(struct pmu *pmu, struct perf_event *event,
 	/*
 	 * De-schedule the event and mark it REVOKED.
 	 */
-	perf_event_exit_event(event, ctx, ctx->task, true);
+	perf_event_exit_event(event, ctx, ctx->task, DETACH_REVOKE);
 
 	/*
 	 * All _free_event() bits that rely on event->pmu:
@@ -14488,12 +14488,13 @@ static void
 perf_event_exit_event(struct perf_event *event,
 		      struct perf_event_context *ctx,
 		      struct task_struct *task,
-		      bool revoke)
+		      unsigned long detach_flags)
 {
 	struct perf_event *parent_event = event->parent;
-	unsigned long detach_flags = DETACH_EXIT;
 	unsigned int attach_state;
 
+	detach_flags |= DETACH_EXIT;
+
 	if (parent_event) {
 		/*
 		 * Do not destroy the 'original' grouping; because of the
@@ -14516,8 +14517,8 @@ perf_event_exit_event(struct perf_event *event,
 			sync_child_event(event, task);
 	}
 
-	if (revoke)
-		detach_flags |= DETACH_GROUP | DETACH_REVOKE;
+	if (detach_flags & DETACH_REVOKE)
+		detach_flags |= DETACH_GROUP;
 
 	perf_remove_from_context(event, detach_flags);
 	/*
@@ -14605,7 +14606,7 @@ static void perf_event_exit_task_context(struct task_struct *task, bool exit)
 		perf_event_task(task, ctx, 0);
 
 	list_for_each_entry_safe(child_event, next, &ctx->event_list, event_entry)
-		perf_event_exit_event(child_event, ctx, exit ? task : NULL, false);
+		perf_event_exit_event(child_event, ctx, exit ? task : NULL, 0);
 
 	mutex_unlock(&ctx->mutex);
 
Signature · 1 line
2.53.0
author maintainer
#26 lore raw

PATCH 24/518 bpf: Support for hardening against JIT spraying

In reply to Greg Kroah-Hartman

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

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

From: Pawan Gupta <[email protected]>

commit 96cce16e26dd02a8678f1e87f88a4b5cdb63b995 upstream.

The BPF JIT allocator packs many small programs into larger executable allocations and reuses space within those allocations as programs are loaded and freed. When fresh code is written into space that a previous program occupied, an indirect jump into the new program can reuse a branch prediction left behind by the old one.

Flush the indirect branch predictors before reusing JIT memory so that indirect jumps into a newly written program don't reuse predictions from an old program that occupied the same space.

Introduce bpf_arch_pred_flush_enabled static key and bpf_arch_pred_flush static call for flushing the branch predictors on JIT memory reuse. Architectures that need a flush, can update it to a predictor flush function. By default, its a NOP and does not emit any CALL.

Allocations larger than a pack are not covered by this flush. That is safe because cBPF programs (the unprivileged attack surface) are bounded well below a pack size. Issue a warning if this assumption is ever violated while the flush is active.

---
 include/linux/filter.h | 10 ++++++++++
 kernel/bpf/core.c      | 19 +++++++++++++++++++
 2 files changed, 29 insertions(+)
include/linux/filter.h +10 -0
index 88a241aac36a27..2a7e6cbbbe1d3f 100644
@@ -21,6 +21,7 @@
 #include <linux/if_vlan.h>
 #include <linux/vmalloc.h>
 #include <linux/sockptr.h>
+#include <linux/static_call.h>
 #include <linux/u64_stats_sync.h>
 
 #include <net/sch_generic.h>
@@ -1291,6 +1292,15 @@ extern long bpf_jit_limit_max;
 
 typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size);
 
+/*
+ * Flush the indirect branch predictors before reusing JIT memory, so that
+ * indirect jumps into a newly written program don't reuse predictions left
+ * behind by an old program that occupied the same space.
+ */
+void bpf_arch_pred_flush(void);
+DECLARE_STATIC_CALL(bpf_arch_pred_flush, bpf_arch_pred_flush);
+DECLARE_STATIC_KEY_FALSE(bpf_pred_flush_enabled);
+
 void bpf_jit_fill_hole_with_zero(void *area, unsigned int size);
 
 struct bpf_binary_header *
kernel/bpf/core.c +19 -0
index 6aa2a8b2403065..f49b9b23f95e60 100644
@@ -20,6 +20,7 @@
 #include <uapi/linux/btf.h>
 #include <linux/filter.h>
 #include <linux/skbuff.h>
+#include <linux/static_call.h>
 #include <linux/vmalloc.h>
 #include <linux/prandom.h>
 #include <linux/bpf.h>
@@ -883,6 +884,15 @@ void bpf_jit_fill_hole_with_zero(void *area, unsigned int size)
 	memset(area, 0, size);
 }
 
+DEFINE_STATIC_CALL_NULL(bpf_arch_pred_flush, bpf_arch_pred_flush);
+
+/*
+ * Enabled once bpf_arch_pred_flush points at a real flush routine. Lets the
+ * pack allocator test "is a predictor flush wired up at all" with a cheap
+ * static branch instead of repeatedly querying the static call target.
+ */
+DEFINE_STATIC_KEY_FALSE(bpf_pred_flush_enabled);
+
 #define BPF_PROG_SIZE_TO_NBITS(size)	(round_up(size, BPF_PROG_CHUNK_SIZE) / BPF_PROG_CHUNK_SIZE)
 
 static DEFINE_MUTEX(pack_mutex);
@@ -941,6 +951,14 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
 
 	mutex_lock(&pack_mutex);
 	if (size > BPF_PROG_PACK_SIZE) {
+		/*
+		 * Allocations larger than a pack get their own pages, and
+		 * predictors are not flushed for such allocation. This is only
+		 * safe because cBPF programs (the unprivileged attack surface)
+		 * are bounded well below a pack size.
+		 */
+		if (static_branch_unlikely(&bpf_pred_flush_enabled))
+			pr_warn_once("BPF: Predictors not flushed for allocations greater than BPF_PROG_PACK_SIZE\n");
 		size = round_up(size, PAGE_SIZE);
 		ptr = bpf_jit_alloc_exec(size);
 		if (ptr) {
@@ -971,6 +989,7 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
 	pos = 0;
 
 found_free_area:
+	static_call_cond(bpf_arch_pred_flush)();
 	bitmap_set(pack->bitmap, pos, nbits);
 	ptr = (void *)(pack->ptr) + (pos << BPF_PROG_CHUNK_SHIFT);
 
Signature · 1 line
2.53.0
author maintainer
#27 lore raw

PATCH 25/518 x86/bugs: Enable IBPB flush on BPF JIT allocation

In reply to Greg Kroah-Hartman

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

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

From: Pawan Gupta <[email protected]>

commit a3af84b0fa00ead01fcd0e28b5d773ff25990a0d upstream.

Enable hardening against JIT spraying when Spectre-v2 mitigations are in use. Specifically, issue an IBPB flush on BPF JIT memory reuse. Skip enabling the IBPB flush if the BPF dispatcher is already using a retpoline sequence.

This hardening applies only when BPF-JIT is in use. Guard the enabling under CONFIG_BPF_JIT so that bugs.c still builds with CONFIG_BPF_JIT=n.

---
 arch/x86/include/asm/nospec-branch.h |  4 +++
 arch/x86/kernel/cpu/bugs.c           | 50 +++++++++++++++++++++++++---
 2 files changed, 49 insertions(+), 5 deletions(-)
arch/x86/include/asm/nospec-branch.h +4 -0
index 4f4b5e8a157430..b68892e6d58c47 100644
@@ -388,6 +388,10 @@ extern void srso_alias_return_thunk(void);
 extern void entry_untrain_ret(void);
 extern void write_ibpb(void);
 
+#ifdef CONFIG_BPF_JIT
+extern void bpf_arch_ibpb(void);
+#endif
+
 #ifdef CONFIG_X86_64
 extern void clear_bhb_loop(void);
 #endif
arch/x86/kernel/cpu/bugs.c +45 -5

88 lines not on this page · raw message

Signature · 1 line
2.53.0
author maintainer
#28 lore raw

PATCH 26/518 bpf: Restrict JIT predictor flush to cBPF

In reply to Greg Kroah-Hartman

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

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

From: Pawan Gupta <[email protected]>

commit 0bb99f2cfaae6822d734d69722de30af823efdf3 upstream.

Currently predictor flush on memory reuse is done for all BPF JIT allocations, but only cBPF programs can be loaded by an unprivileged user. eBPF is privileged by default, and flushing predictors for all CPUs on every eBPF reuse penalizes the common case for no security benefit.

eBPF allocations can be frequent on busy systems, only flush predictors for cBPF programs. Trampoline and dispatcher allocations also skip the flush as they are eBPF-only.

---
 arch/arm64/net/bpf_jit_comp.c   |  4 ++--
 arch/loongarch/net/bpf_jit.c    |  5 +++--
 arch/powerpc/net/bpf_jit_comp.c |  4 ++--
 arch/riscv/net/bpf_jit_comp64.c |  2 +-
 arch/riscv/net/bpf_jit_core.c   |  3 ++-
 arch/x86/net/bpf_jit_comp.c     |  5 +++--
 include/linux/filter.h          |  5 +++--
 kernel/bpf/core.c               | 13 ++++++++-----
 kernel/bpf/dispatcher.c         |  2 +-
 9 files changed, 25 insertions(+), 18 deletions(-)
arch/arm64/net/bpf_jit_comp.c +2 -2
index 0816c40fc7af95..9491c987e50c01 100644
@@ -2094,7 +2094,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
 	image_size = extable_offset + extable_size;
 	ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr,
 					      sizeof(u64), &header, &image_ptr,
-					      jit_fill_hole);
+					      jit_fill_hole, was_classic);
 	if (!ro_header)
 		goto out_off;
 
@@ -2782,7 +2782,7 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
 
 void *arch_alloc_bpf_trampoline(unsigned int size)
 {
-	return bpf_prog_pack_alloc(size, jit_fill_hole);
+	return bpf_prog_pack_alloc(size, jit_fill_hole, false);
 }
 
 void arch_free_bpf_trampoline(void *image, unsigned int size)
arch/loongarch/net/bpf_jit.c +3 -2
index 24913dc7f4e835..e14a8aa47fc8ea 100644
@@ -1762,7 +1762,7 @@ static int invoke_bpf(struct jit_ctx *ctx, struct bpf_tramp_links *tl,
 
 void *arch_alloc_bpf_trampoline(unsigned int size)
 {
-	return bpf_prog_pack_alloc(size, jit_fill_hole);
+	return bpf_prog_pack_alloc(size, jit_fill_hole, false);
 }
 
 void arch_free_bpf_trampoline(void *image, unsigned int size)
@@ -2228,7 +2228,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
 	image_size = prog_size + extable_size;
 	/* Now we know the size of the structure to make */
 	ro_header = bpf_jit_binary_pack_alloc(image_size, &ro_image_ptr, sizeof(u32),
-					      &header, &image_ptr, jit_fill_hole);
+					      &header, &image_ptr, jit_fill_hole,
+					      bpf_prog_was_classic(prog));
 	if (!ro_header)
 		goto out_offset;
 
arch/powerpc/net/bpf_jit_comp.c +2 -2
index 53ab97ad607453..73ff8a64bb7fad 100644
@@ -295,7 +295,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
 	alloclen = proglen + FUNCTION_DESCR_SIZE + fixup_len + extable_len;
 
 	fhdr = bpf_jit_binary_pack_alloc(alloclen, &fimage, 4, &hdr, &image,
-					      bpf_jit_fill_ill_insns);
+					 bpf_jit_fill_ill_insns, bpf_prog_was_classic(fp));
 	if (!fhdr)
 		goto out_err;
 
@@ -583,7 +583,7 @@ bool bpf_jit_inlines_helper_call(s32 imm)
 
 void *arch_alloc_bpf_trampoline(unsigned int size)
 {
-	return bpf_prog_pack_alloc(size, bpf_jit_fill_ill_insns);
+	return bpf_prog_pack_alloc(size, bpf_jit_fill_ill_insns, false);
 }
 
 void arch_free_bpf_trampoline(void *image, unsigned int size)
arch/riscv/net/bpf_jit_comp64.c +1 -1
index 2f1109dbf105b7..404a98a0fc90e8 100644
@@ -1321,7 +1321,7 @@ int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
 
 void *arch_alloc_bpf_trampoline(unsigned int size)
 {
-	return bpf_prog_pack_alloc(size, bpf_fill_ill_insns);
+	return bpf_prog_pack_alloc(size, bpf_fill_ill_insns, false);
 }
 
 void arch_free_bpf_trampoline(void *image, unsigned int size)
arch/riscv/net/bpf_jit_core.c +2 -1
index 4365d07aaf547c..ce3bd3762e08cc 100644
@@ -109,7 +109,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
 				bpf_jit_binary_pack_alloc(prog_size + extable_size,
 							  &jit_data->ro_image, sizeof(u32),
 							  &jit_data->header, &jit_data->image,
-							  bpf_fill_ill_insns);
+							  bpf_fill_ill_insns,
+							  bpf_prog_was_classic(prog));
 			if (!jit_data->ro_header)
 				goto out_offset;
 
arch/x86/net/bpf_jit_comp.c +3 -2
index ea9e707e8abffb..ef8b112fd7b692 100644
@@ -3520,7 +3520,7 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *rw_im
 
 void *arch_alloc_bpf_trampoline(unsigned int size)
 {
-	return bpf_prog_pack_alloc(size, jit_fill_hole);
+	return bpf_prog_pack_alloc(size, jit_fill_hole, false);
 }
 
 void arch_free_bpf_trampoline(void *image, unsigned int size)
@@ -3831,7 +3831,8 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr
 			/* allocate module memory for x86 insns and extable */
 			header = bpf_jit_binary_pack_alloc(roundup(proglen, align) + extable_size,
 							   &image, align, &rw_header, &rw_image,
-							   jit_fill_hole);
+							   jit_fill_hole,
+							   bpf_prog_was_classic(prog));
 			if (!header)
 				goto out_addrs;
 			prog->aux->extable = (void *) image + roundup(proglen, align);
include/linux/filter.h +3 -2
index 2a7e6cbbbe1d3f..ea654453e43a34 100644
@@ -1315,7 +1315,7 @@ void bpf_jit_free(struct bpf_prog *fp);
 struct bpf_binary_header *
 bpf_jit_binary_pack_hdr(const struct bpf_prog *fp);
 
-void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns);
+void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool was_classic);
 void bpf_prog_pack_free(void *ptr, u32 size);
 
 static inline bool bpf_prog_kallsyms_verify_off(const struct bpf_prog *fp)
@@ -1329,7 +1329,8 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **ro_image,
 			  unsigned int alignment,
 			  struct bpf_binary_header **rw_hdr,
 			  u8 **rw_image,
-			  bpf_jit_fill_hole_t bpf_fill_ill_insns);
+			  bpf_jit_fill_hole_t bpf_fill_ill_insns,
+			  bool was_classic);
 int bpf_jit_binary_pack_finalize(struct bpf_binary_header *ro_header,
 				 struct bpf_binary_header *rw_header);
 void bpf_jit_binary_pack_free(struct bpf_binary_header *ro_header,
kernel/bpf/core.c +8 -5
index f49b9b23f95e60..1b7e74e63bd4bc 100644
@@ -942,7 +942,7 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
 	return NULL;
 }
 
-void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
+void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool was_classic)
 {
 	unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
 	struct bpf_prog_pack *pack;
@@ -957,7 +957,7 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
 		 * safe because cBPF programs (the unprivileged attack surface)
 		 * are bounded well below a pack size.
 		 */
-		if (static_branch_unlikely(&bpf_pred_flush_enabled))
+		if (was_classic && static_branch_unlikely(&bpf_pred_flush_enabled))
 			pr_warn_once("BPF: Predictors not flushed for allocations greater than BPF_PROG_PACK_SIZE\n");
 		size = round_up(size, PAGE_SIZE);
 		ptr = bpf_jit_alloc_exec(size);
@@ -989,7 +989,9 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns)
 	pos = 0;
 
 found_free_area:
-	static_call_cond(bpf_arch_pred_flush)();
+	/* Flush only for cBPF as it may contain a crafted gadget */
+	if (static_branch_unlikely(&bpf_pred_flush_enabled) && was_classic)
+		static_call_cond(bpf_arch_pred_flush)();
 	bitmap_set(pack->bitmap, pos, nbits);
 	ptr = (void *)(pack->ptr) + (pos << BPF_PROG_CHUNK_SHIFT);
 
@@ -1149,7 +1151,8 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,
 			  unsigned int alignment,
 			  struct bpf_binary_header **rw_header,
 			  u8 **rw_image,
-			  bpf_jit_fill_hole_t bpf_fill_ill_insns)
+			  bpf_jit_fill_hole_t bpf_fill_ill_insns,
+			  bool was_classic)
 {
 	struct bpf_binary_header *ro_header;
 	u32 size, hole, start;
@@ -1162,7 +1165,7 @@ bpf_jit_binary_pack_alloc(unsigned int proglen, u8 **image_ptr,
 
 	if (bpf_jit_charge_modmem(size))
 		return NULL;
-	ro_header = bpf_prog_pack_alloc(size, bpf_fill_ill_insns);
+	ro_header = bpf_prog_pack_alloc(size, bpf_fill_ill_insns, was_classic);
 	if (!ro_header) {
 		bpf_jit_uncharge_modmem(size);
 		return NULL;
kernel/bpf/dispatcher.c +1 -1
index b77db7413f8c70..ea2d60dc1feeb7 100644
@@ -145,7 +145,7 @@ void bpf_dispatcher_change_prog(struct bpf_dispatcher *d, struct bpf_prog *from,
 
 	mutex_lock(&d->mutex);
 	if (!d->image) {
-		d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero);
+		d->image = bpf_prog_pack_alloc(PAGE_SIZE, bpf_jit_fill_hole_with_zero, false);
 		if (!d->image)
 			goto out;
 		d->rw_image = bpf_jit_alloc_exec(PAGE_SIZE);
Signature · 1 line
2.53.0
author maintainer
#29 lore raw

PATCH 27/518 bpf: Skip redundant IBPB in pack allocator

In reply to Greg Kroah-Hartman

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

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

From: Pawan Gupta <[email protected]>

commit a23c1c5396a91680703360d1ee28a44657c503c4 upstream.

bpf_prog_pack_alloc() issues IBPB on all CPUs on every cBPF allocation, even when reusing chunks from an existing pack where no new memory was touched since the last IBPB.

Since IBPB on all CPUs is heavy, Dave Hansen suggested to track allocation since last IBPB, and only issue IBPB at reuse for the chunks that have not seen an IBPB since they were last freed.

Track per-pack whether an IBPB is needed via arch_flush_needed. Set it when allocating a chunk, reset on IBPB flush. On reuse, conditionally issue the flush. Since IBPB invalidates all BTB entries, clear the flag on all packs after flushing.

---
 kernel/bpf/core.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)
kernel/bpf/core.c +14 -1
index 1b7e74e63bd4bc..1bf4b8dffe9158 100644
@@ -876,6 +876,7 @@ int bpf_jit_add_poke_descriptor(struct bpf_prog *prog,
 struct bpf_prog_pack {
 	struct list_head list;
 	void *ptr;
+	bool arch_flush_needed;
 	unsigned long bitmap[];
 };
 
@@ -928,6 +929,8 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
 	bpf_fill_ill_insns(pack->ptr, BPF_PROG_PACK_SIZE);
 	bitmap_zero(pack->bitmap, BPF_PROG_PACK_SIZE / BPF_PROG_CHUNK_SIZE);
 
+	if (static_branch_unlikely(&bpf_pred_flush_enabled))
+		pack->arch_flush_needed = true;
 	set_vm_flush_reset_perms(pack->ptr);
 	err = set_memory_rox((unsigned long)pack->ptr,
 			     BPF_PROG_PACK_SIZE / PAGE_SIZE);
@@ -990,8 +993,15 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool
 
 found_free_area:
 	/* Flush only for cBPF as it may contain a crafted gadget */
-	if (static_branch_unlikely(&bpf_pred_flush_enabled) && was_classic)
+	if (static_branch_unlikely(&bpf_pred_flush_enabled) &&
+	    pack->arch_flush_needed &&
+	    was_classic) {
+		struct bpf_prog_pack *p;
+
 		static_call_cond(bpf_arch_pred_flush)();
+		list_for_each_entry(p, &pack_list, list)
+			p->arch_flush_needed = false;
+	}
 	bitmap_set(pack->bitmap, pos, nbits);
 	ptr = (void *)(pack->ptr) + (pos << BPF_PROG_CHUNK_SHIFT);
 
@@ -1029,6 +1039,9 @@ void bpf_prog_pack_free(void *ptr, u32 size)
 		  "bpf_prog_pack bug: missing bpf_arch_text_invalidate?\n");
 
 	bitmap_clear(pack->bitmap, pos, nbits);
+
+	if (static_branch_unlikely(&bpf_pred_flush_enabled))
+		pack->arch_flush_needed = true;
 	if (bitmap_find_next_zero_area(pack->bitmap, BPF_PROG_CHUNK_COUNT, 0,
 				       BPF_PROG_CHUNK_COUNT, 0) == 0) {
 		list_del(&pack->list);
Signature · 1 line
2.53.0
author maintainer
#30 lore raw

PATCH 28/518 bpf: Prefer packs that wont trigger an IBPB flush on allocation

In reply to Greg Kroah-Hartman

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

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

From: Pawan Gupta <[email protected]>

commit a9b1f19a6a673ba06820898d0f1ad02883ea1639 upstream.

Currently BPF pack allocator picks the chunks from the first available pack. While this is okay, it naturally leads to more frequent flushes when there are multiple packs in the system that weren't used since the last flush.

As an optimization prefer allocating the new programs from packs that are unused since last flush. When all packs are dirty, allocation forces a flush and marks all packs clean.

Below are some future optimizations ideas:

1. Currently, the "dirty" tracking is only done at the pack-level. Flush frequency can further be reduced with chunk-level tracking. This requires a new bitmap per-pack to track the dirty state.
2. IBPB flush is done on all CPUs, even if only a single CPU ran the BPF program. On a system with hundreds of CPUs this could be a major bottleneck forcing hundreds of IPIs to deliver the flush. The solution is to track the CPUs where a BPF program ran, and issue IBPB only on those CPUs.
3. Avoid IBPB when flush is already done at other sources (e.g. context switch).

---
 kernel/bpf/core.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)
kernel/bpf/core.c +24 -3
index 1bf4b8dffe9158..bba4acd61d4126 100644
@@ -948,8 +948,8 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
 void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool was_classic)
 {
 	unsigned int nbits = BPF_PROG_SIZE_TO_NBITS(size);
-	struct bpf_prog_pack *pack;
-	unsigned long pos;
+	struct bpf_prog_pack *pack, *fallback_pack = NULL;
+	unsigned long pos, fallback_pos = 0;
 	void *ptr = NULL;
 
 	mutex_lock(&pack_mutex);
@@ -981,8 +981,29 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool
 	list_for_each_entry(pack, &pack_list, list) {
 		pos = bitmap_find_next_zero_area(pack->bitmap, BPF_PROG_CHUNK_COUNT, 0,
 						 nbits, 0);
-		if (pos < BPF_PROG_CHUNK_COUNT)
+		if (pos >= BPF_PROG_CHUNK_COUNT)
+			continue;
+		/* Flush not enabled, use any pack */
+		if (!static_branch_unlikely(&bpf_pred_flush_enabled))
 			goto found_free_area;
+		/*
+		 * cBPF reuse of a dirty pack triggers a flush, so prefer a
+		 * clean pack for cBPF. eBPF never flushes, so pick the first
+		 * free pack, dirty or clean.
+		 */
+		if (!was_classic || !pack->arch_flush_needed)
+			goto found_free_area;
+		if (!fallback_pack) {
+			fallback_pack = pack;
+			fallback_pos = pos;
+		}
+	}
+
+	/* No preferred pack found */
+	if (fallback_pack) {
+		pack = fallback_pack;
+		pos = fallback_pos;
+		goto found_free_area;
 	}
 
 	pack = alloc_new_pack(bpf_fill_ill_insns);
Signature · 1 line
2.53.0
author maintainer
#31 lore raw

PATCH 29/518 bpf: Prefer dirty packs for eBPF allocations

In reply to Greg Kroah-Hartman

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

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

From: Pawan Gupta <[email protected]>

commit b72e29e0f7ee329d89f86db8700c8ea99b4a370a upstream.

The pack allocator only flushes predictors when reusing a dirty pack for cBPF, eBPF allocations never trigger a flush. Currently, eBPF picks the first free pack, which could be a clean pack. As an optimization, leaving a clean pack for cBPF can avoid flushes.

Prefer dirty packs for eBPF and keep clean packs free for cBPF. This mirrors the existing cBPF preference for clean packs: each program kind prefers the pack that avoids an extra flush, and falls back to the other kind only when no preferred pack has room. eBPF reuse of a dirty pack is harmless since eBPF being privileged does not flush.

---
 kernel/bpf/core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
kernel/bpf/core.c +3 -3
index bba4acd61d4126..de61e1894452ef 100644
@@ -988,10 +988,10 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool
 			goto found_free_area;
 		/*
 		 * cBPF reuse of a dirty pack triggers a flush, so prefer a
-		 * clean pack for cBPF. eBPF never flushes, so pick the first
-		 * free pack, dirty or clean.
+		 * clean pack for cBPF. eBPF never flushes, so steer it to a
+		 * dirty pack and keep clean packs free for cBPF.
 		 */
-		if (!was_classic || !pack->arch_flush_needed)
+		if (was_classic ^ pack->arch_flush_needed)
 			goto found_free_area;
 		if (!fallback_pack) {
 			fallback_pack = pack;
Signature · 1 line
2.53.0
author maintainer
#32 lore raw

PATCH 30/518 wifi: rtw89: correct drop logic for malformed AMPDU frames

In reply to Greg Kroah-Hartman

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

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

From: Po-Hao Huang <[email protected]>

[ Upstream commit 63ccdfac8677387dfdbd9d4336089e9823280704 ]

The previous commit aims to fix issue caused by malformed AMPDU frames. But the drop logic fails to deal with the first AMPDU packet paired with certain range of sequence number, and leads to unexpected packet drop. It is more likely to encounter this failure when there are busy traffic during rekey process and could lead to disconnection from the AP. Fix this by adding a initial state judgement and only reset status during pairwise rekey.

Fixes bda294ed0ed0 ("wifi: rtw89: Drop malformed AMPDU frames with abnormal PN")
---
 drivers/net/wireless/realtek/rtw89/core.c     | 3 ++-
 drivers/net/wireless/realtek/rtw89/mac80211.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
drivers/net/wireless/realtek/rtw89/core.c +2 -1
index 70feab97dccb5a..486c1774fb9759 100644
@@ -3363,7 +3363,8 @@ static bool rtw89_core_skb_pn_valid(struct rtw89_dev *rtwdev,
 		last_pn = tid_stats->last_pn;
 
 		if (pn > last_pn) {
-			if (ieee80211_sn_less(mpdu_sn, tid_stats->last_sn)) {
+			if (last_pn != -1LL &&
+			    ieee80211_sn_less(mpdu_sn, tid_stats->last_sn)) {
 				dev_kfree_skb_any(skb);
 
 				return false;
drivers/net/wireless/realtek/rtw89/mac80211.c +2 -1
index 501c3af1da01a9..0672d13d13a647 100644
@@ -964,7 +964,8 @@ static int rtw89_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 			rtw89_err(rtwdev, "failed to add key to sec cam\n");
 			return ret;
 		}
-		rtw89_core_tid_rx_stats_reset(rtwdev);
+		if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE)
+			rtw89_core_tid_rx_stats_reset(rtwdev);
 		break;
 	case DISABLE_KEY:
 		flush_work(&rtwdev->txq_work);
Signature · 1 line
2.53.0
author maintainer
#33 lore raw

PATCH 31/518 usb: gadget: function: rndis: add length check to response query

In reply to Greg Kroah-Hartman

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

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

From: Griffin Kroah-Hartman <[email protected]>

commit 95f90eea070837f7c72207d5520f805bdefc3bc5 upstream.

Add variable representations for BufLength and BufOffset in rndis_query_response(), and perform a length check on them.

This is identical to how rndis_set_response() handles these parameters.

---
 drivers/usb/gadget/function/rndis.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/usb/gadget/function/rndis.c +10 -4
@@ -591,6 +591,7 @@ static int rndis_init_response(struct rn
 static int rndis_query_response(struct rndis_params *params,
 				rndis_query_msg_type *buf)
 {
+	u32 BufLength, BufOffset;
 	rndis_query_cmplt_type *resp;
 	rndis_resp_t *r;
 
@@ -598,6 +599,13 @@ static int rndis_query_response(struct r
 	if (!params->dev)
 		return -ENOTSUPP;
 
+	BufLength = le32_to_cpu(buf->InformationBufferLength);
+	BufOffset = le32_to_cpu(buf->InformationBufferOffset);
+	if ((BufLength > RNDIS_MAX_TOTAL_SIZE) ||
+	    (BufOffset > RNDIS_MAX_TOTAL_SIZE) ||
+	    (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE))
+		return -EINVAL;
+
 	/*
 	 * we need more memory:
 	 * gen_ndis_query_resp expects enough space for
@@ -614,10 +622,8 @@ static int rndis_query_response(struct r
 	resp->RequestID = buf->RequestID; /* Still LE in msg buffer */
 
 	if (gen_ndis_query_resp(params, le32_to_cpu(buf->OID),
-			le32_to_cpu(buf->InformationBufferOffset)
-					+ 8 + (u8 *)buf,
-			le32_to_cpu(buf->InformationBufferLength),
-			r)) {
+				BufOffset + 8 + (u8 *)buf,
+				BufLength, r)) {
 		/* OID not supported */
 		resp->Status = cpu_to_le32(RNDIS_STATUS_NOT_SUPPORTED);
 		resp->MessageLength = cpu_to_le32(sizeof *resp);
author maintainer
#34 lore raw

PATCH 32/518 usb: gadget: function: rndis: add length check for header

In reply to Greg Kroah-Hartman

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

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

From: Griffin Kroah-Hartman <[email protected]>

commit 21b5bf155435008e0fb0736795289788e63d426f upstream.

Add a length check for the rndis header in rndis_rm_hdr, to ensure that MessageType, MessageLength, DataOffset, and DataLength fields are present before they are accessed.

---
 drivers/usb/gadget/function/rndis.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/usb/gadget/function/rndis.c +6 -0
@@ -1080,6 +1080,12 @@ int rndis_rm_hdr(struct gether *port,
 	/* tmp points to a struct rndis_packet_msg_type */
 	__le32 *tmp = (void *)skb->data;
 
+	/* Need at least MessageType, MessageLength, DataOffset, DataLength */
+	if (skb->len < 16) {
+		dev_kfree_skb_any(skb);
+		return -EINVAL;
+	}
+
 	/* MessageType, MessageLength */
 	if (cpu_to_le32(RNDIS_MSG_PACKET)
 			!= get_unaligned(tmp++)) {
author maintainer
#35 lore raw

PATCH 33/518 iio: accel: bmc150: clamp the device-reported FIFO frame count

In reply to Greg Kroah-Hartman

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

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

From: Bryam Vargas <[email protected]>

commit ce0e1cae26096fe959a0da5563a6d6d5a801d5fb upstream.

__bmc150_accel_fifo_flush() copies the number of samples the device reports in its hardware FIFO into an on-stack buffer

	u16 buffer[BMC150_ACCEL_FIFO_LENGTH * 3];

which is sized for at most BMC150_ACCEL_FIFO_LENGTH (32) samples. The frame count is read from the FIFO_STATUS register and only masked to its 7 valid bits:

	count = val & 0x7F;

so it can be 0..127. The only other limit applied to it is the optional caller-supplied sample budget:

	if (samples && count > samples)
		count = samples;

which does not constrain count on the flush-all path (samples == 0), and leaves it well above 32 whenever samples is larger. count samples are then transferred into buffer[]:

	bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);

bmc150_accel_fifo_transfer() reads count * 6 bytes through regmap, so a malfunctioning, malicious or counterfeit accelerometer (or an attacker tampering with the I2C/SPI bus) that reports up to 127 frames writes up to 762 bytes into the 192-byte buffer: a stack out-of-bounds write of up to 570 bytes that clobbers the stack canary, saved registers and the return address.

Clamp count to BMC150_ACCEL_FIFO_LENGTH, the number of samples buffer[] is sized for, before the transfer, mirroring the watermark clamp already done in bmc150_accel_set_watermark(). A well-formed flush reports at most BMC150_ACCEL_FIFO_LENGTH frames, so legitimate devices are unaffected.

Fixes 3bbec9773389 ("iio: bmc150_accel: add support for hardware fifo")
---
 drivers/iio/accel/bmc150-accel-core.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/iio/accel/bmc150-accel-core.c +2 -0
@@ -991,6 +991,8 @@ static int __bmc150_accel_fifo_flush(str
 	if (samples && count > samples)
 		count = samples;
 
+	count = min_t(u8, count, BMC150_ACCEL_FIFO_LENGTH);
+
 	ret = bmc150_accel_fifo_transfer(data, (u8 *)buffer, count);
 	if (ret)
 		return ret;
author maintainer
#36 lore raw

PATCH 34/518 iio: accel: kxsd9: fix runtime PM imbalance on write_raw() error

In reply to Greg Kroah-Hartman

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

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

From: Biren Pandya <[email protected]>

commit 44a5fd874bb6873bdaec59f722c1d57832fbc9df upstream.

kxsd9_write_raw() takes a runtime PM reference with pm_runtime_get_sync() but returns -EINVAL directly when a scale with a non-zero integer part is requested, skipping the matching pm_runtime_put_autosuspend(). This leaks a runtime PM usage-counter reference on every such write, after which the device can no longer autosuspend.

Set the error code and fall through to the existing put instead of returning early.

Fixes 9a9a369d6178 ("iio: accel: kxsd9: Deploy system and runtime PM")
Assisted-by Claude:claude-opus-4-8 coccinelle
---
 drivers/iio/accel/kxsd9.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/iio/accel/kxsd9.c +3 -2
@@ -147,8 +147,9 @@ static int kxsd9_write_raw(struct iio_de
 	if (mask == IIO_CHAN_INFO_SCALE) {
 		/* Check no integer component */
 		if (val)
-			return -EINVAL;
-		ret = kxsd9_write_scale(indio_dev, val2);
+			ret = -EINVAL;
+		else
+			ret = kxsd9_write_scale(indio_dev, val2);
 	}
 
 	pm_runtime_put_autosuspend(st->dev);
author maintainer
#37 lore raw

PATCH 35/518 iio: adc: ad4062: add GPIOLIB dependency

In reply to Greg Kroah-Hartman

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

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

From: Arnd Bergmann <[email protected]>

commit a5b7991d5a737df71a5e4230554481255af64ed4 upstream.

The ad4062 driver gained support for the gpiochip and now fails to build when GPIOLIB is disabled:

390-linux-ld: drivers/iio/adc/ad4062.o: in function `ad4062_gpio_get':
drivers/iio/adc/ad4062.c:1383:(.text+0x3dc): undefined reference to gpiochip_get_data

Add a Kconfig dependency for this.

Fixes da1d3596b1e4 ("iio: adc: ad4062: Add GPIO Controller support")
---
 drivers/iio/adc/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/Kconfig +1 -0
@@ -78,6 +78,7 @@ config AD4030
 config AD4062
 	tristate "Analog Devices AD4062 Driver"
 	depends on I3C
+	depends on GPIOLIB
 	select REGMAP_I3C
 	select IIO_BUFFER
 	select IIO_TRIGGERED_BUFFER
author maintainer
#38 lore raw

PATCH 36/518 iio: adc: ad7380: select REGMAP

In reply to Greg Kroah-Hartman

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

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

From: Samuel Moelius <[email protected]>

commit 6697091b386a4e2830bdd38512c87a4befff2b32 upstream.

The AD7380 driver uses generic regmap types and APIs. However, its Kconfig entry does not select REGMAP.

As a result, AD7380 can be enabled from an allnoconfig-derived config with SPI_MASTER=y while REGMAP remains unset, causing ad7380.o to fail to build.

Fixes b095217c104b ("iio: adc: ad7380: new driver for AD7380 ADCs")
---
 drivers/iio/adc/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/Kconfig +1 -0
@@ -312,6 +312,7 @@ config AD7298
 config AD7380
 	tristate "Analog Devices AD7380 ADC driver"
 	depends on SPI_MASTER
+	select REGMAP
 	select SPI_OFFLOAD
 	select IIO_BUFFER
 	select IIO_BUFFER_DMAENGINE
author maintainer
#39 lore raw

PATCH 37/518 iio: adc: ad7768-1: Select GPIOLIB

In reply to Greg Kroah-Hartman

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

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

From: Jonathan Cameron <[email protected]>

commit 5a9c90350be4f6f175bdd193e8bd60a7aedfb4d2 upstream.

This driver provides a gpio chip a some related functions are not stubbed if GPIOLIB is not built.

ad7768-1.c:420: undefined reference to gpiochip_get_data' ad7768-1.c:498: undefined reference to devm_gpiochip_add_data_with_key'

Dual sign off reflects change of affiliation whilst this was under review.

---
 drivers/iio/adc/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/Kconfig +1 -0
@@ -416,6 +416,7 @@ config AD7766
 config AD7768_1
 	tristate "Analog Devices AD7768-1 ADC driver"
 	depends on SPI
+	select GPIOLIB
 	select REGULATOR
 	select REGMAP_SPI
 	select RATIONAL
author maintainer
#40 lore raw

PATCH 38/518 iio: adc: ad7779: add missing select IIO_TRIGGERED_BUFFER to Kconfig

In reply to Greg Kroah-Hartman

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

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

From: Joshua Crofts <[email protected]>

commit fd354554af1d2b33232ca6c8a3d79ed82413d715 upstream.

The Kconfig entry for the AD7779 is missing a
'select IIO_TRIGGERED_BUFFER' parameter, causing build failures.

Fixes c9a3f8c7bfcb ("drivers: iio: adc: add support for ad777x family")
---
 drivers/iio/adc/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/adc/Kconfig +1 -0
@@ -437,6 +437,7 @@ config AD7779
 	depends on SPI
 	select CRC8
 	select IIO_BUFFER
+	select IIO_TRIGGERED_BUFFER
 	select IIO_BACKEND
 	help
 	  Say yes here to build support for Analog Devices AD777X family
author maintainer
#41 lore raw

PATCH 39/518 iio: adc: ad_sigma_delta: fix clear_pending_event for registerless devices

In reply to Greg Kroah-Hartman

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

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

From: Radu Sabau <[email protected]>

commit 91bc6767a4f55dc470d8a56b55b9f2ea09094efe upstream.

ad_sigma_delta_clear_pending_event() falls through to the status register read path for devices with has_registers = false and no rdy_gpiod. For such devices, ad_sd_read_reg() skips the address byte entirely and clocks raw MISO bytes with no address phase — making it byte-for-byte identical to reading conversion data. If a pending conversion result is present, this partially consumes it and corrupts the data stream for the subsequent ad_sd_read_reg() call in ad_sigma_delta_single_conversion().

Furthermore, with num_resetclks = 0 on these devices, data_read_len evaluates to 0. If the clocked byte has bit 7 clear, pending_event is set and the code attempts memset(data + 2, 0xff, 0 - 1), overflowing to SIZE_MAX and corrupting the heap.

Fix by returning 0 immediately when neither rdy_gpiod nor has_registers is set. This is safe for all current registerless devices: ad7191 and ad7780 (with powerdown GPIO) are reset between conversions by CS deassertion, so there is no stale result to drain; ad7780 (without powerdown GPIO) and max11205 are continuously-converting and cycle ~DRDY at the output data rate regardless of whether the previous result was read, so the next falling edge fires naturally.

A future registerless device that holds ~DRDY asserted until data is read would be broken by this early return and would require either num_resetclks set or a rdy-gpio.

The same heap corruption is reachable on any device with rdy_gpiod set but num_resetclks = 0: if the GPIO indicates a pending event, the drain path executes memset(data + 2, 0xff, 0 - 1) regardless of has_registers. Add an explicit data_read_len == 0 guard after the pending event check; the stale result is then consumed by the first ad_sd_read_reg() call in ad_sigma_delta_single_conversion().

Fixes 132d44dc6966 ("iio: adc: ad_sigma_delta: Check for previous ready signals")
---
 drivers/iio/adc/ad_sigma_delta.c |   31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)
drivers/iio/adc/ad_sigma_delta.c +29 -2
@@ -262,11 +262,25 @@ static int ad_sigma_delta_clear_pending_
 
 	/*
 	 * Read R̅D̅Y̅ pin (if possible) or status register to check if there is an
-	 * old event.
+	 * old event. For devices with neither an RDY GPIO nor registers,
+	 * ad_sd_read_reg() transmits no address byte and clocks raw MISO bytes,
+	 * which is indistinguishable from reading conversion data and would
+	 * partially consume a pending result. Skip the check for such devices.
+	 *
+	 * This is safe for all current registerless devices: ad7191 and ad7780
+	 * (with powerdown GPIO) are reset between conversions by CS deassertion,
+	 * so there is no stale result to drain; ad7780 (without powerdown GPIO)
+	 * and max11205 are continuously-converting and cycle ~DRDY at the output
+	 * data rate regardless of whether the previous result was read, so the
+	 * next falling edge fires naturally.
+	 *
+	 * A future registerless device that holds ~DRDY asserted until data is
+	 * read would be broken by this early return and would need either
+	 * num_resetclks set or a rdy-gpio.
 	 */
 	if (sigma_delta->rdy_gpiod) {
 		pending_event = gpiod_get_value(sigma_delta->rdy_gpiod);
-	} else {
+	} else if (sigma_delta->info->has_registers) {
 		unsigned int status_reg;
 
 		ret = ad_sd_read_reg(sigma_delta, AD_SD_REG_STATUS, 1, &status_reg);
@@ -274,12 +288,25 @@ static int ad_sigma_delta_clear_pending_
 			return ret;
 
 		pending_event = !(status_reg & AD_SD_REG_STATUS_RDY);
+	} else {
+		return 0;
 	}
 
 	if (!pending_event)
 		return 0;
 
 	/*
+	 * With num_resetclks = 0, data_read_len is 0 and the drain sequence
+	 * below would compute memset(data + 2, 0xff, 0 - 1), underflowing to
+	 * SIZE_MAX and corrupting the heap. There is no safe way to drain the
+	 * stale result without knowing the data register size; it will be
+	 * consumed by the first ad_sd_read_reg() call in
+	 * ad_sigma_delta_single_conversion().
+	 */
+	if (!data_read_len)
+		return 0;
+
+	/*
 	 * In general the size of the data register is unknown. It varies from
 	 * device to device, might be one byte longer if CONTROL.DATA_STATUS is
 	 * set and even varies on some devices depending on which input is
author maintainer
#42 lore raw

PATCH 40/518 iio: adc: ad_sigma_delta: fix CS held asserted and state leaks

In reply to Greg Kroah-Hartman

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

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

From: Radu Sabau <[email protected]>

commit c72da0688575e5ef39c36bb44fed53aa18f8ae65 upstream.

In ad_sigma_delta_single_conversion(), set_mode(AD_SD_MODE_IDLE) and disable_one() were called from the out: block while keep_cs_asserted was still true. This caused any SPI transfer issued by those callbacks to carry cs_change=1, leaving CS permanently asserted after the conversion. Fix by moving both calls into the out_unlock: block, after keep_cs_asserted is cleared, matching the pattern already used in ad_sd_calibrate().

In the error path of ad_sd_buffer_postenable(), if an operation fails after set_mode(AD_SD_MODE_CONTINUOUS) has already succeeded (e.g. spi_offload_trigger_enable()), the device is left in continuous conversion mode with CS physically asserted. Additionally, bus_locked remaining true after spi_bus_unlock() causes subsequent SPI operations to call spi_sync_locked() without the bus lock actually held, allowing concurrent SPI access.

Fix the error path by clearing keep_cs_asserted first, then calling set_mode(AD_SD_MODE_IDLE) to revert the device mode and deassert CS, then clearing bus_locked before releasing the bus.

For devices that implement neither set_mode nor disable_one (such as MAX11205, which has no physical CS pin), no SPI transfer is issued during cleanup and the cs_change flag has no effect on any physical line.

Fixes 132d44dc6966 ("iio: adc: ad_sigma_delta: Check for previous ready signals")
---
 drivers/iio/adc/ad_sigma_delta.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/adc/ad_sigma_delta.c +5 -3
@@ -468,11 +468,10 @@ int ad_sigma_delta_single_conversion(str
 out:
 	ad_sd_disable_irq(sigma_delta);
 
-	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
-	ad_sigma_delta_disable_one(sigma_delta, chan->address);
-
 out_unlock:
 	sigma_delta->keep_cs_asserted = false;
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+	ad_sigma_delta_disable_one(sigma_delta, chan->address);
 	sigma_delta->bus_locked = false;
 	spi_bus_unlock(sigma_delta->spi->controller);
 out_release:
@@ -605,6 +604,9 @@ static int ad_sd_buffer_postenable(struc
 	return 0;
 
 err_unlock:
+	sigma_delta->keep_cs_asserted = false;
+	ad_sigma_delta_set_mode(sigma_delta, AD_SD_MODE_IDLE);
+	sigma_delta->bus_locked = false;
 	spi_bus_unlock(sigma_delta->spi->controller);
 	spi_unoptimize_message(&sigma_delta->sample_msg);
 
author maintainer
#43 lore raw

PATCH 41/518 iio: adc: lpc32xx: Initialize completion before requesting IRQ

In reply to Greg Kroah-Hartman

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

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

From: Maxwell Doose <[email protected]>

commit e561b35633f450ee607e87a6401d97f156a0cd54 upstream.

In the report from Jaeyoung Chung:

"lpc32xx_adc_probe() in drivers/iio/adc/lpc32xx_adc.c registers its interrupt handler with devm_request_irq() before it initializes st->completion with init_completion(). If an interrupt arrives after devm_request_irq() and before init_completion(), the handler calls complete() on an uninitialized completion, causing a kernel panic.

The probe path, in lpc32xx_adc_probe():

    iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); /* st kzalloc-zeroed */
    ...
    retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
                              LPC32XXAD_NAME, st);           /* register handler */
    ...
    init_completion(&st->completion);                       /* initialize completion */

lpc32xx_adc_isr() calls complete():

    complete(&st->completion);

If the device raises an interrupt before init_completion() runs, complete() acquires the uninitialized wait.lock and walks the zeroed task_list in swake_up_locked(). The zeroed task_list makes list_empty() return false, so swake_up_locked() dereferences a NULL list entry, triggering a KASAN wild-memory-access."

Fix the chance of a spurious IRQ causing an uninitialized pointer dereference by moving init_completion() above devm_request_irq().

---
 drivers/iio/adc/lpc32xx_adc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/adc/lpc32xx_adc.c +2 -2
@@ -179,6 +179,8 @@ static int lpc32xx_adc_probe(struct plat
 	if (irq < 0)
 		return irq;
 
+	init_completion(&st->completion);
+
 	retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
 				  LPC32XXAD_NAME, st);
 	if (retval < 0) {
@@ -197,8 +199,6 @@ static int lpc32xx_adc_probe(struct plat
 
 	platform_set_drvdata(pdev, iodev);
 
-	init_completion(&st->completion);
-
 	iodev->name = LPC32XXAD_NAME;
 	iodev->info = &lpc32xx_adc_iio_info;
 	iodev->modes = INDIO_DIRECT_MODE;
author maintainer
#44 lore raw

PATCH 42/518 iio: adc: nxp-sar-adc: Fix the delay calculation in nxp_sar_adc_wait_for()

In reply to Greg Kroah-Hartman

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

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

From: Andy Shevchenko <[email protected]>

commit a9f41809bf1bd8e5c1bc4b6a1052adac58eb7ab6 upstream.

The original code was using ndelay() twice. In one case the delay is calculated as 1/3 of ADC clock and in the other as 80 ADC clocks. But according to the comments in all cases it should be a multiplier of the ADC clock, and not a fraction of it. Inadvertently nxp_sar_adc_wait_for() takes the wrong case and spread it over the code make it wrong in all places. Fix this by modifying a helper to correctly use the multiplier.

Fixes 7e5c0f97c66a ("iio: adc: nxp-sar-adc: Avoid division by zero")
Fixes 4434072a893e ("iio: adc: Add the NXP SAR ADC support for the s32g2/3 platforms")
---
 drivers/iio/adc/nxp-sar-adc.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/adc/nxp-sar-adc.c +2 -2
@@ -198,13 +198,13 @@ static void nxp_sar_adc_irq_cfg(struct n
 		writel(0, NXP_SAR_ADC_IMR(info->regs));
 }
 
-static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, unsigned int cycles)
+static void nxp_sar_adc_wait_for(struct nxp_sar_adc *info, u64 cycles)
 {
 	u64 rate;
 
 	rate = clk_get_rate(info->clk);
 	if (rate)
-		ndelay(div64_u64(NSEC_PER_SEC, rate * cycles));
+		ndelay(div64_u64(NSEC_PER_SEC * cycles, rate));
 }
 
 static bool nxp_sar_adc_set_enabled(struct nxp_sar_adc *info, bool enable)
author maintainer
#45 lore raw

PATCH 43/518 iio: adc: spear: Initialize completion before requesting IRQ

In reply to Greg Kroah-Hartman

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

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

From: Maxwell Doose <[email protected]>

commit 3ee2128b6f0eb0be7b6cb8f6e0f1f113a65201a0 upstream.

In the report from Jaeyoung Chung:

"spear_adc_probe() in drivers/iio/adc/spear_adc.c registers its interrupt handler with devm_request_irq() before it initializes st->completion with init_completion(). If an interrupt arrives after devm_request_irq() and before init_completion(), the handler calls complete() on an uninitialized completion, causing a kernel panic.

The probe path, in spear_adc_probe():

    iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*st)); /* st kzalloc-zeroed */
    ...
    retval = devm_request_irq(&pdev->dev, irq, spear_adc_isr, 0,
                              LPC32XXAD_NAME, st);           /* register handler */
    ...
    init_completion(&st->completion);                       /* initialize completion */

spear_adc_isr() calls complete():

    complete(&st->completion);

If the device raises an interrupt before init_completion() runs, complete() acquires the uninitialized wait.lock and walks the zeroed task_list in swake_up_locked(). The zeroed task_list makes list_empty() return false, so swake_up_locked() dereferences a NULL list entry, triggering a KASAN wild-memory-access."

Fix the chance of a spurious IRQ causing an uninitialized pointer dereference by moving init_completion() above devm_request_irq().

---
 drivers/iio/adc/spear_adc.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iio/adc/spear_adc.c +1 -2
@@ -280,6 +280,7 @@ static int spear_adc_probe(struct platfo
 	st = iio_priv(indio_dev);
 	st->dev = dev;
 
+	init_completion(&st->completion);
 	mutex_init(&st->lock);
 
 	/*
@@ -326,8 +327,6 @@ static int spear_adc_probe(struct platfo
 
 	spear_adc_configure(st);
 
-	init_completion(&st->completion);
-
 	indio_dev->name = SPEAR_ADC_MOD_NAME;
 	indio_dev->info = &spear_adc_info;
 	indio_dev->modes = INDIO_DIRECT_MODE;
author maintainer
#46 lore raw

PATCH 44/518 iio: adc: ti-ads1119: fix PM reference leak in buffer preenable

In reply to Greg Kroah-Hartman

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

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

From: Guangshuo Li <[email protected]>

commit adf4bc07f814da8329278d32600147f5a150938c upstream.

ads1119_triggered_buffer_preenable() resumes the device with pm_runtime_resume_and_get() before starting a conversion.

If i2c_smbus_write_byte() fails, the function returns the error directly and leaves the runtime PM usage counter elevated. The matching postdisable callback is not called when preenable fails, so the reference is leaked and the device may remain runtime-active indefinitely.

Store the I2C transfer result in ret and drop the runtime PM reference on failure before returning the error.

Fixes a9306887eba41 ("iio: adc: ti-ads1119: Add driver")
---
 drivers/iio/adc/ti-ads1119.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/iio/adc/ti-ads1119.c +5 -1
@@ -459,7 +459,11 @@ static int ads1119_triggered_buffer_pree
 	if (ret)
 		return ret;
 
-	return i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
+	ret = i2c_smbus_write_byte(st->client, ADS1119_CMD_START_SYNC);
+	if (ret)
+		pm_runtime_put_autosuspend(dev);
+
+	return ret;
 }
 
 static int ads1119_triggered_buffer_postdisable(struct iio_dev *indio_dev)
author maintainer
#47 lore raw

PATCH 45/518 iio: adc: ti-ads124s08: Return reset GPIO lookup errors

In reply to Greg Kroah-Hartman

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

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

From: Pengpeng Hou <[email protected]>

commit 7dc4de2aa6316f1d044cde21f5acfec5f3ec6b47 upstream.

devm_gpiod_get_optional() returns NULL when the optional GPIO is absent, but returns an ERR_PTR when the GPIO provider lookup fails, including probe deferral.

Probe currently logs the ERR_PTR case as if the reset GPIO were simply absent and keeps the error pointer in reset_gpio. Later ads124s_reset() treats any non-NULL reset_gpio as a valid descriptor and passes it to gpiod_set_value_cansleep().

Return the lookup error instead of retaining the ERR_PTR.

---
 drivers/iio/adc/ti-ads124s08.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/adc/ti-ads124s08.c +2 -1
@@ -321,7 +321,8 @@ static int ads124s_probe(struct spi_devi
 	ads124s_priv->reset_gpio = devm_gpiod_get_optional(&spi->dev,
 						   "reset", GPIOD_OUT_LOW);
 	if (IS_ERR(ads124s_priv->reset_gpio))
-		dev_info(&spi->dev, "Reset GPIO not defined\n");
+		return dev_err_probe(&spi->dev, PTR_ERR(ads124s_priv->reset_gpio),
+				     "Failed to get reset GPIO\n");
 
 	ads124s_priv->chip_info = &ads124s_chip_info_tbl[spi_id->driver_data];
 
author maintainer
#48 lore raw

PATCH 46/518 iio: backend: fix uninitialized data in debugfs

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

commit a6e8b14a4897d0b6df9744f33d0a30e6b92368eb upstream.

If the *ppos value is non-zero then simple_write_to_buffer() will not initialize the start of the buf[] buffer. Non-zero ppos values aren't going to work at all. Check for that at the start of the function and return -ENOSPC.

Fixes cdf01e0809a4 ("iio: backend: add debugFs interface")
---
 drivers/iio/industrialio-backend.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/industrialio-backend.c +1 -1
@@ -156,7 +156,7 @@ static ssize_t iio_backend_debugfs_write
 	ssize_t rc;
 	int ret;
 
-	if (count >= sizeof(buf))
+	if (*ppos != 0 || count >= sizeof(buf))
 		return -ENOSPC;
 
 	rc = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf, count);
author maintainer
#49 lore raw

PATCH 47/518 iio: buffer: hw-consumer: free scan_mask on buffer release

In reply to Greg Kroah-Hartman

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

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

From: Felix Gu <[email protected]>

commit 6325d6e2204327965b849c0a16efb6ac9202e5a8 upstream.

The scan_mask lifetime changed in commit 9a2e1233d38c ("iio: buffer:
hw-consumer: remove redundant scan_mask flexible array").

Before that change, the scan mask storage was embedded in struct hw_consumer_buffer, so iio_hw_buf_release() could free the whole allocation with a single kfree(hw_buf).

That commit moved the scan mask to a separate bitmap_zalloc() allocation stored in buffer.scan_mask, but left iio_hw_buf_release() unchanged.

Free the scan mask in iio_hw_buf_release() before freeing the buffer wrapper.

Fixes 9a2e1233d38c ("iio: buffer: hw-consumer: remove redundant scan_mask flexible array")
---
 drivers/iio/buffer/industrialio-hw-consumer.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/iio/buffer/industrialio-hw-consumer.c +2 -0
index 700528c9a0a4..10e912bbf0c5 100644
@@ -40,6 +40,8 @@ static void iio_hw_buf_release(struct iio_buffer *buffer)
 {
 	struct hw_consumer_buffer *hw_buf =
 		iio_buffer_to_hw_consumer_buffer(buffer);
+
+	bitmap_free(buffer->scan_mask);
 	kfree(hw_buf);
 }
 
Signature · 1 line
2.55.0
author maintainer
#50 lore raw

PATCH 48/518 iio: chemical: scd30: Cleanup initializations and fix sign-extension bug

In reply to Greg Kroah-Hartman

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

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

From: Maxwell Doose <[email protected]>

commit 60d877910a43c305b5165131b258a17b1d772d57 upstream.

Include linux/bitfield.h for FIELD_GET().

Create new macros for bit manipulation in combination with manual bit manipulation being replaced with FIELD_GET().

The current variable declaration and initializations are barely readable and use comma separations across multiple lines. Refactor the initializations so that mantissa and exp have separate declarations and sign gets initialized later.

In addition (and due to the nature of the cleanup), fix a sign-extension bug where, float32 would get bitwise anded with ~BIT(31) (which is 0xFFFFFFFF7FFFFFFF) which corrupted the exponent.

---
 drivers/iio/chemical/scd30_core.c |   19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
drivers/iio/chemical/scd30_core.c +15 -4
@@ -4,6 +4,8 @@
  *
  * Copyright (c) 2020 Tomasz Duszynski <[email protected]>
  */
+
+#include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/cleanup.h>
 #include <linux/completion.h>
@@ -43,6 +45,11 @@
 #define SCD30_TEMP_OFFSET_MAX 655360
 #define SCD30_EXTRA_TIMEOUT_PER_S 250
 
+/* Floating point arithmetic macros */
+#define SCD30_FLOAT_MANTISSA_MSK GENMASK(22, 0)
+#define SCD30_FLOAT_EXP_MSK GENMASK(30, 23)
+#define SCD30_FLOAT_SIGN_MSK BIT(31)
+
 enum {
 	SCD30_CONC,
 	SCD30_TEMP,
@@ -89,10 +96,14 @@ static int scd30_reset(struct scd30_stat
 /* simplified float to fixed point conversion with a scaling factor of 0.01 */
 static int scd30_float_to_fp(int float32)
 {
-	int fraction, shift,
-	    mantissa = float32 & GENMASK(22, 0),
-	    sign = (float32 & BIT(31)) ? -1 : 1,
-	    exp = (float32 & ~BIT(31)) >> 23;
+	int fraction, shift, sign;
+	int mantissa = FIELD_GET(SCD30_FLOAT_MANTISSA_MSK, float32);
+	int exp = FIELD_GET(SCD30_FLOAT_EXP_MSK, float32);
+
+	if (float32 & SCD30_FLOAT_SIGN_MSK)
+		sign = -1;
+	else
+		sign = 1;
 
 	/* special case 0 */
 	if (!exp && !mantissa)
author maintainer
#51 lore raw

PATCH 49/518 iio: common: st_sensors: honour channel endianness in read_axis_data

In reply to Greg Kroah-Hartman

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

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

From: Herman van Hazendonk <[email protected]>

commit 55052184ac9011db2ea983e54d6c21f0b1079a12 upstream.

st_sensors_read_axis_data() unconditionally decoded multi-byte results with get_unaligned_le16() / get_unaligned_le24() regardless of the channel's declared scan_type.endianness.

For every ST sensor that has used this helper since it was introduced this happened to be fine because the ST IMU/accel/gyro/pressure families publish their data registers as little-endian and the channel specs in those drivers declare IIO_LE accordingly.

The LSM303DLH magnetometer however publishes its X/Y/Z output as a pair of big-endian bytes (the H register sits at the lower address, 0x03/0x05/0x07, and the L register immediately after), and its channel specs in st_magn_core.c correctly declare IIO_BE -- but read_axis_data() ignored that and decoded as little-endian, swapping the high and low bytes of every magnetometer sample. The LSM303DLHC and LSM303DLM share the same st_magn_16bit_channels (IIO_BE) and were therefore byte-swapped by the same bug; users of those parts will see different in_magn_*_raw values after this fix lands.

The bug is most visible on a stationary chip: in earth's field the true X reading is small and the high byte sits at 0x00, so swapping the bytes pins sysfs X at exactly the low byte's pattern (e.g. 0x00F0 = 240). Y and Z still appear "to vary" because their magnitudes are larger and the noise in the low byte produces big swings in the swapped high byte:

before (LSM303DLH flat, sysfs in_magn_*_raw):

      X=240 (stuck), Y= 12032..23296, Z=-16128..-9728

after (direct i2c-dev big-endian decode, same chip same orientation):
X≈-4096, Y≈210, Z≈80 (sensible values reflecting earth's
ambient field at low gauss range)

Fix read_axis_data() to dispatch on ch->scan_type.endianness and call get_unaligned_be16() / get_unaligned_be24() when the channel declares IIO_BE. Existing IIO_LE consumers (st_accel, st_gyro, st_pressure, st_lsm6dsx and others) are unaffected because their channel specs already declare IIO_LE and the LE path is unchanged.

While restructuring the branches, replace the previously implicit silent-success-with-uninitialised-*data fall-through for byte_for_channel outside 1..3 with an explicit return -EINVAL. No in-tree ST sensor publishes such a channel, but the new behaviour is strictly safer than handing userspace garbage.

Fixes 23491b513bcd ("iio:common: Add STMicroelectronics common library")
Assisted-by Claude:claude-opus-4-7 sparse smatch clang-analyzer coccinelle checkpatch
Assisted-by Sashiko:claude-opus-4-7
---
 drivers/iio/common/st_sensors/st_sensors_core.c |   23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
drivers/iio/common/st_sensors/st_sensors_core.c +17 -6
@@ -498,6 +498,7 @@ static int st_sensors_read_axis_data(str
 	u8 *outdata;
 	struct st_sensor_data *sdata = iio_priv(indio_dev);
 	unsigned int byte_for_channel;
+	u32 tmp;
 
 	byte_for_channel = DIV_ROUND_UP(ch->scan_type.realbits +
 					ch->scan_type.shift, 8);
@@ -508,12 +509,22 @@ static int st_sensors_read_axis_data(str
 	if (err < 0)
 		return err;
 
-	if (byte_for_channel == 1)
-		*data = (s8)*outdata;
-	else if (byte_for_channel == 2)
-		*data = (s16)get_unaligned_le16(outdata);
-	else if (byte_for_channel == 3)
-		*data = (s32)sign_extend32(get_unaligned_le24(outdata), 23);
+	if (byte_for_channel == 1) {
+		tmp = *outdata;
+	} else if (byte_for_channel == 2) {
+		if (ch->scan_type.endianness == IIO_BE)
+			tmp = get_unaligned_be16(outdata);
+		else
+			tmp = get_unaligned_le16(outdata);
+	} else if (byte_for_channel == 3) {
+		if (ch->scan_type.endianness == IIO_BE)
+			tmp = get_unaligned_be24(outdata);
+		else
+			tmp = get_unaligned_le24(outdata);
+	} else {
+		return -EINVAL;
+	}
+	*data = sign_extend32(tmp, BYTES_TO_BITS(byte_for_channel) - 1);
 
 	return 0;
 }
author maintainer
#52 lore raw

PATCH 50/518 iio: core: fix uninitialized data in debugfs

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

commit ab92ed206d41fd171ebd37bc46360d9f2140d043 upstream.

If *ppos is non-zero then simple_write_to_buffer() will not initialize the start of buf[]. Non zero values for *ppos aren't going to work anyway. Test for them at the start of the function and return -EINVAL.

Fixes 6d5dd486c715 ("iio: core: make use of simple_write_to_buffer()")
---
 drivers/iio/industrialio-core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/industrialio-core.c +1 -1
@@ -418,7 +418,7 @@ static ssize_t iio_debugfs_write_reg(str
 	char buf[80];
 	int ret;
 
-	if (count >= sizeof(buf))
+	if (*ppos != 0 || count >= sizeof(buf))
 		return -EINVAL;
 
 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
author maintainer
#53 lore raw

PATCH 51/518 iio: dac: ad3552r-hs: fix uninitialized data ni ad3552r_hs_write_data_source()

In reply to Greg Kroah-Hartman

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

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

From: Dan Carpenter <[email protected]>

commit eaaa7eef181892ef7ba56c6295b81f0ae4492c13 upstream.

If the *ppos value is non-zero then the simple_write_to_buffer() function won't initialized the start of the buf[] buffer. Non-zero values for *ppos won't work here generally, so just test for them and return -ENOSPC at the start of the function.

Fixes b1c5d68ea66e ("iio: dac: ad3552r-hs: add support for internal ramp")
---
 drivers/iio/dac/ad3552r-hs.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/dac/ad3552r-hs.c +1 -1
@@ -549,7 +549,7 @@ static ssize_t ad3552r_hs_write_data_sou
 
 	guard(mutex)(&st->lock);
 
-	if (count >= sizeof(buf))
+	if (*ppos != 0 || count >= sizeof(buf))
 		return -ENOSPC;
 
 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, ppos, userbuf,
author maintainer
#54 lore raw

PATCH 52/518 iio: event: Fix event FIFO reset race

In reply to Greg Kroah-Hartman

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

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

From: Lars-Peter Clausen <[email protected]>

commit af791d295737ea6b6ff2c8d8488462a49c14af01 upstream.

iio_event_getfd() creates the event file descriptor with anon_inode_getfd(), which allocates a new fd, creates the anonymous file and installs it in the process fd table before returning to the caller.

The IIO code resets the event FIFO after anon_inode_getfd() has returned, but before IIO_GET_EVENT_FD_IOCTL has copied the fd number to userspace. But since fd tables are shared between threads, another thread can guess the newly allocated fd number and issue a read() on it as soon as the fd has been installed.

This means the kfifo_to_user() in iio_event_chrdev_read() can run in parallel with the kfifo_reset_out() in iio_event_getfd().

The kfifo documentation says that kfifo_reset_out() is only safe when it is called from the reader thread and there is only one concurrent reader. Otherwise it is dangerous and must be handled in the same way as kfifo_reset().

If that happens, kfifo_to_user() can advance the FIFO out index based on state from before the reset, after the reset has already moved the out index to the current in index. That can leave the FIFO with an out index past the in index. A later read() can then see an underflowed FIFO length and copy more data than the event FIFO buffer contains. This can result in an out-of-bounds read and leak adjacent kernel memory to userspace.

Move the FIFO reset before anon_inode_getfd(). At that point the event fd is marked busy, but the new fd has not been installed yet, so userspace cannot access it while the FIFO is reset.

Fixes b91accafbb10 ("iio:event: Fix and cleanup locking")
Reported-by Codex:gpt-5.5
---
 drivers/iio/industrialio-event.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/iio/industrialio-event.c +2 -3
@@ -207,6 +207,8 @@ static int iio_event_getfd(struct iio_de
 		goto unlock;
 	}
 
+	kfifo_reset_out(&ev_int->det_events);
+
 	iio_device_get(indio_dev);
 
 	fd = anon_inode_getfd("iio:event", &iio_event_chrdev_fileops,
@@ -214,10 +216,7 @@ static int iio_event_getfd(struct iio_de
 	if (fd < 0) {
 		clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
 		iio_device_put(indio_dev);
-	} else {
-		kfifo_reset_out(&ev_int->det_events);
 	}
-
 unlock:
 	mutex_unlock(&iio_dev_opaque->mlock);
 	return fd;
author maintainer
#55 lore raw

PATCH 53/518 iio: gyro: bmg160: bail out when bandwidth/filter is not in table

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit 8320c77e67382d5d55d77043a5f60a867d408a2b upstream.

bmg160_get_filter() walks bmg160_samp_freq_table[] looking for the entry matching the bw_bits value read from the chip:

	for (i = 0; i < ARRAY_SIZE(bmg160_samp_freq_table); ++i) {
		if (bmg160_samp_freq_table[i].bw_bits == bw_bits)
			break;
	}
	*val = bmg160_samp_freq_table[i].filter;

If no entry matches, i ends up equal to the array size and the next line reads one slot past the end. bmg160_set_filter() has the same shape, driven by 'val' instead of bw_bits.

smatch flags both:

drivers/iio/gyro/bmg160_core.c:204 bmg160_get_filter() error:
buffer overflow 'bmg160_samp_freq_table' 7 <= 7 drivers/iio/gyro/bmg160_core.c:222 bmg160_set_filter() error:
buffer overflow 'bmg160_samp_freq_table' 7 <= 7

Return -EINVAL when no entry matches.

The set_filter() path is reachable from userspace via the sysfs in_anglvel_filter_low_pass_3db_frequency interface, so userspace can trivially trigger the out-of-bounds read with a value that is not in bmg160_samp_freq_table[].filter.

Fixes 22b46c45fb9b ("iio:gyro:bmg160 Gyro Sensor driver")
---
 drivers/iio/gyro/bmg160_core.c |    6 ++++++
 1 file changed, 6 insertions(+)
drivers/iio/gyro/bmg160_core.c +6 -0
@@ -201,6 +201,9 @@ static int bmg160_get_filter(struct bmg1
 			break;
 	}
 
+	if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+		return -EINVAL;
+
 	*val = bmg160_samp_freq_table[i].filter;
 
 	return ret ? ret : IIO_VAL_INT;
@@ -218,6 +221,9 @@ static int bmg160_set_filter(struct bmg1
 			break;
 	}
 
+	if (i == ARRAY_SIZE(bmg160_samp_freq_table))
+		return -EINVAL;
+
 	ret = regmap_write(data->regmap, BMG160_REG_PMU_BW,
 			   bmg160_samp_freq_table[i].bw_bits);
 	if (ret < 0) {
author maintainer
#56 lore raw

PATCH 54/518 iio: gyro: bmg160: wait full startup time after mode change at probe

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit 088fcb9b567f8723074ad9eb1bf5cb46f8a0096b upstream.

bmg160_chip_init() calls bmg160_set_mode(BMG160_MODE_NORMAL) and then waits only 500-1000 us. Per the BMG160 datasheet (BST-BMG160-DS000-07 Rev. 1.0, May 2013), the start-up and wake-up times (tsu, twusm) are 30 ms.

The same file already waits BMG160_MAX_STARTUP_TIME_MS (80 ms) in bmg160_runtime_resume() after the same set_mode(NORMAL) operation. The 500 us value at probe was likely a unit mix-up; the old comment said "500 ms" while the code used microseconds.

Reuse the same constant via msleep() and add a code comment explaining the datasheet basis for the wait. Without this, register writes that follow the mode change can hit the chip before it is ready.

Fixes 22b46c45fb9b ("iio:gyro:bmg160 Gyro Sensor driver")
---
 drivers/iio/gyro/bmg160_core.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)
drivers/iio/gyro/bmg160_core.c +8 -2
@@ -264,8 +264,14 @@ static int bmg160_chip_init(struct bmg16
 	if (ret < 0)
 		return ret;
 
-	/* Wait upto 500 ms to be ready after changing mode */
-	usleep_range(500, 1000);
+	/*
+	 * Wait for the chip to be ready after switching to normal mode.
+	 * The BMG160 datasheet (BST-BMG160-DS000-07 Rev. 1.0, May 2013)
+	 * specifies a start-up / wake-up time (tsu, twusm) of 30 ms; use
+	 * BMG160_MAX_STARTUP_TIME_MS (80 ms) as a safety margin, matching
+	 * what bmg160_runtime_resume() already does.
+	 */
+	msleep(BMG160_MAX_STARTUP_TIME_MS);
 
 	/* Set Bandwidth */
 	ret = bmg160_set_bw(data, BMG160_DEF_BW);
author maintainer
#57 lore raw

PATCH 55/518 iio: imu: adis: add IRQF_NO_THREAD to non-FIFO trigger IRQ

In reply to Greg Kroah-Hartman

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

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

From: Runyu Xiao <[email protected]>

commit 6e1b9bff1202da55c464e36bd34a2b6863d7fe30 upstream.

devm_adis_probe_trigger() registers iio_trigger_generic_data_rdy_poll() through devm_request_irq() on the non-FIFO path, but it does not add IRQF_NO_THREAD to the IRQ flags.

When the kernel is booted with forced IRQ threading, the parent IRQ can otherwise be threaded by the IRQ core and the subsequent IIO trigger child IRQ is then dispatched from irq/... thread context instead of hardirq context. Because iio_trigger_generic_data_rdy_poll() immediately drives iio_trigger_poll(), this violates the hardirq-only IIO trigger helper contract and can push downstream trigger consumers through the wrong execution context.

Add IRQF_NO_THREAD on top of the existing adis->irq_flag value for the non-FIFO request_irq() path, while preserving the current trigger polarity and IRQF_NO_AUTOEN behavior.

Fixes fec86c6b8369 ("iio: imu: adis: Add Managed device functions")
---
 drivers/iio/imu/adis_trigger.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/imu/adis_trigger.c +1 -1
@@ -94,7 +94,7 @@ int devm_adis_probe_trigger(struct adis
 	else
 		ret = devm_request_irq(&adis->spi->dev, adis->spi->irq,
 				       &iio_trigger_generic_data_rdy_poll,
-				       adis->irq_flag,
+				       adis->irq_flag | IRQF_NO_THREAD,
 				       indio_dev->name,
 				       adis->trig);
 	if (ret)
author maintainer
#58 lore raw

PATCH 56/518 iio: imu: bmi160: add IRQF_NO_THREAD to data-ready trigger IRQ

In reply to Greg Kroah-Hartman

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

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

From: Runyu Xiao <[email protected]>

commit cd5a6a5096b246e10600da3ac47a1274ce9573c8 upstream.

bmi160_probe_trigger() registers iio_trigger_generic_data_rdy_poll() through devm_request_irq(), but it passes only irq_type and does not add IRQF_NO_THREAD.

When the kernel is booted with forced IRQ threading, the parent IRQ can otherwise be threaded by the IRQ core and the subsequent IIO trigger child IRQ is dispatched from irq/... thread context instead of hardirq context. Because the handler immediately pushes the event into iio_trigger_poll(), this violates the hardirq-only IIO trigger helper contract and can drive downstream trigger consumers through the wrong execution context.

Add IRQF_NO_THREAD on top of irq_type when registering the BMI160 data- ready trigger handler.

Fixes 895bf81e6bbf ("iio:bmi160: add drdy interrupt support")
---
 drivers/iio/imu/bmi160/bmi160_core.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/iio/imu/bmi160/bmi160_core.c +2 -1
@@ -788,7 +788,8 @@ int bmi160_probe_trigger(struct iio_dev
 
 	ret = devm_request_irq(&indio_dev->dev, irq,
 			       &iio_trigger_generic_data_rdy_poll,
-			       irq_type, "bmi160", data->trig);
+			       irq_type | IRQF_NO_THREAD,
+			       "bmi160", data->trig);
 	if (ret)
 		return ret;
 
author maintainer
#59 lore raw

PATCH 57/518 iio: imu: inv_icm42600: fix timestamp clock period by using lower value

In reply to Greg Kroah-Hartman

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

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

From: Jean-Baptiste Maneyrol <[email protected]>

commit 8b0b864c11a2e2ada470f9d5010e1c2bf1eceef2 upstream.

Clock period value is used for computing periods of sampling. There is no need for it to be higher than the maximum odr, otherwise we are losing precision in the computation for nothing.

Switch clock period value to maximum odr period (8kHz).

Fixes 0ecc363ccea7 ("iio: make invensense timestamp module generic")
---
 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c |    4 ++--
 drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c  |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +2 -2
@@ -1170,10 +1170,10 @@ struct iio_dev *inv_icm42600_accel_init(
 	accel_st->filter = INV_ICM42600_FILTER_AVG_16X;
 
 	/*
-	 * clock period is 32kHz (31250ns)
+	 * clock period is 8kHz (125000ns)
 	 * jitter is +/- 2% (20 per mille)
 	 */
-	ts_chip.clock_period = 31250;
+	ts_chip.clock_period = 125000;
 	ts_chip.jitter = 20;
 	ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
 	inv_sensors_timestamp_init(&accel_st->ts, &ts_chip);
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +2 -2
@@ -755,10 +755,10 @@ struct iio_dev *inv_icm42600_gyro_init(s
 	}
 
 	/*
-	 * clock period is 32kHz (31250ns)
+	 * clock period is 8kHz (125000ns)
 	 * jitter is +/- 2% (20 per mille)
 	 */
-	ts_chip.clock_period = 31250;
+	ts_chip.clock_period = 125000;
 	ts_chip.jitter = 20;
 	ts_chip.init_period = inv_icm42600_odr_to_period(st->conf.accel.odr);
 	inv_sensors_timestamp_init(&gyro_st->ts, &ts_chip);
author maintainer
#60 lore raw

PATCH 58/518 iio: imu: inv_icm42600: fix timestamping by limiting FIFO reading

In reply to Greg Kroah-Hartman

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

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

From: Jean-Baptiste Maneyrol <[email protected]>

commit affe3f077d7a4eeb25937f5323ff059a54b4712c upstream.

Timestamps are made by measuring the chip clock using the watermark interrupts. If we read more than watermark samples as done today, we are reducing the period between interrupts and distort the time measurement. Fix that by reading only watermark samples in the interrupt case.

Fixes 7f85e42a6c54 ("iio: imu: inv_icm42600: add buffer support in iio devices")
---
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c |    9 +++++----
 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h |    1 +
 2 files changed, 6 insertions(+), 4 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +5 -4
@@ -248,6 +248,7 @@ int inv_icm42600_buffer_update_watermark
 
 	/* compute watermark value in bytes */
 	wm_size = watermark * packet_size;
+	st->fifo.watermark.value = watermark;
 
 	/* changing FIFO watermark requires to turn off watermark interrupt */
 	ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0,
@@ -454,11 +455,10 @@ int inv_icm42600_buffer_fifo_read(struct
 	st->fifo.nb.accel = 0;
 	st->fifo.nb.total = 0;
 
-	/* compute maximum FIFO read size */
+	/* compute maximum FIFO read size (watermark for max = 0 interrupt case) */
 	if (max == 0)
-		max_count = sizeof(st->fifo.data);
-	else
-		max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
+		max = st->fifo.watermark.value;
+	max_count = max * inv_icm42600_get_packet_size(st->fifo.en);
 
 	/* read FIFO count value */
 	raw_fifo_count = (__be16 *)st->buffer;
@@ -574,6 +574,7 @@ int inv_icm42600_buffer_init(struct inv_
 
 	st->fifo.watermark.eff_gyro = 1;
 	st->fifo.watermark.eff_accel = 1;
+	st->fifo.watermark.value = 1;
 
 	/*
 	 * Default FIFO configuration (bits 7 to 5)
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h +1 -0
@@ -34,6 +34,7 @@ struct inv_icm42600_fifo {
 		unsigned int accel;
 		unsigned int eff_gyro;
 		unsigned int eff_accel;
+		unsigned int value;
 	} watermark;
 	size_t count;
 	struct {
author maintainer
#61 lore raw

PATCH 59/518 iio: imu: st_lsm6dsx: deselect shub page before reading whoami

In reply to Greg Kroah-Hartman

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

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

From: Andreas Kempe <[email protected]>

commit aede83625ff5d9539508582036df30c809d51058 upstream.

As part of driver initialization, e.g. st_lsm6dsx_init_shub() selects the shub register page using st_lsm6dsx_set_page(). Selecting the shub register page shadows the regular register space so whoami, among other registers, is no longer accessible.

In applications where the IMU is permanently powered separately from the processor, there is a window where a reset of the CPU leaves the IMU in the shub register page. Once this occurs, any subsequent probe attempt fails because of the register shadowing.

Using the ism330dlc, the error typically looks like

    st_lsm6dsx_i2c 3-006a: unsupported whoami [10]

with the unknown whoami read from a reserved register in the shub page.

The reset register is also shadowed by the page select, preventing a reset from recovering the chip.

Unconditionally clear the shub page before the whoami readout to ensure normal register access and allow the initialization to proceed.

Place the fix in st_lsm6dsx_check_whoami() before the whoami check because hw->settings, which st_lsm6dsx_set_page() relies on, is first assigned in that function.

Placing the fix in a more logical place than the whoami check would require a bigger restructuring of the code.

Fixes c91c1c844ebd ("iio: imu: st_lsm6dsx: add i2c embedded controller support")
---
 drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c |   21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +20 -1
@@ -1660,6 +1660,26 @@ static int st_lsm6dsx_check_whoami(struc
 		return -ENODEV;
 	}
 
+	hw->settings = &st_lsm6dsx_sensor_settings[i];
+
+	if (hw->settings->shub_settings.page_mux.addr) {
+		/*
+		 * If the IMU has the shub page selected on init, for example
+		 * after a CPU watchdog reset while the page is selected, the
+		 * regular register space is shadowed. While the regular
+		 * register space is shadowed, the registers needed for
+		 * initializing the IMU are not available.
+		 *
+		 * Unconditionally clear the shub page selection to ensure
+		 * normal register access.
+		 */
+		err = st_lsm6dsx_set_page(hw, false);
+		if (err < 0) {
+			dev_err(hw->dev, "failed to clear shub page\n");
+			return err;
+		}
+	}
+
 	err = regmap_read(hw->regmap, ST_LSM6DSX_REG_WHOAMI_ADDR, &data);
 	if (err < 0) {
 		dev_err(hw->dev, "failed to read whoami register\n");
@@ -1672,7 +1692,6 @@ static int st_lsm6dsx_check_whoami(struc
 	}
 
 	*name = st_lsm6dsx_sensor_settings[i].id[j].name;
-	hw->settings = &st_lsm6dsx_sensor_settings[i];
 
 	return 0;
 }
author maintainer
#62 lore raw

PATCH 60/518 iio: light: al3000a: add missing REGMAP_I2C to Kconfig

In reply to Greg Kroah-Hartman

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

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

From: Joshua Crofts <[email protected]>

commit a2d30022b7c316ad845d1b696e724058b88e5a4e upstream.

The KConfig entry for the al3000a is missing a select REGMAP_I2C, causing build failures.

Fixes d531b9f78949 ("iio: light: Add support for AL3000a illuminance sensor")
---
 drivers/iio/light/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/light/Kconfig +1 -0
@@ -45,6 +45,7 @@ config ADUX1020
 
 config AL3000A
 	tristate "AL3000a ambient light sensor"
+	select REGMAP_I2C
 	depends on I2C
 	help
 	  Say Y here if you want to build a driver for the Dyna Image AL3000a
author maintainer
#63 lore raw

PATCH 61/518 iio: light: al3010: add missing REGMAP_I2C to Kconfig

In reply to Greg Kroah-Hartman

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

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

From: Joshua Crofts <[email protected]>

commit 84486e3bbda18a2df1ed74ca78e1e14bde9a941b upstream.

The KConfig entry for the AL3010 is missing a select REGMAP_I2C, causing build failures.

Fixes 0e5e21e23dd6 ("iio: light: al3010: Implement regmap support")
---
 drivers/iio/light/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/light/Kconfig +1 -0
@@ -56,6 +56,7 @@ config AL3000A
 
 config AL3010
 	tristate "AL3010 ambient light sensor"
+	select REGMAP_I2C
 	depends on I2C
 	help
 	  Say Y here if you want to build a driver for the Dyna Image AL3010
author maintainer
#64 lore raw

PATCH 62/518 iio: light: al3010: fix incorrect scale for the highest gain range

In reply to Greg Kroah-Hartman

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

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

From: Vidhu Sarwal <[email protected]>

commit aa411adc6ce40ad1a55ebc965f255a4cfc0005f8 upstream.

al3010_scales[] encodes the highest gain range as {0, 1187200}. For IIO_VAL_INT_PLUS_MICRO, the fractional part must be less than 1000000, so the scale 1.1872 should instead be represented as { 1, 187200 }.

Since write_raw() compares the value from userspace against this table, writing the advertised 1.1872 scale never matches the malformed entry and returns -EINVAL. As a result, the highest gain range cannot be selected. Reading the scale in that state also reports the malformed value.

Fixes c36b5195ab70 ("iio: light: add Dyna-Image AL3010 driver")
---
 drivers/iio/light/al3010.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/al3010.c +1 -1
@@ -42,7 +42,7 @@ enum al3xxxx_range {
 };
 
 static const int al3010_scales[][2] = {
-	{0, 1187200}, {0, 296800}, {0, 74200}, {0, 18600}
+	{ 1, 187200 }, { 0, 296800 }, { 0, 74200 }, { 0, 18600 },
 };
 
 static const struct regmap_config al3010_regmap_config = {
author maintainer
#65 lore raw

PATCH 63/518 iio: light: al3010: read both ALS ADC registers again

In reply to Greg Kroah-Hartman

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

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

From: Alexander A. Klimov <[email protected]>

commit ee78fae068f52a5582aaf448d9414f826855c106 upstream.

al3010_read_raw() used to read two adjacent registers until the driver was modernized using the regmap framework. That cleanup accidentally replaced the 16-bit word read with a single byte read. I'm reverting latter.

Fixes 0e5e21e23dd6 ("iio: light: al3010: Implement regmap support")
---
 drivers/iio/light/al3010.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/light/al3010.c +5 -3
@@ -111,7 +111,8 @@ static int al3010_read_raw(struct iio_de
 			   int *val2, long mask)
 {
 	struct al3010_data *data = iio_priv(indio_dev);
-	int ret, gain, raw;
+	int ret, gain;
+	__le16 raw;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -120,11 +121,12 @@ static int al3010_read_raw(struct iio_de
 		 * - low byte of output is stored at AL3010_REG_DATA_LOW
 		 * - high byte of output is stored at AL3010_REG_DATA_LOW + 1
 		 */
-		ret = regmap_read(data->regmap, AL3010_REG_DATA_LOW, &raw);
+		ret = regmap_bulk_read(data->regmap, AL3010_REG_DATA_LOW,
+				       &raw, sizeof(raw));
 		if (ret)
 			return ret;
 
-		*val = raw;
+		*val = le16_to_cpu(raw);
 
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
author maintainer
#66 lore raw

PATCH 64/518 iio: light: al3320a: add missing REGMAP_I2C to Kconfig

In reply to Greg Kroah-Hartman

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

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

From: Joshua Crofts <[email protected]>

commit 9efcc9ba9b2e940cc01e63d132ae741e4c5d09c7 upstream.

The Kconfig entry for the al3320a is missing a select REGMAP_I2C, causing build failures.

Fixes 1850e6ae7f91 ("iio: light: al3320a: Implement regmap support")
---
 drivers/iio/light/Kconfig |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/light/Kconfig +1 -0
@@ -67,6 +67,7 @@ config AL3010
 
 config AL3320A
 	tristate "AL3320A ambient light sensor"
+	select REGMAP_I2C
 	depends on I2C
 	help
 	  Say Y here if you want to build a driver for the Dyna Image AL3320A
author maintainer
#67 lore raw

PATCH 65/518 iio: light: al3320a: read both ALS ADC registers again

In reply to Greg Kroah-Hartman

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

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

From: Alexander A. Klimov <[email protected]>

commit 744bccc2647c6b2206290e8e40890a23812116b3 upstream.

al3320a_read_raw() used to read two adjacent registers until the driver was modernized using the regmap framework. That cleanup accidentally replaced the 16-bit word read with a single byte read. I'm reverting latter.

Fixes 1850e6ae7f91 ("iio: light: al3320a: Implement regmap support")
---
 drivers/iio/light/al3320a.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/light/al3320a.c +5 -3
@@ -135,7 +135,8 @@ static int al3320a_read_raw(struct iio_d
 			    int *val2, long mask)
 {
 	struct al3320a_data *data = iio_priv(indio_dev);
-	int ret, gain, raw;
+	int ret, gain;
+	__le16 raw;
 
 	switch (mask) {
 	case IIO_CHAN_INFO_RAW:
@@ -144,11 +145,12 @@ static int al3320a_read_raw(struct iio_d
 		 * - low byte of output is stored at AL3320A_REG_DATA_LOW
 		 * - high byte of output is stored at AL3320A_REG_DATA_LOW + 1
 		 */
-		ret = regmap_read(data->regmap, AL3320A_REG_DATA_LOW, &raw);
+		ret = regmap_bulk_read(data->regmap, AL3320A_REG_DATA_LOW,
+				       &raw, sizeof(raw));
 		if (ret)
 			return ret;
 
-		*val = raw;
+		*val = le16_to_cpu(raw);
 
 		return IIO_VAL_INT;
 	case IIO_CHAN_INFO_SCALE:
author maintainer
#68 lore raw

PATCH 66/518 iio: light: gp2ap002: fix runtime PM leak on read error

In reply to Greg Kroah-Hartman

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

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

From: Biren Pandya <[email protected]>

commit 38b72267b7e22768a1f26d9935de4e1752a1dc85 upstream.

gp2ap002_read_raw() calls pm_runtime_get_sync() before reading the lux value, but if gp2ap002_get_lux() fails, it returns directly. This skips the pm_runtime_put_autosuspend() call at the "out" label, permanently leaking a runtime PM reference and preventing the device from autosuspending.

Replace the direct return with a "goto out" to ensure the reference is properly dropped on the error path.

Fixes f6dbf83c17cb ("iio: light: gp2ap002: Take runtime PM reference on light read")
---
 drivers/iio/light/gp2ap002.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/gp2ap002.c +1 -1
@@ -258,7 +258,7 @@ static int gp2ap002_read_raw(struct iio_
 		case IIO_LIGHT:
 			ret = gp2ap002_get_lux(gp2ap002);
 			if (ret < 0)
-				return ret;
+				goto out;
 			*val = ret;
 			ret = IIO_VAL_INT;
 			goto out;
author maintainer
#69 lore raw

PATCH 67/518 iio: light: opt3001: fix missing state reset on timeout

In reply to Greg Kroah-Hartman

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

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

From: Joshua Crofts <[email protected]>

commit c123ca6ee26ad98f70a866ff428b08145c5a24fe upstream.

Currently in the function opt3001_get_processed(), there is a check that directly returns -ETIMEDOUT if the conversion IRQ times out, completely bypassing the err label, leaving ok_to_ignore_lock permanently true, potentially breaking the device's falling threshold interrupt detection.

Assign -ETIMEDOUT to the return variable and jump to the error label to ensure ok_to_ignore_lock is properly reset.

---
 drivers/iio/light/opt3001.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/iio/light/opt3001.c +4 -2
@@ -366,8 +366,10 @@ static int opt3001_get_processed(struct
 		ret = wait_event_timeout(opt->result_ready_queue,
 				opt->result_ready,
 				msecs_to_jiffies(OPT3001_RESULT_READY_LONG));
-		if (ret == 0)
-			return -ETIMEDOUT;
+		if (ret == 0) {
+			ret = -ETIMEDOUT;
+			goto err;
+		}
 	} else {
 		/* Sleep for result ready time */
 		timeout = (opt->int_time == OPT3001_INT_TIME_SHORT) ?
author maintainer
#70 lore raw

PATCH 68/518 iio: light: tsl2591: return actual error from probe IRQ failure

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit a00ffd15674bfaf8b906503c1600e3d8709af56c upstream.

When devm_request_threaded_irq() fails, probe logs the error and then returns -EINVAL, dropping the real error code and breaking the deferred-probe flow for -EPROBE_DEFER.

Return ret directly; the IRQ subsystem already prints on failure.

Fixes 2335f0d7c790 ("iio: light: Added AMS tsl2591 driver implementation")
---
 drivers/iio/light/tsl2591.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/iio/light/tsl2591.c +2 -4
@@ -1137,10 +1137,8 @@ static int tsl2591_probe(struct i2c_clie
 						NULL, tsl2591_event_handler,
 						IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 						"tsl2591_irq", indio_dev);
-		if (ret) {
-			dev_err_probe(&client->dev, ret, "IRQ request error\n");
-			return -EINVAL;
-		}
+		if (ret)
+			return ret;
 		indio_dev->info = &tsl2591_info;
 	} else {
 		indio_dev->info = &tsl2591_info_no_irq;
author maintainer
#71 lore raw

PATCH 69/518 iio: light: veml6030: fix channel type when pushing events

In reply to Greg Kroah-Hartman

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

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

From: Javier Carrasco <[email protected]>

commit c52bb33b641ebaae3e209f97714cb1758206f7d9 upstream.

The events are registered for IIO_LIGHT and not for IIO_INTENSITY. Use the correct channel type.

When at it, fix minor checkpatch code style warning (alignment).

Fixes 7b779f573c48 ("iio: light: add driver for veml6030 ambient light sensor")
---
 drivers/iio/light/veml6030.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/light/veml6030.c +5 -3
@@ -875,9 +875,11 @@ static irqreturn_t veml6030_event_handle
 	else
 		evtdir = IIO_EV_DIR_FALLING;
 
-	iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_INTENSITY,
-					0, IIO_EV_TYPE_THRESH, evtdir),
-					iio_get_time_ns(indio_dev));
+	iio_push_event(indio_dev, IIO_UNMOD_EVENT_CODE(IIO_LIGHT,
+						       0,
+						       IIO_EV_TYPE_THRESH,
+						       evtdir),
+		       iio_get_time_ns(indio_dev));
 
 	return IRQ_HANDLED;
 }
author maintainer
#72 lore raw

PATCH 70/518 iio: magnetometer: ak8975: Add missed pm_runtime_put_autosuspend() call

In reply to Greg Kroah-Hartman

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

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

From: Andy Shevchenko <[email protected]>

commit e94944d7364d3ddb273539492f9bd9c9a622549a upstream.

On the failure in the ak8975_read_axis() the PM runtime gets unbalanced. Balance it by calling pm_runtime_put_autosuspend() on error path as well.

---
 drivers/iio/magnetometer/ak8975.c |    1 +
 1 file changed, 1 insertion(+)
drivers/iio/magnetometer/ak8975.c +1 -0
@@ -784,6 +784,7 @@ static int ak8975_read_axis(struct iio_d
 
 exit:
 	mutex_unlock(&data->lock);
+	pm_runtime_put_autosuspend(&data->client->dev);
 	dev_err(&client->dev, "Error in reading axis\n");
 	return ret;
 }
author maintainer
#73 lore raw

PATCH 71/518 iio: pressure: bmp280: zero-init bmp580 trigger handler buffer

In reply to Greg Kroah-Hartman

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

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

From: David Carlier <[email protected]>

commit 1172160f2a2de7bade3bec64b8c5ecf945cde5ed upstream.

bmp580_trigger_handler() builds an on-stack scan buffer containing two __le32 fields and an aligned_s64 timestamp, and pushes it to userspace via iio_push_to_buffers_with_ts(). However, only the low 3 bytes of each __le32 field are populated by the device data:

	memcpy(&buffer.comp_press, &data->buf[3], 3);
	memcpy(&buffer.comp_temp,  &data->buf[0], 3);

The high byte of each field is left uninitialised on the stack. The bmp580 channels declare storagebits = 32, so the IIO core transports all four bytes per sample to userspace as part of the scan element, leaking two bytes of kernel stack per scan.

Zero-initialise the buffer before populating it, mirroring the fix applied to bme280_trigger_handler() in commit 018f50909e66 ("iio:
bmp280: zero-init buffer").

Fixes 872c8014e05e ("iio: pressure: bmp280: drop sensor_data array")
---
 drivers/iio/pressure/bmp280-core.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/pressure/bmp280-core.c +1 -1
@@ -1910,7 +1910,7 @@ static irqreturn_t bmp380_trigger_handle
 		u32 comp_press;
 		s32 comp_temp;
 		aligned_s64 timestamp;
-	} buffer;
+	} buffer = { };
 	int ret;
 
 	guard(mutex)(&data->lock);
author maintainer
#74 lore raw

PATCH 72/518 iio: pressure: mpl115: fix runtime PM leak on read error

In reply to Greg Kroah-Hartman

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

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

From: Biren Pandya <[email protected]>

commit fbe67ff37a6fd855a6c097f84f3738bd13d0a898 upstream.

mpl115_read_raw() takes a runtime PM reference with pm_runtime_get_sync() before reading the processed pressure or raw temperature, but on the read error path it returns without calling pm_runtime_put_autosuspend(). Each failed read therefore leaks a runtime PM reference and prevents the device from autosuspending.

Drop the reference before checking the return value so both the success and error paths are balanced.

Fixes 0c3a333524a3 ("iio: pressure: mpl115: Implementing low power mode by shutdown gpio")
Assisted-by Claude:claude-opus-4-8 coccinelle
---
 drivers/iio/pressure/mpl115.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/pressure/mpl115.c +2 -2
@@ -106,18 +106,18 @@ static int mpl115_read_raw(struct iio_de
 	case IIO_CHAN_INFO_PROCESSED:
 		pm_runtime_get_sync(data->dev);
 		ret = mpl115_comp_pressure(data, val, val2);
+		pm_runtime_put_autosuspend(data->dev);
 		if (ret < 0)
 			return ret;
-		pm_runtime_put_autosuspend(data->dev);
 
 		return IIO_VAL_INT_PLUS_MICRO;
 	case IIO_CHAN_INFO_RAW:
 		pm_runtime_get_sync(data->dev);
 		/* temperature -5.35 C / LSB, 472 LSB is 25 C */
 		ret = mpl115_read_temp(data);
+		pm_runtime_put_autosuspend(data->dev);
 		if (ret < 0)
 			return ret;
-		pm_runtime_put_autosuspend(data->dev);
 		*val = ret >> 6;
 
 		return IIO_VAL_INT;
author maintainer
#75 lore raw

PATCH 73/518 iio: proximity: vl53l0x: notify trigger and clear IRQ on error paths

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit be843b0579f872ec7590d825e2c9a656d4790c4b upstream.

vl53l0x_trigger_handler() returns directly on the I2C read failure paths without calling iio_trigger_notify_done() or vl53l0x_clear_irq().

A single transient i2c_smbus_read_i2c_block_data() failure (negative errno or a short read) therefore leaves two pieces of state behind:

- iio_trigger_notify_done() never decrements the trigger's use_count,

    so iio_trigger_poll_nested() silently drops further dispatches
    (see industrialio-trigger.c, the !atomic_read(&trig->use_count)
    guard);

- vl53l0x_clear_irq() never writes SYSTEM_INTERRUPT_CLEAR, so the chip keeps the DRDY interrupt asserted.

The sensor's buffer mode stays wedged from then on, recoverable only by re-binding the driver. The sibling driver vl53l1x-i2c.c handles exactly the same case correctly by jumping to a "notify_and_clear_irq" label that always calls both helpers; mirror that here.

The bogus negative-int return value cast to irqreturn_t also goes away as a side effect.

Fixes 762186c6e7b1 ("iio: proximity: vl53l0x-i2c: Added continuous mode support")
---
 drivers/iio/proximity/vl53l0x-i2c.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
drivers/iio/proximity/vl53l0x-i2c.c +3 -4
@@ -87,15 +87,14 @@ static irqreturn_t vl53l0x_trigger_handl
 	ret = i2c_smbus_read_i2c_block_data(data->client,
 					VL_REG_RESULT_RANGE_STATUS,
 					sizeof(buffer), buffer);
-	if (ret < 0)
-		return ret;
-	else if (ret != 12)
-		return -EREMOTEIO;
+	if (ret != 12)
+		goto done;
 
 	scan.chan = get_unaligned_be16(&buffer[10]);
 	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
 				    iio_get_time_ns(indio_dev));
 
+done:
 	iio_trigger_notify_done(indio_dev->trig);
 	vl53l0x_clear_irq(data);
 
author maintainer
#76 lore raw

PATCH 74/518 iio: resolver: ad2s1210: notify trigger and clear state on fault read error

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit 70247658d0e783c93b48fcbc3b81d99e992ff478 upstream.

ad2s1210_trigger_handler() walks several scan-mask branches and uses "goto error_ret" to land on the iio_trigger_notify_done() teardown at the bottom of the function for every I/O error -- except the MOD_CONFIG fault-register read, which uses a bare "return ret":

	if (st->fixed_mode == MOD_CONFIG) {
		unsigned int reg_val;

		ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &reg_val);
		if (ret < 0)
			return ret;
		...
	}

Two problems on that path:

- the handler returns a negative errno where the prototype expects an irqreturn_t (IRQ_HANDLED / IRQ_NONE), so the caller in the IIO core sees a value outside the enum;
- iio_trigger_notify_done() is skipped, leaving the trigger busy-flag set. A single transient SPI/regmap error on the fault read then wedges the trigger so subsequent samples are dropped until the consumer is detached.

Convert the error path to "goto error_ret" so the failure path goes through the same notify_done() teardown as every other error in the handler.

Fixes f9b9ff95be8c ("iio: resolver: ad2s1210: add support for adi,fixed-mode")
---
 drivers/iio/resolver/ad2s1210.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/resolver/ad2s1210.c +1 -1
@@ -1334,7 +1334,7 @@ static irqreturn_t ad2s1210_trigger_hand
 
 		ret = regmap_read(st->regmap, AD2S1210_REG_FAULT, &reg_val);
 		if (ret < 0)
-			return ret;
+			goto error_ret;
 
 		st->sample.fault = reg_val;
 	}
author maintainer
#77 lore raw

PATCH 75/518 iio: temperature: Build mlx90635 with CONFIG_MLX90635

In reply to Greg Kroah-Hartman

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

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

From: Pengpeng Hou <[email protected]>

commit 63a76e3a587c4143e8e24e8a6b0c232fa0676034 upstream.

drivers/iio/temperature/Kconfig has a dedicated MLX90635 option, but the Makefile currently builds mlx90635.o under CONFIG_MLX90632.

This means enabling CONFIG_MLX90635 alone does not carry its provider object into the build, while enabling CONFIG_MLX90632 unexpectedly also builds mlx90635.o.

Gate mlx90635.o on the matching generated Kconfig symbol.

Fixes a1d1ba5e1c28 ("iio: temperature: mlx90635 MLX90635 IR Temperature sensor")
---
 drivers/iio/temperature/Makefile |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/temperature/Makefile +1 -1
@@ -13,7 +13,7 @@ obj-$(CONFIG_MAX31865) += max31865.o
 obj-$(CONFIG_MCP9600) += mcp9600.o
 obj-$(CONFIG_MLX90614) += mlx90614.o
 obj-$(CONFIG_MLX90632) += mlx90632.o
-obj-$(CONFIG_MLX90632) += mlx90635.o
+obj-$(CONFIG_MLX90635) += mlx90635.o
 obj-$(CONFIG_TMP006) += tmp006.o
 obj-$(CONFIG_TMP007) += tmp007.o
 obj-$(CONFIG_TMP117) += tmp117.o
author maintainer
#78 lore raw

PATCH 76/518 iio: temperature: ltc2983: Fix n_wires default bypassing rotation check

In reply to Greg Kroah-Hartman

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

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

From: Liviu Stan <[email protected]>

commit 434c150752675f44dc52c384a7fa22e5176bc35a upstream.

When adi,number-of-wires is absent, n_wires is left at 0. The binding documents a default of 2 wires, matching the hardware default. However the current-rotate validation checks n_wires == 2 || n_wires == 3, so with n_wires = 0 the guard is bypassed and adi,current-rotate is accepted for a 2-wire RTD.

Initialize n_wires = 2 to match the binding default and ensure the rotation check fires correctly when the property is absent.

Fixes f110f3188e56 ("iio: temperature: Add support for LTC2983")
---
 drivers/iio/temperature/ltc2983.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/temperature/ltc2983.c +1 -1
@@ -741,7 +741,7 @@ ltc2983_rtd_new(const struct fwnode_hand
 	struct ltc2983_rtd *rtd;
 	int ret = 0;
 	struct device *dev = &st->spi->dev;
-	u32 excitation_current = 0, n_wires = 0;
+	u32 excitation_current = 0, n_wires = 2;
 
 	rtd = devm_kzalloc(dev, sizeof(*rtd), GFP_KERNEL);
 	if (!rtd)
author maintainer
#79 lore raw

PATCH 77/518 iio: temperature: ltc2983: Fix reinit_completion() called after conversion start

In reply to Greg Kroah-Hartman

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

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

From: Liviu Stan <[email protected]>

commit 5cb9fdb446bfc3ae0524496f53fb68e67051701b upstream.

reinit_completion() was called after regmap_write() initiated the hardware conversion, creating a race window where the interrupt could fire and call complete() before reinit_completion() reset the completion.

Move reinit_completion() before the regmap_write() to close the race. ltc2983_eeprom_cmd() already does it in the correct order.

Fixes f110f3188e56 ("iio: temperature: Add support for LTC2983")
---
 drivers/iio/temperature/ltc2983.c |    3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/iio/temperature/ltc2983.c +1 -2
@@ -1177,12 +1177,11 @@ static int ltc2983_chan_read(struct ltc2
 	start_conversion |= LTC2983_STATUS_CHAN_SEL(sensor->chan);
 	dev_dbg(&st->spi->dev, "Start conversion on chan:%d, status:%02X\n",
 		sensor->chan, start_conversion);
+	reinit_completion(&st->completion);
 	/* start conversion */
 	ret = regmap_write(st->regmap, LTC2983_STATUS_REG, start_conversion);
 	if (ret)
 		return ret;
-
-	reinit_completion(&st->completion);
 	/*
 	 * wait for conversion to complete.
 	 * 300 ms should be more than enough to complete the conversion.
author maintainer
#80 lore raw

PATCH 78/518 iio: temperature: tmp006: use devm_iio_trigger_register

In reply to Greg Kroah-Hartman

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

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

From: Stepan Ionichev <[email protected]>

commit 3c5eed894efd93d68d7f6a359a81ddef0e928774 upstream.

tmp006_probe() allocates the DRDY trigger with devm_iio_trigger_alloc() but registers it with plain iio_trigger_register(). The driver has no .remove() callback, so on module unload the trigger stays in the global trigger list while its memory is freed by devm, leaving a dangling entry.

Switch to devm_iio_trigger_register() so the registration is undone in the same devm scope as the allocation.

Fixes 91f75ccf9f03 ("iio: temperature: tmp006: add triggered buffer support")
---
 drivers/iio/temperature/tmp006.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/temperature/tmp006.c +1 -1
@@ -350,7 +350,7 @@ static int tmp006_probe(struct i2c_clien
 
 		data->drdy_trig->ops = &tmp006_trigger_ops;
 		iio_trigger_set_drvdata(data->drdy_trig, indio_dev);
-		ret = iio_trigger_register(data->drdy_trig);
+		ret = devm_iio_trigger_register(&client->dev, data->drdy_trig);
 		if (ret)
 			return ret;
 
author maintainer
#81 lore raw

PATCH 79/518 ALSA: usx2y: us144mkii: fix work UAF on disconnect

In reply to Greg Kroah-Hartman

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

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

From: HyeongJun An <[email protected]>

commit 147996e7e7c9e8339c0e04f6fa7ccb3e4d448ff7 upstream.

tascam_disconnect() cancels capture_work and midi_in_work before usb_kill_anchored_urbs() kills the capture/MIDI-in URBs. Those URBs self-resubmit, and their completion handlers reschedule the work.

A URB that completes in the small window between cancel_work_sync() and usb_kill_anchored_urbs() therefore re-arms the work after its only cancel. Nothing cancels it again before snd_card_free() frees the card-private tascam structure, so the work handler then runs on freed memory.

Kill the anchored URBs before cancelling the work; once the work is cancelled no remaining URB can complete to re-arm it.

Fixes c1bb0c13e430 ("ALSA: usb-audio: us144mkii: Implement audio capture and decoding")
Assisted-by Claude:claude-opus-4-8
---
 sound/usb/usx2y/us144mkii.c |   17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)
sound/usb/usx2y/us144mkii.c +11 -6
@@ -585,19 +585,24 @@ static void tascam_disconnect(struct usb
 		return;
 
 	if (intf->cur_altsetting->desc.bInterfaceNumber == 0) {
-		/* Ensure all deferred work is complete before freeing resources */
 		snd_card_disconnect(tascam->card);
-		cancel_work_sync(&tascam->stop_work);
-		cancel_work_sync(&tascam->capture_work);
-		cancel_work_sync(&tascam->midi_in_work);
-		cancel_work_sync(&tascam->midi_out_work);
-		cancel_work_sync(&tascam->stop_pcm_work);
 
+		/*
+		 * Kill the URBs before cancelling the work, so a late URB
+		 * completion cannot re-arm a work that then runs after
+		 * snd_card_free().
+		 */
 		usb_kill_anchored_urbs(&tascam->playback_anchor);
 		usb_kill_anchored_urbs(&tascam->capture_anchor);
 		usb_kill_anchored_urbs(&tascam->feedback_anchor);
 		usb_kill_anchored_urbs(&tascam->midi_in_anchor);
 		usb_kill_anchored_urbs(&tascam->midi_out_anchor);
+
+		cancel_work_sync(&tascam->stop_work);
+		cancel_work_sync(&tascam->capture_work);
+		cancel_work_sync(&tascam->midi_in_work);
+		cancel_work_sync(&tascam->midi_out_work);
+		cancel_work_sync(&tascam->stop_pcm_work);
 		timer_delete_sync(&tascam->error_timer);
 		tascam_free_urbs(tascam);
 		snd_card_free(tascam->card);
author maintainer
#82 lore raw

PATCH 80/518 ALSA: virtio: Add missing 384 kHz PCM rate mapping

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 83fbbcb7935ec6d2c8ba3bc133e8a0ead2ab0b2d upstream.

The VirtIO sound UAPI defines VIRTIO_SND_PCM_RATE_384000, and ALSA has SNDRV_PCM_RATE_384000. However, virtio-snd's rate conversion tables stop at 192 kHz.

A device advertising only 384 kHz is rejected as having no supported PCM frame rates. A device advertising 384 kHz together with lower rates does not expose 384 kHz through the ALSA hardware constraints. The selected ALSA rate also needs a reverse mapping for SET_PARAMS.

Add the missing 384 kHz entries to both conversion tables.

Fixes 29b96bf50ba9 ("ALSA: virtio: build PCM devices and substream hardware descriptors")
Fixes da76e9f3e43a ("ALSA: virtio: PCM substream operators")
---
 sound/virtio/virtio_pcm.c     |    3 ++-
 sound/virtio/virtio_pcm_ops.c |    3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)
sound/virtio/virtio_pcm.c +2 -1
@@ -77,7 +77,8 @@ static const struct virtsnd_v2a_rate g_v
 	[VIRTIO_SND_PCM_RATE_88200] = { SNDRV_PCM_RATE_88200, 88200 },
 	[VIRTIO_SND_PCM_RATE_96000] = { SNDRV_PCM_RATE_96000, 96000 },
 	[VIRTIO_SND_PCM_RATE_176400] = { SNDRV_PCM_RATE_176400, 176400 },
-	[VIRTIO_SND_PCM_RATE_192000] = { SNDRV_PCM_RATE_192000, 192000 }
+	[VIRTIO_SND_PCM_RATE_192000] = { SNDRV_PCM_RATE_192000, 192000 },
+	[VIRTIO_SND_PCM_RATE_384000] = { SNDRV_PCM_RATE_384000, 384000 }
 };
 
 /**
sound/virtio/virtio_pcm_ops.c +2 -1
@@ -90,7 +90,8 @@ static const struct virtsnd_a2v_rate g_a
 	{ 88200, VIRTIO_SND_PCM_RATE_88200 },
 	{ 96000, VIRTIO_SND_PCM_RATE_96000 },
 	{ 176400, VIRTIO_SND_PCM_RATE_176400 },
-	{ 192000, VIRTIO_SND_PCM_RATE_192000 }
+	{ 192000, VIRTIO_SND_PCM_RATE_192000 },
+	{ 384000, VIRTIO_SND_PCM_RATE_384000 }
 };
 
 static int virtsnd_pcm_sync_stop(struct snd_pcm_substream *substream);
author maintainer
#83 lore raw

PATCH 81/518 ALSA: virtio: Validate control metadata from the device

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit c77a6cbb36ff8cbc1f084d94f8dcda5250935271 upstream.

virtio-snd control handling trusts the device-provided control type and value count returned by the device.

That metadata is then used directly to index g_v2a_type_map[] in virtsnd_kctl_info(), and to size loops and memcpy() operations in virtsnd_kctl_get() and virtsnd_kctl_put() against fixed-size virtio_snd_ctl_value and snd_ctl_elem_value arrays.

A buggy or malicious device can therefore trigger out-of-bounds access by advertising an invalid control type or an oversized value count.

Validate control type and count once in virtsnd_kctl_parse_cfg(), before querying enumerated items or exposing the control to ALSA.

---
 sound/virtio/virtio_kctl.c |   50 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)
sound/virtio/virtio_kctl.c +50 -0
@@ -18,6 +18,21 @@ static const snd_ctl_elem_type_t g_v2a_t
 	[VIRTIO_SND_CTL_TYPE_IEC958] = SNDRV_CTL_ELEM_TYPE_IEC958
 };
 
+/* Map for converting VirtIO types to maximum value counts. */
+static const unsigned int g_v2a_count_map[] = {
+	[VIRTIO_SND_CTL_TYPE_BOOLEAN] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer),
+	[VIRTIO_SND_CTL_TYPE_INTEGER] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer),
+	[VIRTIO_SND_CTL_TYPE_INTEGER64] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.integer64),
+	[VIRTIO_SND_CTL_TYPE_ENUMERATED] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.enumerated),
+	[VIRTIO_SND_CTL_TYPE_BYTES] =
+		ARRAY_SIZE(((struct virtio_snd_ctl_value *)0)->value.bytes),
+	[VIRTIO_SND_CTL_TYPE_IEC958] = 1
+};
+
 /* Map for converting VirtIO access rights to ALSA access rights. */
 static const unsigned int g_v2a_access_map[] = {
 	[VIRTIO_SND_CTL_ACCESS_READ] = SNDRV_CTL_ELEM_ACCESS_READ,
@@ -36,6 +51,37 @@ static const unsigned int g_v2a_mask_map
 	[VIRTIO_SND_CTL_EVT_MASK_TLV] = SNDRV_CTL_EVENT_MASK_TLV
 };
 
+static int virtsnd_kctl_validate_info(struct virtio_snd *snd, u32 cid,
+				      struct virtio_snd_ctl_info *kinfo)
+{
+	struct virtio_device *vdev = snd->vdev;
+	unsigned int type = le32_to_cpu(kinfo->type);
+	unsigned int count = le32_to_cpu(kinfo->count);
+
+	if (type >= ARRAY_SIZE(g_v2a_type_map)) {
+		dev_err(&vdev->dev, "control #%u: unknown type %u\n",
+			cid, type);
+		return -EINVAL;
+	}
+
+	if (count > g_v2a_count_map[type] ||
+	    (type == VIRTIO_SND_CTL_TYPE_IEC958 && count != 1)) {
+		dev_err(&vdev->dev, "control #%u: invalid count %u for type %u\n",
+			cid, count, type);
+		return -EINVAL;
+	}
+
+	if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED &&
+	    !le32_to_cpu(kinfo->value.enumerated.items)) {
+		dev_err(&vdev->dev,
+			"control #%u: no items for enumerated control\n",
+			cid);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /**
  * virtsnd_kctl_info() - Returns information about the control.
  * @kcontrol: ALSA control element.
@@ -385,6 +431,10 @@ int virtsnd_kctl_parse_cfg(struct virtio
 		struct virtio_snd_ctl_info *kinfo = &snd->kctl_infos[i];
 		unsigned int type = le32_to_cpu(kinfo->type);
 
+		rc = virtsnd_kctl_validate_info(snd, i, kinfo);
+		if (rc)
+			return rc;
+
 		if (type == VIRTIO_SND_CTL_TYPE_ENUMERATED) {
 			rc = virtsnd_kctl_get_enum_items(snd, i);
 			if (rc)
author maintainer
#84 lore raw

PATCH 82/518 ALSA: ymfpci: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

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

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

From: Zhao Dongdong <[email protected]>

commit e64d170346d00b580c0043de3e5ccb3e331c47d4 upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_ymfpci_create_spdif_controls() does not check the return value before dereferencing kctl->id.device, which can lead to a NULL pointer dereference.

Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes c9b83ae4a160 ("ALSA: ymfpci: Fix kctl->id initialization")
---
 sound/pci/ymfpci/ymfpci_main.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/pci/ymfpci/ymfpci_main.c +6 -0
@@ -1781,16 +1781,22 @@ int snd_ymfpci_mixer(struct snd_ymfpci *
 	if (snd_BUG_ON(!chip->pcm_spdif))
 		return -ENXIO;
 	kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = chip->pcm_spdif->device;
 	err = snd_ctl_add(chip->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ymfpci_spdif_mask, chip);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = chip->pcm_spdif->device;
 	err = snd_ctl_add(chip->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ymfpci_spdif_stream, chip);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = chip->pcm_spdif->device;
 	err = snd_ctl_add(chip->card, kctl);
 	if (err < 0)
author maintainer
#85 lore raw

PATCH 83/518 ALSA: aoa: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

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

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

From: Zhao Dongdong <[email protected]>

commit 8df560fefe6fed6a20b7e06720eeaeccec349ac0 upstream.

snd_ctl_new1() can return NULL when memory allocation fails. In layout.c, the function does not check the return value before dereferencing ctl->id.name or passing to aoa_snd_ctl_add(), which can lead to a NULL pointer dereference.

Add NULL checks after snd_ctl_new1() calls and return early if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes f3d9478b2ce4 ("[ALSA] snd-aoa: add snd-aoa")
---
 sound/aoa/fabrics/layout.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/aoa/fabrics/layout.c +6 -0
@@ -948,6 +948,8 @@ static void layout_attached_codec(struct
 			if (lineout == 1)
 				ldev->gpio.methods->set_lineout(codec->gpio, 1);
 			ctl = snd_ctl_new1(&lineout_ctl, codec->gpio);
+			if (!ctl)
+				return;
 			if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
 				strscpy(ctl->id.name, "Headphone Switch");
 			ldev->lineout_ctrl = ctl;
@@ -961,12 +963,16 @@ static void layout_attached_codec(struct
 			if (ldev->have_lineout_detect) {
 				ctl = snd_ctl_new1(&lineout_detect_choice,
 						   ldev);
+				if (!ctl)
+					return;
 				if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
 					strscpy(ctl->id.name,
 						"Headphone Detect Autoswitch");
 				aoa_snd_ctl_add(ctl);
 				ctl = snd_ctl_new1(&lineout_detected,
 						   ldev);
+				if (!ctl)
+					return;
 				if (cc->connected & CC_LINEOUT_LABELLED_HEADPHONE)
 					strscpy(ctl->id.name,
 						"Headphone Detected");
author maintainer
#86 lore raw

PATCH 84/518 ALSA: caiaq: fix out-of-bounds read in the Traktor Kontrol S4 input parser

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

commit f7f3f9fd81e7adbaa12c2e62ee07f0e094a543fd upstream.

snd_usb_caiaq_tks4_dispatch() decodes the Traktor Kontrol S4 input stream in fixed 16-byte (TKS4_MSGBLOCK_SIZE) message blocks. On every iteration it advances buf and subtracts the block size while looping on "while (len)".

len is urb->actual_length. That value is supplied by the device and is not guaranteed to be a multiple of 16. When a final short block leaves len between 1 and 15, the loop runs once more, reads up to buf[15], and then does "len -= TKS4_MSGBLOCK_SIZE". As len is unsigned this underflows to a huge value. The loop then keeps iterating and walking buf far past the end of the 512-byte ep4_in_buf, reading out of bounds until a bogus block id happens to be hit.

Iterate only while a full message block is available. This stops the unsigned underflow and silently drops any trailing partial block, which carries no complete control value anyway.

The sibling endpoint-4 parsers are not affected. The Traktor Kontrol X1 and Maschine arms in snd_usb_caiaq_ep4_reply_dispatch() floor urb->actual_length before dispatching.

Fixes 15c5ab607045 ("ALSA: snd-usb-caiaq: Add support for Traktor Kontrol S4")
---
 sound/usb/caiaq/input.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/caiaq/input.c +1 -1
@@ -330,7 +330,7 @@ static void snd_usb_caiaq_tks4_dispatch(
 {
 	struct device *dev = caiaqdev_to_dev(cdev);
 
-	while (len) {
+	while (len >= TKS4_MSGBLOCK_SIZE) {
 		unsigned int i, block_id = (buf[0] << 8) | buf[1];
 
 		switch (block_id) {
author maintainer
#87 lore raw

PATCH 85/518 ALSA: cmipci: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

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

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

From: Zhao Dongdong <[email protected]>

commit c205bd1b28fb7e5f1061a4e78813fad7d315cb3e upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_cmipci_spdif_controls() does not check the return value before dereferencing kctl->id.device, which can lead to a NULL pointer dereference.

Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes f2f312ad88c6 ("ALSA: cmipci: Fix kctl->id initialization")
---
 sound/pci/cmipci.c |    6 ++++++
 1 file changed, 6 insertions(+)
sound/pci/cmipci.c +6 -0
@@ -2637,16 +2637,22 @@ static int snd_cmipci_mixer_new(struct c
 		}
 		if (cm->can_ac3_hw) {
 			kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm);
+			if (!kctl)
+				return -ENOMEM;
 			kctl->id.device = pcm_spdif_device;
 			err = snd_ctl_add(card, kctl);
 			if (err < 0)
 				return err;
 			kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm);
+			if (!kctl)
+				return -ENOMEM;
 			kctl->id.device = pcm_spdif_device;
 			err = snd_ctl_add(card, kctl);
 			if (err < 0)
 				return err;
 			kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm);
+			if (!kctl)
+				return -ENOMEM;
 			kctl->id.device = pcm_spdif_device;
 			err = snd_ctl_add(card, kctl);
 			if (err < 0)
author maintainer
#88 lore raw

PATCH 86/518 ALSA: compress: Fix task creation error unwind

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 4a60127debb9e370d6c0e22a307326b624a141f3 upstream.

snd_compr_task_new() allocates the driver task before validating the returned DMA buffers and reserving file descriptors. When either of those later steps fails, the core frees its task wrapper and DMA-buffer references without calling the driver's task_free() callback. Any driver resources allocated by task_create() are therefore leaked.

The dual-fd allocation path also jumps to cleanup without storing the negative get_unused_fd_flags() result in retval. Since retval still contains the successful task_create() return value, TASK_CREATE can incorrectly report success although the task was discarded.

Preserve the fd allocation errors and call task_free() when failure occurs after a successful task_create() callback.

Fixes 04177158cf98 ("ALSA: compress_offload: introduce accel operation mode")
Fixes 3d3f43fab4cf ("ALSA: compress_offload: improve file descriptors installation for dma-buf")
---
 sound/core/compress_offload.c |   13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
sound/core/compress_offload.c +9 -4
@@ -1083,15 +1083,18 @@ static int snd_compr_task_new(struct snd
 	   file descriptors are allocated before fd_install() */
 	if (!task->input || !task->input->file || !task->output || !task->output->file) {
 		retval = -EINVAL;
-		goto cleanup;
+		goto free_driver_task;
 	}
 	fd_i = get_unused_fd_flags(O_WRONLY|O_CLOEXEC);
-	if (fd_i < 0)
-		goto cleanup;
+	if (fd_i < 0) {
+		retval = fd_i;
+		goto free_driver_task;
+	}
 	fd_o = get_unused_fd_flags(O_RDONLY|O_CLOEXEC);
 	if (fd_o < 0) {
+		retval = fd_o;
 		put_unused_fd(fd_i);
-		goto cleanup;
+		goto free_driver_task;
 	}
 	/* keep dmabuf reference until freed with task free ioctl */
 	get_dma_buf(task->input);
@@ -1103,6 +1106,8 @@ static int snd_compr_task_new(struct snd
 	list_add_tail(&task->list, &stream->runtime->tasks);
 	stream->runtime->total_tasks++;
 	return 0;
+free_driver_task:
+	stream->ops->task_free(stream, task);
 cleanup:
 	snd_compr_task_free(task);
 	return retval;
author maintainer
#89 lore raw

PATCH 87/518 ALSA: es1938: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

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

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

From: Zhao Dongdong <[email protected]>

commit 1edd1f02dddd20aeb6066ded41017615766ea42f upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_es1938_mixer() does not check the return value before dereferencing the pointer, which can lead to a NULL pointer dereference.

Add a NULL check after snd_ctl_new1() and return -ENOMEM if it fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes 1da177e4c3f4 ("Linux-2.6.12-rc2")
---
 sound/pci/es1938.c |    2 ++
 1 file changed, 2 insertions(+)
sound/pci/es1938.c +2 -0
@@ -1655,6 +1655,8 @@ static int snd_es1938_mixer(struct es193
 	for (idx = 0; idx < ARRAY_SIZE(snd_es1938_controls); idx++) {
 		struct snd_kcontrol *kctl;
 		kctl = snd_ctl_new1(&snd_es1938_controls[idx], chip);
+		if (!kctl)
+			return -ENOMEM;
 		switch (idx) {
 			case 0:
 				chip->master_volume = kctl;
author maintainer
#90 lore raw

PATCH 88/518 ALSA: FCP: Add Focusrite ISA C8X support

In reply to Greg Kroah-Hartman

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

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

From: Geoffrey D. Bennett <[email protected]>

commit e0ecb324246be9cf3a0689346a658e48a38546b2 upstream.

Add USB PID 0x821e to the list of devices handled by the Focusrite Control Protocol (FCP) driver.

---
 sound/usb/mixer_quirks.c |    1 +
 1 file changed, 1 insertion(+)
sound/usb/mixer_quirks.c +1 -0
@@ -4451,6 +4451,7 @@ int snd_usb_mixer_apply_create_quirk(str
 	case USB_ID(0x1235, 0x821b): /* Focusrite Scarlett 16i16 4th Gen */
 	case USB_ID(0x1235, 0x821c): /* Focusrite Scarlett 18i16 4th Gen */
 	case USB_ID(0x1235, 0x821d): /* Focusrite Scarlett 18i20 4th Gen */
+	case USB_ID(0x1235, 0x821e): /* Focusrite ISA C8X */
 		err = snd_fcp_init(mixer);
 		break;
 
author maintainer
#91 lore raw

PATCH 89/518 ALSA: firewire: isight: bound the sample count to the packet payload

In reply to Greg Kroah-Hartman

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

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

From: Maoyi Xie <[email protected]>

commit 29b9667982e4df2ed7744f86b1144f8bb58eb698 upstream.

isight_packet() takes the frame count from the device iso packet and checks it only against the device claimed iso length.

	count = be32_to_cpu(payload->sample_count);
	if (likely(count <= (length - 16) / 4))
		isight_samples(isight, payload->samples, count);

length is the iso header data_length. It can be up to 0xffff. So the gate allows a count up to about 16379. isight_samples() then copies count frames out of payload->samples into the PCM DMA buffer.

payload->samples holds only 2 * MAX_FRAMES_PER_PACKET values. The device multiplexes two samples per frame. A count past MAX_FRAMES_PER_PACKET reads past the payload. A count past the buffer size writes past runtime->dma_area. The smallest PCM buffer is larger than MAX_FRAMES_PER_PACKET. Bounding the count to MAX_FRAMES_PER_PACKET keeps both the read and the write in range.

A malicious or faulty Apple iSight on the FireWire bus reaches this during a normal capture.

Add the MAX_FRAMES_PER_PACKET bound to the gate.

---
 sound/firewire/isight.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
sound/firewire/isight.c +2 -1
@@ -179,7 +179,8 @@ static void isight_packet(struct fw_iso_
 	if (likely(length >= 16 &&
 		   payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) {
 		count = be32_to_cpu(payload->sample_count);
-		if (likely(count <= (length - 16) / 4)) {
+		if (likely(count <= (length - 16) / 4 &&
+			   count <= MAX_FRAMES_PER_PACKET)) {
 			total = be32_to_cpu(payload->sample_total);
 			if (unlikely(total != isight->total_samples)) {
 				if (!isight->first_packet)
author maintainer
#92 lore raw

PATCH 90/518 ALSA: gus: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

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

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

From: Zhao Dongdong <[email protected]>

commit c7fa99d30c7a166a5e5db5a585ce7501ff68326b upstream.

snd_ctl_new1() can return NULL when memory allocation fails. snd_gf1_pcm_volume_control() does not check the return value before dereferencing kctl->id.index, which can lead to a NULL pointer dereference.

Add a NULL check after snd_ctl_new1() and return -ENOMEM if it fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes c5ae57b1bb99 ("ALSA: gus: Fix kctl->id initialization")
---
 sound/isa/gus/gus_pcm.c |    2 ++
 1 file changed, 2 insertions(+)
sound/isa/gus/gus_pcm.c +2 -0
@@ -851,6 +851,8 @@ int snd_gf1_pcm_new(struct snd_gus_card
 		kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control1, gus);
 	else
 		kctl = snd_ctl_new1(&snd_gf1_pcm_volume_control, gus);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.index = control_index;
 	err = snd_ctl_add(card, kctl);
 	if (err < 0)
author maintainer
#93 lore raw

PATCH 91/518 ALSA: hda/cs35l41: Fix firmware load work teardown

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit b65020d5398f499c09498c9786dba6d67ae57664 upstream.

cs35l41_hda creates ALSA controls whose private data points at the cs35l41_hda object. The firmware load control can also queue fw_load_work.

Those controls are not removed on component unbind, and device remove only cancels fw_load_work through cs35l41_remove_dsp(). That helper is skipped when halo_initialized is false. With firmware_autostart disabled, a firmware load can be requested before the DSP has been initialized. If the component or device is removed before the queued work runs, the worker can run after teardown and dereference driver state that is no longer valid.

Track the created controls and remove them on unbind so no new control callback can reach the driver data or queue more work. Then cancel fw_load_work to drain any request that was already queued. Also cancel the work unconditionally during device remove before runtime PM teardown.

Fixes 47ceabd99a28 ("ALSA: hda: cs35l41: Support Firmware switching and reloading")
Fixes 4c870513fbb0 ("ALSA: hda: cs35l41: Add read-only ALSA control for forced mute")
---
 sound/hda/codecs/side-codecs/cs35l41_hda.c |   77 ++++++++++++++++++++---------
 sound/hda/codecs/side-codecs/cs35l41_hda.h |    5 +
 2 files changed, 60 insertions(+), 22 deletions(-)
sound/hda/codecs/side-codecs/cs35l41_hda.c +55 -22
@@ -1325,6 +1325,43 @@ static int cs35l41_fw_type_ctl_info(stru
 	return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(cs35l41_hda_fw_ids), cs35l41_hda_fw_ids);
 }
 
+static void cs35l41_remove_controls(struct cs35l41_hda *cs35l41)
+{
+	if (!cs35l41->codec)
+		return;
+
+	snd_ctl_remove(cs35l41->codec->card, cs35l41->mute_override_ctl);
+	cs35l41->mute_override_ctl = NULL;
+
+	snd_ctl_remove(cs35l41->codec->card, cs35l41->fw_load_ctl);
+	cs35l41->fw_load_ctl = NULL;
+
+	snd_ctl_remove(cs35l41->codec->card, cs35l41->fw_type_ctl);
+	cs35l41->fw_type_ctl = NULL;
+}
+
+static int cs35l41_add_control(struct cs35l41_hda *cs35l41,
+			       struct snd_kcontrol_new *ctl,
+			       struct snd_kcontrol **kctl)
+{
+	int ret;
+
+	*kctl = snd_ctl_new1(ctl, cs35l41);
+	if (!*kctl)
+		return -ENOMEM;
+
+	ret = snd_ctl_add(cs35l41->codec->card, *kctl);
+	if (ret) {
+		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", ctl->name, ret);
+		*kctl = NULL;
+		return ret;
+	}
+
+	dev_dbg(cs35l41->dev, "Added Control %s\n", ctl->name);
+
+	return 0;
+}
+
 static int cs35l41_create_controls(struct cs35l41_hda *cs35l41)
 {
 	char fw_type_ctl_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
@@ -1360,32 +1397,23 @@ static int cs35l41_create_controls(struc
 	scnprintf(mute_override_ctl_name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s Forced Mute Status",
 		  cs35l41->amp_name);
 
-	ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_type_ctl, cs35l41));
-	if (ret) {
-		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_type_ctl.name, ret);
-		return ret;
-	}
-
-	dev_dbg(cs35l41->dev, "Added Control %s\n", fw_type_ctl.name);
-
-	ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&fw_load_ctl, cs35l41));
-	if (ret) {
-		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", fw_load_ctl.name, ret);
-		return ret;
-	}
-
-	dev_dbg(cs35l41->dev, "Added Control %s\n", fw_load_ctl.name);
+	ret = cs35l41_add_control(cs35l41, &fw_type_ctl, &cs35l41->fw_type_ctl);
+	if (ret)
+		goto err;
 
-	ret = snd_ctl_add(cs35l41->codec->card, snd_ctl_new1(&mute_override_ctl, cs35l41));
-	if (ret) {
-		dev_err(cs35l41->dev, "Failed to add KControl %s = %d\n", mute_override_ctl.name,
-			ret);
-		return ret;
-	}
+	ret = cs35l41_add_control(cs35l41, &fw_load_ctl, &cs35l41->fw_load_ctl);
+	if (ret)
+		goto err;
 
-	dev_dbg(cs35l41->dev, "Added Control %s\n", mute_override_ctl.name);
+	ret = cs35l41_add_control(cs35l41, &mute_override_ctl, &cs35l41->mute_override_ctl);
+	if (ret)
+		goto err;
 
 	return 0;
+
+err:
+	cs35l41_remove_controls(cs35l41);
+	return ret;
 }
 
 static bool cs35l41_dsm_supported(acpi_handle handle, unsigned int commands)
@@ -1522,6 +1550,10 @@ static void cs35l41_hda_unbind(struct de
 		device_link_remove(&cs35l41->codec->core.dev, cs35l41->dev);
 		unlock_system_sleep(sleep_flags);
 		memset(comp, 0, sizeof(*comp));
+
+		cs35l41_remove_controls(cs35l41);
+		cancel_work_sync(&cs35l41->fw_load_work);
+		cs35l41->codec = NULL;
 	}
 }
 
@@ -2060,6 +2092,7 @@ void cs35l41_hda_remove(struct device *d
 	struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
 
 	component_del(cs35l41->dev, &cs35l41_hda_comp_ops);
+	cancel_work_sync(&cs35l41->fw_load_work);
 
 	pm_runtime_get_sync(cs35l41->dev);
 	pm_runtime_dont_use_autosuspend(cs35l41->dev);
sound/hda/codecs/side-codecs/cs35l41_hda.h +5 -0
@@ -57,6 +57,8 @@ enum control_bus {
 	SPI
 };
 
+struct snd_kcontrol;
+
 struct cs35l41_hda {
 	struct device *dev;
 	struct regmap *regmap;
@@ -75,6 +77,9 @@ struct cs35l41_hda {
 	int speaker_id;
 	struct mutex fw_mutex;
 	struct work_struct fw_load_work;
+	struct snd_kcontrol *fw_type_ctl;
+	struct snd_kcontrol *fw_load_ctl;
+	struct snd_kcontrol *mute_override_ctl;
 
 	struct regmap_irq_chip_data *irq_data;
 	bool firmware_running;
author maintainer
#94 lore raw

PATCH 92/518 ALSA: hda/hdmi: Add force-connect quirk for HP EliteDesk 800 G5 Mini

In reply to Greg Kroah-Hartman

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

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

From: Cameron Graham <[email protected]>

commit 0ec17ee704615125c0b6e100c38129393a346bcc upstream.

The HP EliteDesk 800 G5 Mini (PCI subsystem 103c:8595) uses Cannon Lake PCH cAVS HDA with DisplayPort audio pins 0x05 and 0x06 set to AC_JACK_PORT_NONE (N/A) in BIOS defaults, causing hdmi_add_pin() to skip them and the DP audio device to not appear in ALSA.

Add the board to the existing force_connect_list alongside the similar HP EliteDesk 800 G4 entries.

---
 sound/hda/codecs/hdmi/hdmi.c |    1 +
 1 file changed, 1 insertion(+)
sound/hda/codecs/hdmi/hdmi.c +1 -0
@@ -1549,6 +1549,7 @@ static const struct snd_pci_quirk force_
 	SND_PCI_QUIRK(0x103c, 0x83e2, "HP EliteDesk 800 G4", 1),
 	SND_PCI_QUIRK(0x103c, 0x83ef, "HP MP9 G4 Retail System AMS", 1),
 	SND_PCI_QUIRK(0x103c, 0x845a, "HP EliteDesk 800 G4 DM 65W", 1),
+	SND_PCI_QUIRK(0x103c, 0x8595, "HP EliteDesk 800 G5 Mini", 1),
 	SND_PCI_QUIRK(0x103c, 0x83f3, "HP ProDesk 400", 1),
 	SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1),
 	SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1),
author maintainer
#95 lore raw

PATCH 93/518 ALSA: hda/hdmi: Use AC_PINSENSE_ELDV to detect pinsense for Loongson

In reply to Greg Kroah-Hartman

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

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

From: Huacai Chen <[email protected]>

commit 958e4450e961d75bd9d8f5bfe245fb15bc78e02a upstream.

Due to a hardware defect, for Loongson PCI HDMI devices with a reversion ID of 2, the pin sense status must be determined via the ELD.

Add a codec flag, eld_jack_detect, to indicate this case, and do special handlings in read_pin_sense().

---
 include/sound/hda_codec.h    |    1 +
 sound/hda/codecs/hdmi/hdmi.c |    8 +++++++-
 sound/hda/common/jack.c      |    6 ++++++
 3 files changed, 14 insertions(+), 1 deletion(-)
include/sound/hda_codec.h +1 -0
@@ -259,6 +259,7 @@ struct hda_codec {
 	unsigned int forced_resume:1; /* forced resume for jack */
 	unsigned int no_stream_clean_at_suspend:1; /* do not clean streams at suspend */
 	unsigned int ctl_dev_id:1; /* old control element id build behaviour */
+	unsigned int eld_jack_detect:1;	/* Machine jack-detection by ELD */
 
 	unsigned long power_on_acct;
 	unsigned long power_off_acct;
sound/hda/codecs/hdmi/hdmi.c +7 -1
@@ -2286,6 +2286,7 @@ EXPORT_SYMBOL_NS_GPL(snd_hda_hdmi_acomp_
 enum {
 	MODEL_GENERIC,
 	MODEL_GF,
+	MODEL_LOONGSON,
 };
 
 static int generichdmi_probe(struct hda_codec *codec,
@@ -2303,6 +2304,11 @@ static int generichdmi_probe(struct hda_
 	if (id->driver_data == MODEL_GF)
 		codec->no_sticky_stream = 1;
 
+	if (id->driver_data == MODEL_LOONGSON) {
+		if (codec->bus && codec->bus->pci->revision == 0x2)
+			codec->eld_jack_detect = 1; /* Jack-detection by ELD */
+	}
+
 	return 0;
 }
 
@@ -2320,7 +2326,7 @@ static const struct hda_codec_ops generi
 /*
  */
 static const struct hda_device_id snd_hda_id_generichdmi[] = {
-	HDA_CODEC_ID_MODEL(0x00147a47, "Loongson HDMI",		MODEL_GENERIC),
+	HDA_CODEC_ID_MODEL(0x00147a47, "Loongson HDMI",		MODEL_LOONGSON),
 	HDA_CODEC_ID_MODEL(0x10951390, "SiI1390 HDMI",		MODEL_GENERIC),
 	HDA_CODEC_ID_MODEL(0x10951392, "SiI1392 HDMI",		MODEL_GENERIC),
 	HDA_CODEC_ID_MODEL(0x11069f84, "VX11 HDMI/DP",		MODEL_GENERIC),
sound/hda/common/jack.c +6 -0
@@ -58,6 +58,12 @@ static u32 read_pin_sense(struct hda_cod
 				  AC_VERB_GET_PIN_SENSE, dev_id);
 	if (codec->inv_jack_detect)
 		val ^= AC_PINSENSE_PRESENCE;
+	if (codec->eld_jack_detect) {
+		if (val & AC_PINSENSE_ELDV)
+			val |= AC_PINSENSE_PRESENCE;
+		else
+			val &= ~AC_PINSENSE_PRESENCE;
+	}
 	return val;
 }
 
author maintainer
#96 lore raw

PATCH 94/518 ALSA: hda/realtek: Fix noisy mic for Clevo V6xxAW

In reply to Greg Kroah-Hartman

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

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

From: Aaron Erhardt <[email protected]>

commit 493765b8e922a506e09e22e80b6cc9ff05e8295b upstream.

Add a PCI quirk to reduce the volume of the internal microphone to prevent extremely noisy signal.

---
 sound/hda/codecs/realtek/alc269.c |    1 +
 1 file changed, 1 insertion(+)
sound/hda/codecs/realtek/alc269.c +1 -0
@@ -7567,6 +7567,7 @@ static const struct hda_quirk alc269_fix
 	SND_PCI_QUIRK(0x1558, 0x51b3, "Clevo NS70AU", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x5630, "Clevo NP50RNJS", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x5700, "Clevo X560WN[RST]", ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
+	SND_PCI_QUIRK(0x1558, 0x6480, "Clevo V6xxAW", ALC245_FIXUP_CLEVO_NOISY_MIC),
 	SND_PCI_QUIRK(0x1558, 0x70a1, "Clevo NB70T[HJK]", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x70b3, "Clevo NK70SB", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
 	SND_PCI_QUIRK(0x1558, 0x70f2, "Clevo NH79EPY", ALC293_FIXUP_SYSTEM76_MIC_NO_PRESENCE),
author maintainer
#97 lore raw

PATCH 95/518 ALSA: ice1712: check snd_ctl_new1() return value

In reply to Greg Kroah-Hartman

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

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

From: Zhao Dongdong <[email protected]>

commit 2b929b91b0f3bc6de8a844370049cd99ee8e31ff upstream.

snd_ctl_new1() can return NULL when memory allocation fails. The ice1712 driver calls snd_ctl_new1() without checking the return value before dereferencing the pointer in multiple places (ice1712.c, ice1724.c, aureon.c), which can lead to NULL pointer dereferences.

Add NULL checks after snd_ctl_new1() calls and return -ENOMEM if any fails.

Assisted-by Opencode:DeepSeek-V4-Flash
Fixes b9a4efd61b6b ("ALSA: ice1712,ice1724: fix the kcontrol->id initialization")
---
 sound/pci/ice1712/aureon.c  |    2 ++
 sound/pci/ice1712/ice1712.c |    8 ++++++++
 sound/pci/ice1712/ice1724.c |    6 ++++++
 3 files changed, 16 insertions(+)
sound/pci/ice1712/aureon.c +2 -0
@@ -1891,6 +1891,8 @@ static int aureon_add_controls(struct sn
 			for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) {
 				struct snd_kcontrol *kctl;
 				kctl = snd_ctl_new1(&cs8415_controls[i], ice);
+				if (!kctl)
+					return -ENOMEM;
 				if (i > 1)
 					kctl->id.device = ice->pcm->device;
 				err = snd_ctl_add(ice->card, kctl);
sound/pci/ice1712/ice1712.c +8 -0
@@ -2346,21 +2346,29 @@ int snd_ice1712_spdif_build_controls(str
 	if (snd_BUG_ON(!ice->pcm_pro))
 		return -EIO;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_maskc, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_maskp, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_ice1712_spdif_stream, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm_pro->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
sound/pci/ice1712/ice1724.c +6 -0
@@ -2379,16 +2379,22 @@ static int snd_vt1724_spdif_build_contro
 		return err;
 
 	kctl = snd_ctl_new1(&snd_vt1724_spdif_default, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_vt1724_spdif_maskc, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
 		return err;
 	kctl = snd_ctl_new1(&snd_vt1724_spdif_maskp, ice);
+	if (!kctl)
+		return -ENOMEM;
 	kctl->id.device = ice->pcm->device;
 	err = snd_ctl_add(ice->card, kctl);
 	if (err < 0)
author maintainer
#98 lore raw

PATCH 96/518 ALSA: seq: Fix uninitialised heap leak in snd_seq_event_dup()

In reply to Greg Kroah-Hartman

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

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

From: HyeongJun An <[email protected]>

commit 435990e25bf1f4af3e6df12a6fbfd1f7ba4a97d4 upstream.

snd_seq_event_dup() copies an incoming event into a pool cell and, in the UMP-enabled build, clears the trailing cell->ump.raw.extra word that the memcpy() did not cover. The guard deciding whether to clear it compares the copied size against sizeof(cell->event):

	memcpy(&cell->ump, event, size);
	if (size < sizeof(cell->event))
		cell->ump.raw.extra = 0;

For a legacy (non-UMP) event, size == sizeof(struct snd_seq_event) == sizeof(cell->event), so the condition is false and the extra word keeps stale data. The cell pool is allocated with kvmalloc() (not zeroed) and cells are reused via a free list, so that word holds uninitialised heap or leftover event data.

When such a cell is delivered to a UMP client (client->midi_version > 0) that set SNDRV_SEQ_FILTER_NO_CONVERT -- so the legacy event reaches it unconverted -- snd_seq_read() reads it out as the larger struct snd_seq_ump_event and copies the stale word to user space, a 4-byte kernel heap infoleak to an unprivileged /dev/snd/seq client.

Compare against sizeof(cell->ump) instead, so the trailing word is zeroed for every event shorter than the UMP cell.

Fixes 46397622a3fa ("ALSA: seq: Add UMP support")
Assisted-by Claude:claude-opus-4-8
---
 sound/core/seq/seq_memory.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/core/seq/seq_memory.c +1 -1
@@ -364,7 +364,7 @@ int snd_seq_event_dup(struct snd_seq_poo
 	size = snd_seq_event_packet_size(event);
 	memcpy(&cell->ump, event, size);
 #if IS_ENABLED(CONFIG_SND_SEQ_UMP)
-	if (size < sizeof(cell->event))
+	if (size < sizeof(cell->ump))
 		cell->ump.raw.extra = 0;
 #endif
 
author maintainer
#99 lore raw

PATCH 97/518 ALSA: us144mkii: capture_urb_complete: redundant usb_anchor_urb corrupts anchor list on each resubmission

In reply to Greg Kroah-Hartman

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

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

From: WenTao Liang <[email protected]>

commit 5cff1529a2f9b3461a7f5a6e36a86682fc290534 upstream.

In capture_urb_complete(), usb_anchor_urb() is called on every completion callback, but the URB is already anchored from the initial submission in tascam_trigger_start(). Each redundant call corrupts the anchor's doubly-linked list and inflates the URB refcount. When usb_kill_anchored_urbs() traverses the list during stream stop / suspend / disconnect, the corrupted list leads to use-after-free.

Remove the redundant usb_anchor_urb() from the resubmit path.

Fixes c1bb0c13e430 ("ALSA: usb-audio: us144mkii: Implement audio capture and decoding")
---
 sound/usb/usx2y/us144mkii_capture.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/usx2y/us144mkii_capture.c +1 -1
@@ -302,7 +302,6 @@ void capture_urb_complete(struct urb *ur
 	}
 
 	usb_get_urb(urb);
-	usb_anchor_urb(urb, &tascam->capture_anchor);
 	ret = usb_submit_urb(urb, GFP_ATOMIC);
 	if (ret < 0) {
 		dev_err_ratelimited(tascam->card->dev,
@@ -312,6 +311,7 @@ void capture_urb_complete(struct urb *ur
 		usb_put_urb(urb);
 		atomic_dec(
 			&tascam->active_urbs); /* Decrement on failed resubmission */
+		return;
 	}
 out:
 	usb_put_urb(urb);
author maintainer
#100 lore raw

PATCH 98/518 ALSA: usb-audio: add IFB_SILENCE_ON_EMPTY quirk for Behringer Flow 8

In reply to Greg Kroah-Hartman

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

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

From: Gordon Chen <[email protected]>

commit a23812004228d4b041a858b927db787a7ff80f50 upstream.

The Behringer Flow 8 (1397:050c) is an 8-channel USB mixer that declares OUT EP 0x01 with implicit feedback from capture EP 0x81 via its UAC2 endpoint companion descriptor. After 5-35 minutes of continuous playback, the device occasionally returns a capture URB in which every iso_frame_desc has a non-zero status (-EXDEV bursts, visible as rate-limited "frame N active: -18" lines in dmesg from pcm.c).

In that case snd_usb_handle_sync_urb() at endpoint.c counts bytes==0 and falls into the early "skip empty packets" return originally added for M-Audio Fast Track Ultra. As a result the playback EP loses its sole IFB-driven feeder and the OUT ring starves permanently: hw_ptr stops advancing while substream state remains RUNNING. Only USB re-enumeration recovers.

Three independent ftrace captures (taken at the moment of stall via a userspace watchdog) consistently show:

- 60-70 capture URB completions in the 70ms window before the marker
- 0 retire_playback_urb / queue_pending_output_urbs / snd_usb_endpoint_implicit_feedback_sink calls
- every usb_submit_urb in the window comes from

    snd_complete_urb+0x64e (capture self-resubmit), none from the
    queue_pending_output_urbs path

Add a new opt-in quirk QUIRK_FLAG_IFB_SILENCE_ON_EMPTY: when set, the early return is skipped and we fall through to enqueue a packet_info whose packet_size[i] are all 0 (the existing loop already maps status!=0 packets to size 0). prepare_outbound_urb then emits a silence packet, the OUT ring keeps moving, and the device rides through the glitch.

The default behaviour (early return) is preserved for all existing devices including M-Audio Fast Track Ultra. Only Flow 8 opts in here.

---
 sound/usb/endpoint.c |   10 +++++++++-
 sound/usb/quirks.c   |    3 +++
 sound/usb/usbaudio.h |    8 ++++++++
 3 files changed, 20 insertions(+), 1 deletion(-)
sound/usb/endpoint.c +9 -1
@@ -1780,8 +1780,16 @@ static void snd_usb_handle_sync_urb(stru
 		/*
 		 * skip empty packets. At least M-Audio's Fast Track Ultra stops
 		 * streaming once it received a 0-byte OUT URB
+		 *
+		 * However, on devices where bytes==0 means every sync-source
+		 * packet errored (e.g. Behringer Flow 8 returning -EXDEV bursts
+		 * for entire capture URBs), an unconditional return starves the
+		 * IFB-fed OUT ring permanently. Such devices set
+		 * QUIRK_FLAG_IFB_SILENCE_ON_EMPTY to fall through and enqueue a
+		 * packet_info with size 0 packets, so playback emits silence
+		 * and the OUT ring keeps moving.
 		 */
-		if (bytes == 0)
+		if (bytes == 0 && !(ep->chip->quirk_flags & QUIRK_FLAG_IFB_SILENCE_ON_EMPTY))
 			return;
 
 		spin_lock_irqsave(&ep->lock, flags);
sound/usb/quirks.c +3 -0
@@ -2365,6 +2365,8 @@ static const struct usb_audio_quirk_flag
 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
 	DEVICE_FLG(0x1397, 0x0509, /* Behringer UMC404HD */
 		   QUIRK_FLAG_PLAYBACK_FIRST | QUIRK_FLAG_GENERIC_IMPLICIT_FB),
+	DEVICE_FLG(0x1397, 0x050c, /* Behringer Flow 8 */
+		   QUIRK_FLAG_IFB_SILENCE_ON_EMPTY),
 	DEVICE_FLG(0x13e5, 0x0001, /* Serato Phono */
 		   QUIRK_FLAG_IGNORE_CTL_ERROR),
 	DEVICE_FLG(0x152a, 0x880a, /* NeuralDSP Quad Cortex */
@@ -2606,6 +2608,7 @@ static const char *const snd_usb_audio_q
 	QUIRK_STRING_ENTRY(SKIP_IFACE_SETUP),
 	QUIRK_STRING_ENTRY(MIXER_PLAYBACK_LINEAR_VOL),
 	QUIRK_STRING_ENTRY(MIXER_CAPTURE_LINEAR_VOL),
+	QUIRK_STRING_ENTRY(IFB_SILENCE_ON_EMPTY),
 	NULL
 };
 
sound/usb/usbaudio.h +8 -0
@@ -236,6 +236,12 @@ extern bool snd_usb_skip_validation;
  * QUIRK_FLAG_MIXER_CAPTURE_LINEAR_VOL
  *  Similar to QUIRK_FLAG_MIXER_PLAYBACK_LINEAR_VOL, but for capture streams.
  *  Overrides QUIRK_FLAG_MIXER_CAPTURE_MIN_MUTE
+ * QUIRK_FLAG_IFB_SILENCE_ON_EMPTY
+ *  In implicit feedback mode, when an entire capture URB returns with
+ *  all iso_frame_desc[i].status != 0 (bytes==0), do not silently return
+ *  from snd_usb_handle_sync_urb. Instead fall through and enqueue a
+ *  packet_info containing only size-0 packets, so the OUT ring keeps
+ *  moving (emits silence). Needed by Behringer Flow 8 (1397:050c).
  */
 
 enum {
@@ -268,6 +274,7 @@ enum {
 	QUIRK_TYPE_SKIP_IFACE_SETUP		= 26,
 	QUIRK_TYPE_MIXER_PLAYBACK_LINEAR_VOL	= 27,
 	QUIRK_TYPE_MIXER_CAPTURE_LINEAR_VOL	= 28,
+	QUIRK_TYPE_IFB_SILENCE_ON_EMPTY		= 29,
 /* Please also edit snd_usb_audio_quirk_flag_names */
 };
 
@@ -302,5 +309,6 @@ enum {
 #define QUIRK_FLAG_SKIP_IFACE_SETUP		QUIRK_FLAG(SKIP_IFACE_SETUP)
 #define QUIRK_FLAG_MIXER_PLAYBACK_LINEAR_VOL	QUIRK_FLAG(MIXER_PLAYBACK_LINEAR_VOL)
 #define QUIRK_FLAG_MIXER_CAPTURE_LINEAR_VOL	QUIRK_FLAG(MIXER_CAPTURE_LINEAR_VOL)
+#define QUIRK_FLAG_IFB_SILENCE_ON_EMPTY		QUIRK_FLAG(IFB_SILENCE_ON_EMPTY)
 
 #endif /* __USBAUDIO_H */
author maintainer
#101 lore raw

PATCH 99/518 ALSA: usb-audio: avoid kobject path lookup in DualSense match

In reply to Greg Kroah-Hartman

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

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

From: Darvell Long <[email protected]>

commit 7693c0cc415f3a16a7a3355f245474a5e661be4e upstream.

The DualSense jack-detection input handler verifies that a matching input device belongs to the same physical controller by building kobject path strings for both the input device and the USB audio device, then comparing the path prefix.

This was observed when a weak physical connection caused the controller to rapidly disconnect and reconnect. During that repeated hotplug, snd_dualsense_ih_match() can run while the controller's USB device is being disconnected. kobject_get_path() walks ancestor kobjects and dereferences their names; if the USB device kobject name is no longer valid, this can fault in strlen():

  RIP: 0010:strlen+0x10/0x30
  Call Trace:
   kobject_get_path+0x34/0x150
   snd_dualsense_ih_match+0x49/0xd0 [snd_usb_audio]
   input_register_device+0x566/0x6a0
   ps_probe+0xb89/0x1590 [hid_playstation]

The same ownership check can be done without building kobject path strings. The input device is parented below the HID device, USB interface and USB device, so walking the input device parent chain and comparing against the mixer USB device preserves the check without dereferencing kobject names during disconnect.

Fixes 79d561c4ec04 ("ALSA: usb-audio: Add mixer quirk for Sony DualSense PS5")
Assisted-by Cute:gpt-5.5
---
 sound/usb/mixer_quirks.c |   40 ++++++++++++----------------------------
 1 file changed, 12 insertions(+), 28 deletions(-)
sound/usb/mixer_quirks.c +12 -28
@@ -567,46 +567,30 @@ static bool snd_dualsense_ih_match(struc
 {
 	struct dualsense_mixer_elem_info *mei;
 	struct usb_device *snd_dev;
-	char *input_dev_path, *usb_dev_path;
-	size_t usb_dev_path_len;
-	bool match = false;
+	struct device *parent;
 
 	mei = container_of(handler, struct dualsense_mixer_elem_info, ih);
 	snd_dev = mei->info.head.mixer->chip->dev;
 
-	input_dev_path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
-	if (!input_dev_path) {
-		dev_warn(&snd_dev->dev, "Failed to get input dev path\n");
-		return false;
-	}
-
-	usb_dev_path = kobject_get_path(&snd_dev->dev.kobj, GFP_KERNEL);
-	if (!usb_dev_path) {
-		dev_warn(&snd_dev->dev, "Failed to get USB dev path\n");
-		goto free_paths;
-	}
-
 	/*
 	 * Ensure the VID:PID matched input device supposedly owned by the
 	 * hid-playstation driver belongs to the actual hardware handled by
-	 * the current USB audio device, which implies input_dev_path being
-	 * a subpath of usb_dev_path.
+	 * the current USB audio device.
 	 *
 	 * This verification is necessary when there is more than one identical
 	 * controller attached to the host system.
+	 *
+	 * The input device is registered below the HID device, USB interface and
+	 * USB device, so compare the parent chain directly instead of building
+	 * kobject path strings. This avoids dereferencing kobject names while the
+	 * USB device hierarchy is being torn down during disconnect.
 	 */
-	usb_dev_path_len = strlen(usb_dev_path);
-	if (usb_dev_path_len >= strlen(input_dev_path))
-		goto free_paths;
-
-	usb_dev_path[usb_dev_path_len] = '/';
-	match = !memcmp(input_dev_path, usb_dev_path, usb_dev_path_len + 1);
-
-free_paths:
-	kfree(input_dev_path);
-	kfree(usb_dev_path);
+	for (parent = dev->dev.parent; parent; parent = parent->parent) {
+		if (parent == &snd_dev->dev)
+			return true;
+	}
 
-	return match;
+	return false;
 }
 
 static int snd_dualsense_ih_connect(struct input_handler *handler,
author maintainer
#102 lore raw

PATCH 100/518 ALSA: usb-audio: Propagate errors in scarlett_ctl_enum_put()

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 0f25cf1f02e3dba626791d949c759a48c0a44996 upstream.

scarlett_ctl_enum_put() ignores the return value from snd_usb_set_cur_mix_value() and reports success whenever the requested enum value differs from the current one.

If the SET_CUR request fails, the callback still returns success even though neither the hardware state nor the cached mixer value changed.

Fixes 76b188c4b370 ("ALSA: usb-audio: Scarlett mixer interface for 6i6, 18i6, 18i8 and 18i20")
---
 sound/usb/mixer_scarlett.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
sound/usb/mixer_scarlett.c +3 -1
@@ -680,7 +680,9 @@ static int scarlett_ctl_enum_put(struct
 	val = ucontrol->value.integer.value[0];
 	val = val + opt->start;
 	if (val != oval) {
-		snd_usb_set_cur_mix_value(elem, 0, 0, val);
+		err = snd_usb_set_cur_mix_value(elem, 0, 0, val);
+		if (err < 0)
+			return err;
 		return 1;
 	}
 	return 0;
author maintainer
#103 lore raw

PATCH 101/518 ALSA: usb-audio: Propagate US-16x08 write errors in route/mix EQ-switch put callbacks

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 3c06aec8abda6ba068b58a8b7119cdb2a48456b1 upstream.

Several US-16x08 mixer put callbacks log failed control URBs but still return success to userspace. That hides device write failures even though the requested value was not applied.

Return the negative write error instead in the route, master, bus, channel, and EQ switch put callbacks.

Fixes d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
---
 sound/usb/mixer_us16x08.c |   49 ++++++++++++++++++++++------------------------
 1 file changed, 24 insertions(+), 25 deletions(-)
sound/usb/mixer_us16x08.c +24 -25
@@ -224,14 +224,14 @@ static int snd_us16x08_route_put(struct
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(route_msg));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set routing, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_master_info(struct snd_kcontrol *kcontrol,
@@ -283,14 +283,14 @@ static int snd_us16x08_master_put(struct
 	buf[5] = index + 1;
 	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_out));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set master, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_bus_put(struct snd_kcontrol *kcontrol,
@@ -324,14 +324,14 @@ static int snd_us16x08_bus_put(struct sn
 		break;
 	}
 
-	if (err > 0) {
-		elem->cached |= 1;
-		elem->cache_val[0] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set bus parameter, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1;
+	elem->cache_val[0] = val;
+	return 1;
 }
 
 static int snd_us16x08_bus_get(struct snd_kcontrol *kcontrol,
@@ -392,14 +392,14 @@ static int snd_us16x08_channel_put(struc
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(mix_msg_in));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set channel, err:%d\n", err);
+		return err;
 	}
 
-	return err > 0 ? 1 : 0;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
+	return 1;
 }
 
 static int snd_us16x08_mix_info(struct snd_kcontrol *kcontrol,
@@ -529,13 +529,13 @@ static int snd_us16x08_eqswitch_put(stru
 		msleep(15);
 	}
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set eq switch, err:%d\n", err);
+		return err;
 	}
 
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
@@ -1418,4 +1418,3 @@ int snd_us16x08_controls_create(struct u
 
 	return 0;
 }
-
author maintainer
#104 lore raw

PATCH 102/518 ALSA: usb-audio: Roll back quirk control caches on write errors

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit 6380957fa24251856a532e48a46a4dc3d1ae26b6 upstream.

Several mixer quirk callbacks cache the requested
control value in kcontrol->private_value before
issuing a single vendor or class write.

Their paired get and resume paths consume that cache directly, so a failed write currently leaves software state changed even though the update did not succeed. That can make later reads report a value the device never accepted and can replay the stale cache on resume.

Restore the previous cached value on failure in
the Audigy2NX LED, Emu0204 channel switch,
Xonar U1 output switch, Native Instruments controls,
FTU effect program switch, and Sound Blaster E1 input source switch.

Fixes 9cf3689bfe07 ("ALSA: usb-audio: Add audigy2nx resume support")
Fixes 5f503ee9e270 ("ALSA: usb-audio: Add Emu0204 channel switch resume support")
Fixes 2bfb14c3b8fb ("ALSA: usb-audio: Add Xonar U1 resume support")
Fixes da6d276957ea ("ALSA: usb-audio: Add resume support for Native Instruments controls")
Fixes 0b4e9cfcef05 ("ALSA: usb-audio: Add resume support for FTU controls")
Fixes 388fdb8f882a ("ALSA: usb-audio: Support changing input on Sound Blaster E1")
---
 sound/usb/mixer_quirks.c |   45 +++++++++++++++++++++++++++++++++++++--------
 1 file changed, 37 insertions(+), 8 deletions(-)
sound/usb/mixer_quirks.c +37 -8
@@ -333,6 +333,7 @@ static int snd_audigy2nx_led_put(struct
 	int index = kcontrol->private_value & 0xff;
 	unsigned int value = ucontrol->value.integer.value[0];
 	int old_value = kcontrol->private_value >> 8;
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (value > 1)
@@ -341,7 +342,11 @@ static int snd_audigy2nx_led_put(struct
 		return 0;
 	kcontrol->private_value = (value << 8) | index;
 	err = snd_audigy2nx_led_update(mixer, value, index);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_audigy2nx_led_resume(struct usb_mixer_elem_list *list)
@@ -487,6 +492,7 @@ static int snd_emu0204_ch_switch_put(str
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
 	struct usb_mixer_interface *mixer = list->mixer;
 	unsigned int value = ucontrol->value.enumerated.item[0];
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (value > 1)
@@ -497,7 +503,11 @@ static int snd_emu0204_ch_switch_put(str
 
 	kcontrol->private_value = value;
 	err = snd_emu0204_ch_switch_update(mixer, value);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_emu0204_ch_switch_resume(struct usb_mixer_elem_list *list)
@@ -805,7 +815,11 @@ static int snd_xonar_u1_switch_put(struc
 
 	kcontrol->private_value = new_status;
 	err = snd_xonar_u1_switch_update(list->mixer, new_status);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_status;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_xonar_u1_switch_resume(struct usb_mixer_elem_list *list)
@@ -1143,7 +1157,8 @@ static int snd_nativeinstruments_control
 					     struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
-	u8 oldval = (kcontrol->private_value >> 24) & 0xff;
+	unsigned long old_pval = kcontrol->private_value;
+	u8 oldval = (old_pval >> 24) & 0xff;
 	u8 newval = ucontrol->value.integer.value[0];
 	int err;
 
@@ -1153,7 +1168,11 @@ static int snd_nativeinstruments_control
 	kcontrol->private_value &= ~(0xff << 24);
 	kcontrol->private_value |= (unsigned int)newval << 24;
 	err = snd_ni_update_cur_val(list);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static const struct snd_kcontrol_new snd_nativeinstruments_ta6_mixers[] = {
@@ -1308,7 +1327,8 @@ static int snd_ftu_eff_switch_put(struct
 				  struct snd_ctl_elem_value *ucontrol)
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kctl);
-	unsigned int pval = list->kctl->private_value;
+	unsigned long old_pval = list->kctl->private_value;
+	unsigned int pval = old_pval;
 	int cur_val, err, new_val;
 
 	cur_val = pval >> 24;
@@ -1319,7 +1339,11 @@ static int snd_ftu_eff_switch_put(struct
 	kctl->private_value &= ~(0xff << 24);
 	kctl->private_value |= new_val << 24;
 	err = snd_ftu_eff_switch_update(list);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kctl->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_ftu_create_effect_switch(struct usb_mixer_interface *mixer,
@@ -2098,13 +2122,18 @@ static int snd_soundblaster_e1_switch_pu
 {
 	struct usb_mixer_elem_list *list = snd_kcontrol_chip(kcontrol);
 	unsigned char value = !!ucontrol->value.integer.value[0];
+	unsigned long old_pval = kcontrol->private_value;
 	int err;
 
 	if (kcontrol->private_value == value)
 		return 0;
 	kcontrol->private_value = value;
 	err = snd_soundblaster_e1_switch_update(list->mixer, value);
-	return err < 0 ? err : 1;
+	if (err < 0) {
+		kcontrol->private_value = old_pval;
+		return err;
+	}
+	return 1;
 }
 
 static int snd_soundblaster_e1_switch_resume(struct usb_mixer_elem_list *list)
author maintainer
#105 lore raw

PATCH 103/518 ALSA: usb-audio: Update Babyface Pro control caches only after successful writes

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit d8f802ccf1fdbeb89d62748d6a0d0fbd442c8127 upstream.

snd_bbfpro_ctl_put() and snd_bbfpro_vol_put() cache the requested packed control state in kcontrol->private_value before issuing the USB write.

Their get and resume paths use that cached value directly, so a failed write can leave the driver reporting and later replaying a setting the hardware never accepted.

Update the cached state only after a successful USB write.

---
 sound/usb/mixer_quirks.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)
sound/usb/mixer_quirks.c +10 -6
@@ -3011,12 +3011,14 @@ static int snd_bbfpro_ctl_put(struct snd
 	if (val == old_value)
 		return 0;
 
+	err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
+	if (err < 0)
+		return err;
+
 	kcontrol->private_value = reg
 		| ((idx & SND_BBFPRO_CTL_IDX_MASK) << SND_BBFPRO_CTL_IDX_SHIFT)
 		| ((val & SND_BBFPRO_CTL_VAL_MASK) << SND_BBFPRO_CTL_VAL_SHIFT);
-
-	err = snd_bbfpro_ctl_update(mixer, reg, idx, val);
-	return err < 0 ? err : 1;
+	return 1;
 }
 
 static int snd_bbfpro_ctl_resume(struct usb_mixer_elem_list *list)
@@ -3201,11 +3203,13 @@ static int snd_bbfpro_vol_put(struct snd
 
 	new_val = uvalue & SND_BBFPRO_MIXER_VAL_MASK;
 
+	err = snd_bbfpro_vol_update(mixer, idx, new_val);
+	if (err < 0)
+		return err;
+
 	kcontrol->private_value = idx
 		| (new_val << SND_BBFPRO_MIXER_VAL_SHIFT);
-
-	err = snd_bbfpro_vol_update(mixer, idx, new_val);
-	return err < 0 ? err : 1;
+	return 1;
 }
 
 static int snd_bbfpro_vol_resume(struct usb_mixer_elem_list *list)
author maintainer
#106 lore raw

PATCH 104/518 ALSA: usb-audio: Update US-16x08 EQ/comp shadow state after successful writes

In reply to Greg Kroah-Hartman

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

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

From: Cássio Gabriel <[email protected]>

commit a440c17869ecd71da0f295b62868fc742d09a8ba upstream.

snd_us16x08_comp_put() and snd_us16x08_eq_put() update their software stores before sending the USB write. If the transfer fails, later get callbacks report a value the hardware never accepted.

Build the outgoing message from the current store plus the pending value, then commit the store only after a successful write.

Fixes d2bb390a2081 ("ALSA: usb-audio: Tascam US-16x08 DSP mixer quirk")
---
 sound/usb/mixer_us16x08.c |   78 ++++++++++++++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 26 deletions(-)
sound/usb/mixer_us16x08.c +52 -26
@@ -435,6 +435,7 @@ static int snd_us16x08_comp_put(struct s
 	int index = ucontrol->id.index;
 	char buf[sizeof(comp_msg)];
 	int val_idx, val;
+	int threshold, ratio, attack, release, gain, switch_on;
 	int err;
 
 	val = ucontrol->value.integer.value[0];
@@ -447,36 +448,61 @@ static int snd_us16x08_comp_put(struct s
 	/* new control value incl. bias*/
 	val_idx = elem->head.id - SND_US16X08_ID_COMP_BASE;
 
-	store->val[val_idx][index] = ucontrol->value.integer.value[0];
+	threshold = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)]
+		[index];
+	ratio = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index];
+	attack = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index];
+	release = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)]
+		[index];
+	gain = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
+	switch_on = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)]
+		[index];
+
+	switch (val_idx) {
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD):
+		threshold = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO):
+		ratio = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK):
+		attack = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE):
+		release = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN):
+		gain = val;
+		break;
+	case COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH):
+		switch_on = val;
+		break;
+	}
 
 	/* prepare compressor URB message from template  */
 	memcpy(buf, comp_msg, sizeof(comp_msg));
 
 	/* place comp values in message buffer watch bias! */
-	buf[8] = store->val[
-		COMP_STORE_IDX(SND_US16X08_ID_COMP_THRESHOLD)][index]
-		- SND_US16X08_COMP_THRESHOLD_BIAS;
-	buf[11] = ratio_map[store->val[
-		COMP_STORE_IDX(SND_US16X08_ID_COMP_RATIO)][index]];
-	buf[14] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_ATTACK)][index]
-		+ SND_US16X08_COMP_ATTACK_BIAS;
-	buf[17] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_RELEASE)][index]
-		+ SND_US16X08_COMP_RELEASE_BIAS;
-	buf[20] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_GAIN)][index];
-	buf[26] = store->val[COMP_STORE_IDX(SND_US16X08_ID_COMP_SWITCH)][index];
+	buf[8] = threshold - SND_US16X08_COMP_THRESHOLD_BIAS;
+	buf[11] = ratio_map[ratio];
+	buf[14] = attack + SND_US16X08_COMP_ATTACK_BIAS;
+	buf[17] = release + SND_US16X08_COMP_RELEASE_BIAS;
+	buf[20] = gain;
+	buf[26] = switch_on;
 
 	/* place channel selector in message buffer */
 	buf[5] = index + 1;
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(comp_msg));
 
-	if (err > 0) {
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set compressor, err:%d\n", err);
+		return err;
 	}
 
+	store->val[val_idx][index] = val;
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
@@ -578,11 +604,10 @@ static int snd_us16x08_eq_put(struct snd
 	/* copy URB buffer from EQ template */
 	memcpy(buf, eqs_msq, sizeof(eqs_msq));
 
-	store->val[b_idx][p_idx][index] = val;
-	buf[20] = store->val[b_idx][3][index];
-	buf[17] = store->val[b_idx][2][index];
-	buf[14] = store->val[b_idx][1][index];
-	buf[11] = store->val[b_idx][0][index];
+	buf[20] = p_idx == 3 ? val : store->val[b_idx][3][index];
+	buf[17] = p_idx == 2 ? val : store->val[b_idx][2][index];
+	buf[14] = p_idx == 1 ? val : store->val[b_idx][1][index];
+	buf[11] = p_idx == 0 ? val : store->val[b_idx][0][index];
 
 	/* place channel index in URB buffer */
 	buf[5] = index + 1;
@@ -592,14 +617,15 @@ static int snd_us16x08_eq_put(struct snd
 
 	err = snd_us16x08_send_urb(chip, buf, sizeof(eqs_msq));
 
-	if (err > 0) {
-		/* store new value in EQ band cache */
-		elem->cached |= 1 << index;
-		elem->cache_val[index] = val;
-	} else {
+	if (err < 0) {
 		usb_audio_dbg(chip, "Failed to set eq param, err:%d\n", err);
+		return err;
 	}
 
+	store->val[b_idx][p_idx][index] = val;
+	/* store new value in EQ band cache */
+	elem->cached |= 1 << index;
+	elem->cache_val[index] = val;
 	return 1;
 }
 
author maintainer
#107 lore raw

PATCH 105/518 x86,fs/resctrl: Prevent out-of-bounds access while offlining CPU when SNC enabled

In reply to Greg Kroah-Hartman

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

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

From: Reinette Chatre <[email protected]>

commit fc16126cc11d9f507130bf84ab137ee0938c900e upstream.

The architecture updates the cpu_mask in a domain's header to track which online CPUs are associated with the domain. When this mask becomes empty the architecture initiates offline of the domain that includes calling on resctrl fs to offline the domain. If it is a monitoring domain in which LLC occupancy is tracked resctrl fs forces the limbo handler to clear all busy RMID state associated with the domain.

The limbo handler always reads the current event value associated with a busy RMID irrespective of it being checked as part of regular "is it still busy" check or whether it will be forced released anyway. When reading an RMID on a system with SNC enabled the "logical RMID" is converted to the "physical RMID" and this conversion requires the NUMA node ID of the resctrl monitoring domain that is in turn determined by querying the NUMA node ID of any CPU belonging to the monitoring domain.

When the monitoring domain is going offline its cpu_mask is empty causing the NUMA node ID query via cpu_to_node() to be done with "nr_cpu_ids" as argument resulting in an out-of-bounds access.

Refactor the limbo handler to skip reading the RMID when the RMID will just be forced to no longer be dirty in the domain anyway. Add a safety check to the architecture's RMID reader to protect against this scenario.

---
 arch/x86/kernel/cpu/resctrl/monitor.c |    5 ++++
 fs/resctrl/monitor.c                  |   37 +++++++++++++++++++---------------
 2 files changed, 26 insertions(+), 16 deletions(-)
arch/x86/kernel/cpu/resctrl/monitor.c +5 -0
@@ -258,6 +258,11 @@ int resctrl_arch_rmid_read(struct rdt_re
 	if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
 		return -EINVAL;
 
+	if (cpumask_empty(&hdr->cpu_mask)) {
+		pr_warn_once("Domain %d has no CPUs\n", hdr->id);
+		return -EINVAL;
+	}
+
 	d = container_of(hdr, struct rdt_l3_mon_domain, hdr);
 	hw_dom = resctrl_to_arch_mon_dom(d);
 	cpu = cpumask_any(&hdr->cpu_mask);
fs/resctrl/monitor.c +21 -16
@@ -135,10 +135,10 @@ void __check_limbo(struct rdt_l3_mon_dom
 	struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
 	u32 idx_limit = resctrl_arch_system_num_rmid_idx();
 	struct rmid_entry *entry;
+	bool rmid_dirty = true;
 	u32 idx, cur_idx = 1;
 	void *arch_mon_ctx;
 	void *arch_priv;
-	bool rmid_dirty;
 	u64 val = 0;
 
 	arch_priv = mon_event_all[QOS_L3_OCCUP_EVENT_ID].arch_priv;
@@ -161,22 +161,27 @@ void __check_limbo(struct rdt_l3_mon_dom
 			break;
 
 		entry = __rmid_entry(idx);
-		if (resctrl_arch_rmid_read(r, &d->hdr, entry->closid, entry->rmid,
-					   QOS_L3_OCCUP_EVENT_ID, arch_priv, &val,
-					   arch_mon_ctx)) {
-			rmid_dirty = true;
-		} else {
-			rmid_dirty = (val >= resctrl_rmid_realloc_threshold);
+		if (!force_free) {
+			if (resctrl_arch_rmid_read(r, &d->hdr, entry->closid,
+						   entry->rmid, QOS_L3_OCCUP_EVENT_ID,
+						   arch_priv, &val, arch_mon_ctx)) {
+				rmid_dirty = true;
+			} else {
+				rmid_dirty = (val >= resctrl_rmid_realloc_threshold);
 
-			/*
-			 * x86's CLOSID and RMID are independent numbers, so the entry's
-			 * CLOSID is an empty CLOSID (X86_RESCTRL_EMPTY_CLOSID). On Arm the
-			 * RMID (PMG) extends the CLOSID (PARTID) space with bits that aren't
-			 * used to select the configuration. It is thus necessary to track both
-			 * CLOSID and RMID because there may be dependencies between them
-			 * on some architectures.
-			 */
-			trace_mon_llc_occupancy_limbo(entry->closid, entry->rmid, d->hdr.id, val);
+				/*
+				 * x86's CLOSID and RMID are independent numbers,
+				 * so the entry's CLOSID is an empty CLOSID
+				 * (X86_RESCTRL_EMPTY_CLOSID). On Arm the RMID
+				 * (PMG) extends the CLOSID (PARTID) space with
+				 * bits that aren't used to select the configuration.
+				 * It is thus necessary to track both CLOSID and
+				 * RMID because there may be dependencies between
+				 * them on some architectures.
+				 */
+				trace_mon_llc_occupancy_limbo(entry->closid, entry->rmid,
+							      d->hdr.id, val);
+			}
 		}
 
 		if (force_free || !rmid_dirty) {
author maintainer
#108 lore raw

PATCH 106/518 vfio/pci: Use a private flag to prevent power state change with VFs

In reply to Greg Kroah-Hartman

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

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

From: Raghavendra Rao Ananta <[email protected]>

commit 40ef3edf151e184d021917a5c4c771cc0870844a upstream.

The current implementation uses pci_num_vf() while holding the memory_lock to prevent changing the power state of a PF when VFs are enabled. This creates a lockdep circular dependency warning because memory_lock is held during device probing.

[  286.997167] ======================================================
[  287.003363] WARNING: possible circular locking dependency detected
[  287.009562] 7.0.0-dbg-DEV #3 Tainted: G S
[  287.015074] ------------------------------------------------------
[  287.021270] vfio_pci_sriov_/18636 is trying to acquire lock:
[  287.026942] ff45bea2294d4968 (&vdev->memory_lock){+.+.}-{4:4}, at:
vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.036530]
[  287.036530] but task is already holding lock:
[  287.042383] ff45bea3a96b8230 (&new_dev_set->lock){+.+.}-{4:4}, at:
vfio_group_fops_unl_ioctl+0x44d/0x7b0
[  287.051879]
[  287.051879] which lock already depends on the new lock.
[  287.051879]
[  287.060070]
[  287.060070] the existing dependency chain (in reverse order) is:
[  287.067568]
[  287.067568] -> #2 (&new_dev_set->lock){+.+.}-{4:4}:
[  287.073941]        __mutex_lock+0x92/0xb80
[  287.078058]        vfio_assign_device_set+0x66/0x1b0
[  287.083042]        vfio_pci_core_register_device+0xd1/0x2a0
[  287.088638]        vfio_pci_probe+0xd2/0x100
[  287.092933]        local_pci_probe_callback+0x4d/0xa0
[  287.098001]        process_scheduled_works+0x2ca/0x680
[  287.103158]        worker_thread+0x1e8/0x2f0
[  287.107452]        kthread+0x10c/0x140
[  287.111230]        ret_from_fork+0x18e/0x360
[  287.115519]        ret_from_fork_asm+0x1a/0x30
[  287.119983]
[  287.119983] -> #1 ((work_completion)(&arg.work)){+.+.}-{0:0}:
[  287.127219]        __flush_work+0x345/0x490
[  287.131429]        pci_device_probe+0x2e3/0x490
[  287.135979]        really_probe+0x1f9/0x4e0
[  287.140180]        __driver_probe_device+0x77/0x100
[  287.145079]        driver_probe_device+0x1e/0x110
[  287.149803]        __device_attach_driver+0xe3/0x170
[  287.154789]        bus_for_each_drv+0x125/0x150
[  287.159346]        __device_attach+0xca/0x1a0
[  287.163720]        device_initial_probe+0x34/0x50
[  287.168445]        pci_bus_add_device+0x6e/0x90
[  287.172995]        pci_iov_add_virtfn+0x3c9/0x3e0
[  287.177719]        sriov_add_vfs+0x2c/0x60
[  287.181838]        sriov_enable+0x306/0x4a0
[  287.186038]        vfio_pci_core_sriov_configure+0x184/0x220
[  287.191715]        sriov_numvfs_store+0xd9/0x1c0
[  287.196351]        kernfs_fop_write_iter+0x13f/0x1d0
[  287.201338]        vfs_write+0x2be/0x3b0
[  287.205286]        ksys_write+0x73/0x100
[  287.209233]        do_syscall_64+0x14d/0x750
[  287.213529]        entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  287.219120]
[  287.219120] -> #0 (&vdev->memory_lock){+.+.}-{4:4}:
[  287.225491]        __lock_acquire+0x14c6/0x2800
[  287.230048]        lock_acquire+0xd3/0x2f0
[  287.234168]        down_write+0x3a/0xc0
[  287.238019]        vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.243436]        __rpm_callback+0x8c/0x310
[  287.247730]        rpm_resume+0x529/0x6f0
[  287.251765]        __pm_runtime_resume+0x68/0x90
[  287.256402]        vfio_pci_core_enable+0x44/0x310
[  287.261216]        vfio_pci_open_device+0x1c/0x80
[  287.265947]        vfio_df_open+0x10f/0x150
[  287.270148]        vfio_group_fops_unl_ioctl+0x4a4/0x7b0
[  287.275476]        __se_sys_ioctl+0x71/0xc0
[  287.279679]        do_syscall_64+0x14d/0x750
[  287.283975]        entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  287.289559]
[  287.289559] other info that might help us debug this:
[  287.289559]
[  287.297582] Chain exists of:
[  287.297582]   &vdev->memory_lock --> (work_completion)(&arg.work)
--> &new_dev_set->lock
[  287.297582]
[  287.310023]  Possible unsafe locking scenario:
[  287.310023]
[  287.315961]        CPU0                    CPU1
[  287.320510]        ----                    ----
[  287.325059]   lock(&new_dev_set->lock);
[  287.328917]
lock((work_completion)(&arg.work));
[  287.336153]                                lock(&new_dev_set->lock);
[  287.342523]   lock(&vdev->memory_lock);
[  287.346382]
[  287.346382]  *** DEADLOCK ***
[  287.346382]
[  287.352315] 2 locks held by vfio_pci_sriov_/18636:
[  287.357125]  #0: ff45bea208ed3e18 (&group->group_lock){+.+.}-{4:4},
at: vfio_group_fops_unl_ioctl+0x3e3/0x7b0
[  287.367048]  #1: ff45bea3a96b8230 (&new_dev_set->lock){+.+.}-{4:4},
at: vfio_group_fops_unl_ioctl+0x44d/0x7b0
[  287.376976]
[  287.376976] stack backtrace:
[  287.381353] CPU: 191 UID: 0 PID: 18636 Comm: vfio_pci_sriov_
Tainted: G S                  7.0.0-dbg-DEV #3 PREEMPTLAZY
[  287.381355] Tainted: [S]=CPU_OUT_OF_SPEC
[  287.381356] Call Trace:
[  287.381357]  <TASK>
[  287.381358]  dump_stack_lvl+0x54/0x70
[  287.381361]  print_circular_bug+0x2e1/0x300
[  287.381363]  check_noncircular+0xf9/0x120
[  287.381364]  ? __lock_acquire+0x5b4/0x2800
[  287.381366]  __lock_acquire+0x14c6/0x2800
[  287.381368]  ? pci_mmcfg_read+0x4f/0x220
[  287.381370]  ? pci_mmcfg_write+0x57/0x220
[  287.381371]  ? lock_acquire+0xd3/0x2f0
[  287.381373]  ? pci_mmcfg_write+0x57/0x220
[  287.381374]  ? lock_release+0xef/0x360
[  287.381376]  ? vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381377]  lock_acquire+0xd3/0x2f0
[  287.381378]  ? vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381379]  ? lock_is_held_type+0x76/0x100
[  287.381382]  down_write+0x3a/0xc0
[  287.381382]  ? vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381383]  vfio_pci_core_runtime_resume+0x1f/0xa0
[  287.381384]  ? __pfx_pci_pm_runtime_resume+0x10/0x10
[  287.381385]  __rpm_callback+0x8c/0x310
[  287.381386]  ? ktime_get_mono_fast_ns+0x3d/0xb0
[  287.381389]  ? __pfx_pci_pm_runtime_resume+0x10/0x10
[  287.381390]  rpm_resume+0x529/0x6f0
[  287.381392]  ? lock_is_held_type+0x76/0x100
[  287.381394]  __pm_runtime_resume+0x68/0x90
[  287.381396]  vfio_pci_core_enable+0x44/0x310
[  287.381398]  vfio_pci_open_device+0x1c/0x80
[  287.381399]  vfio_df_open+0x10f/0x150
[  287.381401]  vfio_group_fops_unl_ioctl+0x4a4/0x7b0
[  287.381402]  __se_sys_ioctl+0x71/0xc0
[  287.381404]  do_syscall_64+0x14d/0x750
[  287.381405]  ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[  287.381406]  ? trace_irq_disable+0x25/0xd0
[  287.381409]  entry_SYSCALL_64_after_hwframe+0x77/0x7f

Introduce a private flag 'sriov_active' in the vfio_pci_core_device struct. This allows the driver to track the SR-IOV power state requirement without relying on pci_num_vf() while holding the memory_lock. The lock is now only held to set the flag and ensure the device is in D0, after which pci_enable_sriov() can be called without the lock.

Fixes f4162eb1e2fc ("vfio/pci: Change the PF power state to D0 before enabling VFs")
[promote bitfield to plain bool to avoid storage-unit races]
---
 drivers/vfio/pci/vfio_pci_core.c |   17 ++++++++++++++---
 include/linux/vfio_pci_core.h    |    1 +
 2 files changed, 15 insertions(+), 3 deletions(-)
drivers/vfio/pci/vfio_pci_core.c +14 -3
@@ -271,8 +271,11 @@ int vfio_pci_set_power_state(struct vfio
 	int ret;
 
 	/* Prevent changing power state for PFs with VFs enabled */
-	if (pci_num_vf(pdev) && state > PCI_D0)
-		return -EBUSY;
+	if (state > PCI_D0) {
+		lockdep_assert_held_write(&vdev->memory_lock);
+		if (vdev->sriov_active)
+			return -EBUSY;
+	}
 
 	if (vdev->needs_pm_restore) {
 		if (pdev->current_state < PCI_D3hot && state >= PCI_D3hot) {
@@ -2327,8 +2330,9 @@ int vfio_pci_core_sriov_configure(struct
 
 		down_write(&vdev->memory_lock);
 		vfio_pci_set_power_state(vdev, PCI_D0);
-		ret = pci_enable_sriov(pdev, nr_virtfn);
+		vdev->sriov_active = true;
 		up_write(&vdev->memory_lock);
+		ret = pci_enable_sriov(pdev, nr_virtfn);
 		if (ret) {
 			pm_runtime_put(&pdev->dev);
 			goto out_del;
@@ -2342,6 +2346,13 @@ int vfio_pci_core_sriov_configure(struct
 	}
 
 out_del:
+	/*
+	 * Avoid taking the memory_lock intentionally. A race with a power
+	 * state transition would at most result in an -EBUSY, leaving the
+	 * device in PCI_D0.
+	 */
+	vdev->sriov_active = false;
+
 	mutex_lock(&vfio_pci_sriov_pfs_mutex);
 	list_del_init(&vdev->sriov_pfs_item);
 out_unlock:
include/linux/vfio_pci_core.h +1 -0
@@ -127,6 +127,7 @@ struct vfio_pci_core_device {
 	bool			needs_pm_restore:1;
 	bool			pm_intx_masked:1;
 	bool			pm_runtime_engaged:1;
+	bool			sriov_active;
 	struct pci_saved_state	*pci_saved_state;
 	struct pci_saved_state	*pm_save;
 	int			ioeventfds_nr;
author maintainer
#109 lore raw

PATCH 107/518 vfio/pci: Latch disable_idle_d3 per device

In reply to Greg Kroah-Hartman

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

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

From: Alex Williamson <[email protected]>

commit 4575e9aac5336d1365138c0284773bf8da4b1fa3 upstream.

When disable_idle_d3 was introduced in vfio-pci, it directly manipulated the device power state with pci_set_power_state(). There were no refcounts to maintain or balanced operations, we could unconditionally bring the device to D0 and conditionally move it to D3hot. Therefore the module parameter was made writable.

Later, in commit c61302aa48f7 ("vfio/pci: Move module parameters to vfio_pci.c"), as part of the vfio-pci-core split, the writable aspect of the module parameter was nullified. The parameter value could still be changed through sysfs, but the vfio-pci driver latched the values into vfio-pci-core globals at module init. Loading the vfio-pci module, or unloading and reloading, with non-default or different values could change the globals relative to existing devices bound to vfio-pci variant drivers.

Runtime PM was introduced in commit 7ab5e10eda02 ("vfio/pci: Move the unused device into low power state with runtime PM"), which marks the point where power states became refcounted. PM get and put operations need to be balanced, but the same module operations noted above can change the global variables relative to those devices already bound to vfio-pci variant drivers. This introduces a window where PM operations can now become unbalanced.

To resolve this with a narrow footprint for stable backports, the disable_idle_d3 flag is latched into the vfio_pci_core_device at the time of initialization, such that the device always operates with a consistent value.

NB. vfio_pci_dev_set_try_reset() now unconditionally raises the runtime PM usage count around bus reset to account for disable_idle_d3 becoming a per-device rather than global flag. When this flag is set, the additional get/put pair is harmless and allows continued use of the shared vfio_pci_dev_set_pm_runtime_get() helper.

Fixes 7ab5e10eda02 ("vfio/pci: Move the unused device into low power state with runtime PM")
Assisted-by Claude:claude-opus-4-8
---
 drivers/vfio/pci/vfio_pci_core.c |   19 ++++++++++---------
 include/linux/vfio_pci_core.h    |    1 +
 2 files changed, 11 insertions(+), 9 deletions(-)
drivers/vfio/pci/vfio_pci_core.c +10 -9
@@ -538,7 +538,7 @@ int vfio_pci_core_enable(struct vfio_pci
 	u16 cmd;
 	u8 msix_pos;
 
-	if (!disable_idle_d3) {
+	if (!vdev->disable_idle_d3) {
 		ret = pm_runtime_resume_and_get(&pdev->dev);
 		if (ret < 0)
 			return ret;
@@ -617,7 +617,7 @@ out_free_state:
 out_disable_device:
 	pci_disable_device(pdev);
 out_power:
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_put(&pdev->dev);
 	return ret;
 }
@@ -753,7 +753,7 @@ out:
 	vfio_pci_dev_set_try_reset(vdev->vdev.dev_set);
 
 	/* Put the pm-runtime usage counter acquired during enable */
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_put(&pdev->dev);
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_disable);
@@ -2145,6 +2145,8 @@ int vfio_pci_core_init_dev(struct vfio_d
 	init_rwsem(&vdev->memory_lock);
 	xa_init(&vdev->ctx);
 
+	vdev->disable_idle_d3 = disable_idle_d3;
+
 	return 0;
 }
 EXPORT_SYMBOL_GPL(vfio_pci_core_init_dev);
@@ -2240,7 +2242,7 @@ int vfio_pci_core_register_device(struct
 
 	dev->driver->pm = &vfio_pci_core_pm_ops;
 	pm_runtime_allow(dev);
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_put(dev);
 
 	ret = vfio_register_group_dev(&vdev->vdev);
@@ -2249,7 +2251,7 @@ int vfio_pci_core_register_device(struct
 	return 0;
 
 out_power:
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_get_noresume(dev);
 
 	pm_runtime_forbid(dev);
@@ -2268,7 +2270,7 @@ void vfio_pci_core_unregister_device(str
 	vfio_pci_vf_uninit(vdev);
 	vfio_pci_vga_uninit(vdev);
 
-	if (!disable_idle_d3)
+	if (!vdev->disable_idle_d3)
 		pm_runtime_get_noresume(&vdev->pdev->dev);
 
 	pm_runtime_forbid(&vdev->pdev->dev);
@@ -2600,7 +2602,7 @@ static void vfio_pci_dev_set_try_reset(s
 	 * state. Increment the usage count for all the devices in the dev_set
 	 * before reset and decrement the same after reset.
 	 */
-	if (!disable_idle_d3 && vfio_pci_dev_set_pm_runtime_get(dev_set))
+	if (vfio_pci_dev_set_pm_runtime_get(dev_set))
 		return;
 
 	if (!pci_reset_bus(pdev))
@@ -2610,8 +2612,7 @@ static void vfio_pci_dev_set_try_reset(s
 		if (reset_done)
 			cur->needs_reset = false;
 
-		if (!disable_idle_d3)
-			pm_runtime_put(&cur->pdev->dev);
+		pm_runtime_put(&cur->pdev->dev);
 	}
 }
 
include/linux/vfio_pci_core.h +1 -0
@@ -127,6 +127,7 @@ struct vfio_pci_core_device {
 	bool			needs_pm_restore:1;
 	bool			pm_intx_masked:1;
 	bool			pm_runtime_engaged:1;
+	bool			disable_idle_d3:1;
 	bool			sriov_active;
 	struct pci_saved_state	*pci_saved_state;
 	struct pci_saved_state	*pm_save;
author maintainer
#110 lore raw

PATCH 108/518 vfio/pci: Release the VGA arbiter client on register_device() failure

In reply to Greg Kroah-Hartman

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

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

From: Alex Williamson <[email protected]>

commit daedde7f024ecf88bc8e832ed40cf2c795f0796a upstream.

The re-order in the Fixes commit below displaced vfio_pci_vga_init() as the last failure point of what is now vfio_pci_core_register_device() without introducing an unwind for the VGA arbiter registration.

In current kernels this is mostly benign because vfio_pci_set_decode() only uses pci_dev state, but the original failure path could leave a callback with a freed vdev cookie. The stale registration also becomes unsafe again once the callback follows drvdata to the vfio device.

Add the required VGA unwind callout.

Fixes 4aeec3984ddc ("vfio/pci: Re-order vfio_pci_probe()")
Assisted-by Claude:claude-opus-4-8
---
 drivers/vfio/pci/vfio_pci_core.c |    1 +
 1 file changed, 1 insertion(+)
drivers/vfio/pci/vfio_pci_core.c +1 -0
@@ -2255,6 +2255,7 @@ out_power:
 		pm_runtime_get_noresume(dev);
 
 	pm_runtime_forbid(dev);
+	vfio_pci_vga_uninit(vdev);
 out_vf:
 	vfio_pci_vf_uninit(vdev);
 	return ret;
author maintainer
#111 lore raw

PATCH 109/518 vfio/pci: Fix racy bitfields and tighten struct layout

In reply to Greg Kroah-Hartman

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

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

From: Alex Williamson <[email protected]>

commit e73638e55f861758d49f14d7bb5dba3035981cd7 upstream.

Bitfield operations are not atomic, they use a read-modify-write pattern, therefore we should be careful not to pack bitfields that can be concurrently updated into the same storage unit.

This split takes a binary approach: flags that are only modified pre/post open/close remain bitfields, flags modified from user action, including actions that reach across to another device (ex. reset) use dedicated storage units.

Note that the virq_disabled and bardirty flags are relocated to fill an existing hole in the structure.

Bitfield justifications:

has_dyn_msix: written only in vfio_pci_core_enable()
pci_2_3: written only in vfio_pci_core_enable()
reset_works: written only in vfio_pci_core_enable()
extended_caps: written only in vfio_cap_len() under vfio_config_init()
has_vga: written only in vfio_pci_core_enable()
nointx: written only in vfio_pci_core_enable()
needs_pm_restore: written only in vfio_pci_probe_power_state()
disable_idle_d3: written only at .init in vfio_pci_core_init_dev()

Dedicated storage units:

virq_disabled: written by guest INTx command writes in
vfio_basic_config_write() while the device is open
bardirty: written by guest BAR writes in vfio_basic_config_write()
while the device is open
pm_intx_masked: written in the runtime-PM suspend path.
pm_runtime_engaged: written by low-power feature entry/exit paths
needs_reset: set in vfio_pci_core_disable() and cleared for devices in
the set by vfio_pci_dev_set_try_reset()
sriov_active: written by vfio_pci_core_sriov_configure() via sysfs
sriov_numvfs while bound.

Fixes 9cd0f6d5cbb6 ("vfio/pci: Use bitfield for struct vfio_pci_core_device flags")
Assisted-by Claude:claude-opus-4-8
---
 include/linux/vfio_pci_core.h |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
include/linux/vfio_pci_core.h +8 -5
@@ -101,6 +101,9 @@ struct vfio_pci_core_device {
 	const struct vfio_pci_device_ops *pci_ops;
 	void __iomem		*barmap[PCI_STD_NUM_BARS];
 	bool			bar_mmap_supported[PCI_STD_NUM_BARS];
+	/* Flags modified at runtime - dedicated storage unit */
+	bool			virq_disabled;
+	bool			bardirty;
 	u8			*pci_config_map;
 	u8			*vconfig;
 	struct perm_bits	*msi_perm;
@@ -115,19 +118,19 @@ struct vfio_pci_core_device {
 	u16			msix_size;
 	u32			msix_offset;
 	u32			rbar[7];
+	/* Flags only modified on setup/release - bitfield ok */
 	bool			has_dyn_msix:1;
 	bool			pci_2_3:1;
-	bool			virq_disabled:1;
 	bool			reset_works:1;
 	bool			extended_caps:1;
-	bool			bardirty:1;
 	bool			has_vga:1;
-	bool			needs_reset:1;
 	bool			nointx:1;
 	bool			needs_pm_restore:1;
-	bool			pm_intx_masked:1;
-	bool			pm_runtime_engaged:1;
 	bool			disable_idle_d3:1;
+	/* Flags modified at runtime - dedicated storage unit */
+	bool			needs_reset;
+	bool			pm_intx_masked;
+	bool			pm_runtime_engaged;
 	bool			sriov_active;
 	struct pci_saved_state	*pci_saved_state;
 	struct pci_saved_state	*pm_save;
author maintainer
#112 lore raw

PATCH 110/518 vfio: prevent infinite loop in vfio_mig_get_next_state() on blocked arc

In reply to Greg Kroah-Hartman

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

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

From: Junrui Luo <[email protected]>

commit a26b499b757cfc8bbff1088bb1b844639e250893 upstream.

vfio_mig_get_next_state() walks vfio_from_fsm_table[] one step at a time, looping to skip optional states the device does not support until *next_fsm is supported. A blocked transition is encoded as VFIO_DEVICE_STATE_ERROR, which the trailing return reports as -EINVAL.

The skip loop does not account for the ERROR sentinel. state_flags_table[ERROR] is ~0U and vfio_from_fsm_table[ERROR][*] is ERROR, so once *next_fsm becomes ERROR the loop condition stays true and *next_fsm never changes. The blocked arcs STOP_COPY -> PRE_COPY and STOP_COPY -> PRE_COPY_P2P map to ERROR yet pass the support check on a precopy-capable device, causing the loop to spin forever while holding the driver state mutex. This can result in a soft lockup, and a panic with softlockup_panic set.

Terminate the skip loop on the ERROR sentinel so a blocked transition falls through to the existing return and reports -EINVAL.

---
 drivers/vfio/vfio_main.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/vfio/vfio_main.c +2 -1
@@ -858,7 +858,8 @@ int vfio_mig_get_next_state(struct vfio_
 	 * logical state, as per the above comment.
 	 */
 	*next_fsm = vfio_from_fsm_table[cur_fsm][new_fsm];
-	while ((state_flags_table[*next_fsm] & device->migration_flags) !=
+	while (*next_fsm != VFIO_DEVICE_STATE_ERROR &&
+	       (state_flags_table[*next_fsm] & device->migration_flags) !=
 			state_flags_table[*next_fsm])
 		*next_fsm = vfio_from_fsm_table[*next_fsm][new_fsm];
 
author maintainer
#113 lore raw

PATCH 111/518 vfio: Remove device debugfs before releasing devres

In reply to Greg Kroah-Hartman

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

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

From: Alex Williamson <[email protected]>

commit dc7fe87de492ea7f33a72b78d26650b75bf37f4f upstream.

VFIO device debugfs files created with debugfs_create_devm_seqfile() store a devres allocated debugfs_devm_entry as inode private data. vfio_unregister_group_dev() currently calls vfio_device_del() before vfio_device_debugfs_exit(), but device_del() releases devres. This can leave debugfs entries visible with stale inode private data while unregister waits for userspace references to drain.

Remove the per-device debugfs tree before vfio_device_del(). The debugfs view is diagnostic only, so losing it at the start of unregister is preferable to preserving entries whose backing storage may already have been released.

Complete the teardown by clearing the per-device debugfs root after removal. This matches the global debugfs root cleanup and prevents future users from mistaking a removed dentry for a live debugfs tree during the remainder of unregister.

---
 drivers/vfio/debugfs.c   |    1 +
 drivers/vfio/vfio_main.c |    8 +++++++-
 2 files changed, 8 insertions(+), 1 deletion(-)
drivers/vfio/debugfs.c +1 -0
@@ -97,6 +97,7 @@ void vfio_device_debugfs_init(struct vfi
 void vfio_device_debugfs_exit(struct vfio_device *vdev)
 {
 	debugfs_remove_recursive(vdev->debug_root);
+	vdev->debug_root = NULL;
 }
 
 void vfio_debugfs_create_root(void)
drivers/vfio/vfio_main.c +7 -1
@@ -407,6 +407,13 @@ void vfio_unregister_group_dev(struct vf
 	vfio_device_group_unregister(device);
 
 	/*
+	 * Remove debugfs before device_del(), which releases devres.  Some
+	 * debugfs entries are created with debugfs_create_devm_seqfile() and
+	 * therefore rely on devres-managed inode private data.
+	 */
+	vfio_device_debugfs_exit(device);
+
+	/*
 	 * Balances vfio_device_add() in register path, also prevents
 	 * new device opened by userspace in the cdev path.
 	 */
@@ -435,7 +442,6 @@ void vfio_unregister_group_dev(struct vf
 		}
 	}
 
-	vfio_device_debugfs_exit(device);
 	/* Balances vfio_device_set_group in register path */
 	vfio_device_remove_group(device);
 }
author maintainer
#114 lore raw

PATCH 112/518 vfio/mlx5: Fix racy bitfields and tighten struct layout

In reply to Greg Kroah-Hartman

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

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

From: Alex Williamson <[email protected]>

commit f2365a63b02ddea32e7db78b742c2503ec7b81f1 upstream.

Bitfield operations are not atomic, they use a read-modify-write pattern, therefore we should be careful not to pack bitfields that can be concurrently updated into the same storage unit.

This split takes a binary approach: flags that are only modified pre/post open/close remain bitfields, flags modified from user action, including actions that reach across to another device (ex. reset) use dedicated storage units.

Note mlx5_vhca_page_tracker.status is relocated to fill the alignment hole this split exposes.

Bitfield justifications:

migrate_cap: written only in mlx5vf_cmd_set_migratable() at probe
chunk_mode: written only in mlx5vf_cmd_set_migratable() at probe
mig_state_cap: written only in mlx5vf_cmd_set_migratable() at probe

Dedicated storage units:

mdev_detach: written in the VF attach/detach event notifier
mlx5fv_vf_event() at runtime
log_active: written in mlx5vf_start_page_tracker()/
mlx5vf_stop_page_tracker() during runtime dirty tracking
deferred_reset: written in mlx5vf_state_mutex_unlock()/
mlx5vf_pci_aer_reset_done() during runtime reset handling
is_err: set by tracker error handling and dirty-log polling at runtime
object_changed: set by tracker event handling and cleared by dirty-log
polling at runtime

Fixes 61a2f1460fd0 ("vfio/mlx5: Manage the VF attach/detach callback from the PF")
Fixes 79c3cf279926 ("vfio/mlx5: Init QP based resources for dirty tracking")
Fixes f886473071d6 ("vfio/mlx5: Add support for tracker object change event")
Cc Yishai Hadas <[email protected]>
Assisted-by Claude:claude-opus-4-8
---
 drivers/vfio/pci/mlx5/cmd.h |   15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/vfio/pci/mlx5/cmd.h +9 -6
@@ -158,26 +158,29 @@ struct mlx5_vhca_qp {
 struct mlx5_vhca_page_tracker {
 	u32 id;
 	u32 pdn;
-	u8 is_err:1;
-	u8 object_changed:1;
+	/* Flags modified at runtime - dedicated storage unit */
+	u8 is_err;
+	u8 object_changed;
+	int status;
 	struct mlx5_uars_page *uar;
 	struct mlx5_vhca_cq cq;
 	struct mlx5_vhca_qp *host_qp;
 	struct mlx5_vhca_qp *fw_qp;
 	struct mlx5_nb nb;
-	int status;
 };
 
 struct mlx5vf_pci_core_device {
 	struct vfio_pci_core_device core_device;
 	int vf_id;
 	u16 vhca_id;
+	/* Flags only modified on setup/release - bitfield ok */
 	u8 migrate_cap:1;
-	u8 deferred_reset:1;
-	u8 mdev_detach:1;
-	u8 log_active:1;
 	u8 chunk_mode:1;
 	u8 mig_state_cap:1;
+	/* Flags modified at runtime - dedicated storage unit */
+	u8 mdev_detach;
+	u8 log_active;
+	u8 deferred_reset;
 	struct completion tracker_comp;
 	/* protect migration state */
 	struct mutex state_mutex;
author maintainer
#115 lore raw

PATCH 113/518 Bluetooth: btusb: Add USB ID 2c4e:0128 for Mercusys MA60XNB

In reply to Greg Kroah-Hartman

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

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

From: Zenm Chen <[email protected]>

commit 88b4d528eda4ac71c2952b3458f2abbc80a91cd2 upstream.

Add USB ID 2c4e:0128 for Mercusys MA60XNB, an RTL8851BU-based Wi-Fi + Bluetooth adapter.

The information in /sys/kernel/debug/usb/devices about the Bluetooth device is listed as the below:

T:  Bus=03 Lev=01 Prnt=01 Port=04 Cnt=01 Dev#=  3 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=ef(misc ) Sub=02 Prot=01 MxPS=64 #Cfgs=  1
P:  Vendor=2c4e ProdID=0128 Rev= 0.00
S:  Manufacturer=Realtek
S:  Product=802.11ax WLAN Adapter
S:  SerialNumber=00e04c000001
C:* #Ifs= 3 Cfg#= 1 Atr=e0 MxPwr=500mA
A:  FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01
I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=1ms
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=   0 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=   0 Ivl=1ms
I:  If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=   9 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=   9 Ivl=1ms
I:  If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  17 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  17 Ivl=1ms
I:  If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  25 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  25 Ivl=1ms
I:  If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  33 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  33 Ivl=1ms
I:  If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  49 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  49 Ivl=1ms
I:  If#= 1 Alt= 6 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
E:  Ad=03(O) Atr=01(Isoc) MxPS=  63 Ivl=1ms
E:  Ad=83(I) Atr=01(Isoc) MxPS=  63 Ivl=1ms
I:* If#= 2 Alt= 0 #EPs= 8 Cls=ff(vend.) Sub=ff Prot=ff Driver=rtw89_8851bu
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=06(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=07(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=09(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0a(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=0c(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
---
 drivers/bluetooth/btusb.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/bluetooth/btusb.c +2 -0
@@ -531,6 +531,8 @@ static const struct usb_device_id quirks
 						     BTUSB_WIDEBAND_SPEECH },
 	{ USB_DEVICE(0x7392, 0xe611), .driver_info = BTUSB_REALTEK |
 						     BTUSB_WIDEBAND_SPEECH },
+	{ USB_DEVICE(0x2c4e, 0x0128), .driver_info = BTUSB_REALTEK |
+						     BTUSB_WIDEBAND_SPEECH },
 
 	/* Realtek 8852AE Bluetooth devices */
 	{ USB_DEVICE(0x0bda, 0x2852), .driver_info = BTUSB_REALTEK |
author maintainer
#116 lore raw

PATCH 114/518 Bluetooth: btusb: fix use-after-free on registration failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit eedc6867ebad73edbfaf9a0a65fbef7115cc4753 upstream.

Make sure to release the sibling interfaces in case controller registration fails to avoid use-after-free and double-free when they are eventually disconnected.

This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.

Fixes 9bfa35fe422c ("[Bluetooth] Add SCO support to btusb driver")
Fixes 9d08f50401ac ("Bluetooth: btusb: Add support for Broadcom LM_DIAG interface")
Cc [email protected] # 2.6.27
---
 drivers/bluetooth/btusb.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/bluetooth/btusb.c +10 -1
@@ -4409,7 +4409,7 @@ static int btusb_probe(struct usb_interf
 
 	err = hci_register_dev(hdev);
 	if (err < 0)
-		goto out_free_dev;
+		goto err_release_siblings;
 
 	usb_set_intfdata(intf, data);
 
@@ -4418,6 +4418,15 @@ static int btusb_probe(struct usb_interf
 
 	return 0;
 
+err_release_siblings:
+	if (data->diag) {
+		usb_set_intfdata(data->diag, NULL);
+		usb_driver_release_interface(&btusb_driver, data->diag);
+	}
+	if (data->isoc) {
+		usb_set_intfdata(data->isoc, NULL);
+		usb_driver_release_interface(&btusb_driver, data->isoc);
+	}
 out_free_dev:
 	if (data->reset_gpio)
 		gpiod_put(data->reset_gpio);
author maintainer
#117 lore raw

PATCH 115/518 Bluetooth: btusb: fix use-after-free on marvell probe failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit c5b600a3c05b1a7a110d558df935a8fc8a471c79 upstream.

Make sure to stop any TX URBs submitted during Marvell OOB wakeup configuration on later probe failures to avoid use-after-free in the completion callback.

This issue was reported by Sashiko while reviewing a fix for a wakeup source leak in the btusb probe errors paths.

Fixes a4ccc9e33d2f ("Bluetooth: btusb: Configure Marvell to use one of the pins for oob wakeup")
Cc Rajat Jain <[email protected]>
---
 drivers/bluetooth/btusb.c |    8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/bluetooth/btusb.c +5 -3
@@ -4220,7 +4220,7 @@ static int btusb_probe(struct usb_interf
 	if (id->driver_info & BTUSB_INTEL_COMBINED) {
 		err = btintel_configure_setup(hdev, btusb_driver.name);
 		if (err)
-			goto out_free_dev;
+			goto err_kill_tx_urbs;
 
 		/* Transport specific configuration */
 		hdev->send = btusb_send_frame_intel;
@@ -4383,7 +4383,7 @@ static int btusb_probe(struct usb_interf
 		err = usb_set_interface(data->udev, 0, 0);
 		if (err < 0) {
 			BT_ERR("failed to set interface 0, alt 0 %d", err);
-			goto out_free_dev;
+			goto err_kill_tx_urbs;
 		}
 	}
 
@@ -4391,7 +4391,7 @@ static int btusb_probe(struct usb_interf
 		err = usb_driver_claim_interface(&btusb_driver,
 						 data->isoc, data);
 		if (err < 0)
-			goto out_free_dev;
+			goto err_kill_tx_urbs;
 	}
 
 	if (IS_ENABLED(CONFIG_BT_HCIBTUSB_BCM) && data->diag) {
@@ -4427,6 +4427,8 @@ err_release_siblings:
 		usb_set_intfdata(data->isoc, NULL);
 		usb_driver_release_interface(&btusb_driver, data->isoc);
 	}
+err_kill_tx_urbs:
+	usb_kill_anchored_urbs(&data->tx_anchor);
 out_free_dev:
 	if (data->reset_gpio)
 		gpiod_put(data->reset_gpio);
author maintainer
#118 lore raw

PATCH 116/518 Bluetooth: btusb: fix wakeup source leak on probe failure

In reply to Greg Kroah-Hartman

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

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

From: Johan Hovold <[email protected]>

commit 3d93e1bb0fb881fe3ef961d1120556658e9cac4d upstream.

Make sure to disable wakeup on probe failure to avoid leaking the wakeup source.

Fixes fd913ef7ce61 ("Bluetooth: btusb: Add out-of-band wakeup support")
Cc Rajat Jain <[email protected]>
---
 drivers/bluetooth/btusb.c |   18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)
drivers/bluetooth/btusb.c +15 -3
@@ -2996,6 +2996,11 @@ static int marvell_config_oob_wake(struc
 
 	return 0;
 }
+#else
+static inline int marvell_config_oob_wake(struct hci_dev *hdev)
+{
+	return 0;
+}
 #endif
 
 static int btusb_set_bdaddr_marvell(struct hci_dev *hdev,
@@ -3838,6 +3843,11 @@ static int btusb_config_oob_wake(struct
 	bt_dev_info(hdev, "OOB Wake-on-BT configured at IRQ %u", irq);
 	return 0;
 }
+#else
+static inline int btusb_config_oob_wake(struct hci_dev *hdev)
+{
+	return 0;
+}
 #endif
 
 static void btusb_check_needs_reset_resume(struct usb_interface *intf)
@@ -4174,7 +4184,6 @@ static int btusb_probe(struct usb_interf
 	hdev->wakeup  = btusb_wakeup;
 	hdev->hci_drv = &btusb_hci_drv;
 
-#ifdef CONFIG_PM
 	err = btusb_config_oob_wake(hdev);
 	if (err)
 		goto out_free_dev;
@@ -4183,9 +4192,9 @@ static int btusb_probe(struct usb_interf
 	if (id->driver_info & BTUSB_MARVELL && data->oob_wake_irq) {
 		err = marvell_config_oob_wake(hdev);
 		if (err)
-			goto out_free_dev;
+			goto err_disable_wakeup;
 	}
-#endif
+
 	if (id->driver_info & BTUSB_CW6622)
 		hci_set_quirk(hdev, HCI_QUIRK_BROKEN_STORED_LINK_KEY);
 
@@ -4429,6 +4438,9 @@ err_release_siblings:
 	}
 err_kill_tx_urbs:
 	usb_kill_anchored_urbs(&data->tx_anchor);
+err_disable_wakeup:
+	if (data->oob_wake_irq)
+		device_init_wakeup(&data->udev->dev, false);
 out_free_dev:
 	if (data->reset_gpio)
 		gpiod_put(data->reset_gpio);
author maintainer
#119 lore raw

PATCH 117/518 binder: fix UAF in binder_thread_release()

In reply to Greg Kroah-Hartman

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

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

From: Carlos Llamas <[email protected]>

commit 114a116aaa5f0295376cdf12da743c5bce3b20ce upstream.

When a thread exits, binder_thread_release() walks its transaction stack to clear the t->from and t->to_proc that correspond with the exiting thread. However, a process dying in parallel might attempt to kfree some of these transactions. And if one of them has no associated t->to_proc, the t->to_proc->inner_lock will not be acquired.

This means that transaction accesses in binder_thread_release() after t->to_proc has been cleared might race with binder_free_transaction() and cause a use-after-free error as reported by KASAN:

==================================================================

  BUG: KASAN: slab-use-after-free in binder_thread_release+0x5d0/0x798
  Write of size 8 at addr ffff000016627500 by task X/715

  CPU: 17 UID: 0 PID: 715 Comm: X Not tainted 7.1.0-rc5-00149-g8fde5d1d47f6 #30 PREEMPT
  Hardware name: linux,dummy-virt (DT)
  Call trace:
   binder_thread_release+0x5d0/0x798
   binder_ioctl+0x12c0/0x299c
   [...]

  Allocated by task 717 on cpu 18 at 67.267803s:
   __kasan_kmalloc+0xa0/0xbc
   __kmalloc_cache_noprof+0x174/0x444
   binder_transaction+0x554/0x8150
   binder_thread_write+0xa30/0x4354
   binder_ioctl+0x20f0/0x299c
   [...]

  Freed by task 202 on cpu 18 at 90.416221s:
   __kasan_slab_free+0x58/0x80
   kfree+0x1a0/0x4a4
   binder_free_transaction+0x150/0x294
   binder_send_failed_reply+0x398/0x6d8
   binder_release_work+0x3e4/0x4ec
   binder_deferred_func+0xbd8/0x104c
   [...]
  ==================================================================

In order to avoid this, make sure that binder_free_transaction() reads the t->to_proc under the transaction lock. This will serialize the transaction release with the accesses in binder_thread_release(). Plus, it matches the documented locking rules for @to_proc.

Cc stable <[email protected]>
Fixes 7a4408c6bd3e ("binder: make sure accesses to proc/thread are safe")
---
 drivers/android/binder.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder.c +5 -1
@@ -1658,7 +1658,11 @@ static void binder_txn_latency_free(stru
 
 static void binder_free_transaction(struct binder_transaction *t)
 {
-	struct binder_proc *target_proc = t->to_proc;
+	struct binder_proc *target_proc;
+
+	spin_lock(&t->lock);
+	target_proc = t->to_proc;
+	spin_unlock(&t->lock);
 
 	if (target_proc) {
 		binder_inner_proc_lock(target_proc);
author maintainer
#120 lore raw

PATCH 118/518 binder: fix UAF in binder_free_transaction()

In reply to Greg Kroah-Hartman

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

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

From: Carlos Llamas <[email protected]>

commit f223d27a546c1e1f48d38fd67760e78f068fe8c4 upstream.

In binder_free_transaction(), the t->to_proc is read under the t->lock. However, once the t->lock is dropped, the to_proc can die in parallel. This leads to a use-after-free error when we attempt to acquire its inner lock right afterwards:

==================================================================

  BUG: KASAN: slab-use-after-free in _raw_spin_lock+0xe4/0x1a0
  Write of size 4 at addr ffff00001125da70 by task B/672

  CPU: 20 UID: 0 PID: 672 Comm: B Not tainted 7.1.0-rc6-00284-g8e65320d91cd #4 PREEMPT
  Hardware name: linux,dummy-virt (DT)
  Call trace:
   _raw_spin_lock+0xe4/0x1a0
   binder_free_transaction+0x8c/0x320
   binder_send_failed_reply+0x21c/0x2f8
   binder_thread_release+0x488/0x7e0
   binder_ioctl+0x12c0/0x29a0
  [...]

  Allocated by task 675:
   __kmalloc_cache_noprof+0x174/0x444
   binder_open+0x118/0xb70
   do_dentry_open+0x374/0x1040
   vfs_open+0x58/0x3bc
  [...]

  Freed by task 212:
   __kasan_slab_free+0x58/0x80
   kfree+0x1a0/0x4a4
   binder_proc_dec_tmpref+0x32c/0x5e0
   binder_deferred_func+0xc48/0x104c
   process_one_work+0x53c/0xbc0
  [...]
  ==================================================================

To prevent this, pin the target thread (t->to_thread) to guarantee the target process remains alive. Undelivered transactions without a target thread are already safe, as the target process can only be the current context in those paths.

---
 drivers/android/binder.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)
drivers/android/binder.c +13 -0
@@ -1658,10 +1658,19 @@ static void binder_txn_latency_free(stru
 
 static void binder_free_transaction(struct binder_transaction *t)
 {
+	struct binder_thread *target_thread;
 	struct binder_proc *target_proc;
 
 	spin_lock(&t->lock);
 	target_proc = t->to_proc;
+	target_thread = t->to_thread;
+	/*
+	 * Pin target_thread to keep target_proc alive. Undelivered
+	 * transactions with !target_thread are safe, as target_proc
+	 * can only be the current context there.
+	 */
+	if (target_thread)
+		atomic_inc(&target_thread->tmp_ref);
 	spin_unlock(&t->lock);
 
 	if (target_proc) {
@@ -1676,6 +1685,10 @@ static void binder_free_transaction(stru
 			t->buffer->transaction = NULL;
 		binder_inner_proc_unlock(target_proc);
 	}
+
+	if (target_thread)
+		binder_thread_dec_tmpref(target_thread);
+
 	if (trace_binder_txn_latency_free_enabled())
 		binder_txn_latency_free(t);
 	/*
author maintainer
#121 lore raw

PATCH 119/518 rust_binder: use a u64 stride when cleaning up the offsets array

In reply to Greg Kroah-Hartman

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

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

From: Hyunwoo Kim <[email protected]>

commit 803c8a9502e9b97cd6ae937618ef4a8fd6274343 upstream.

Allocation's Drop walks the offsets array (binder_size_t = u64 entries), cleaning up the objects, but it used usize instead of u64 for both the stride and the per-entry read.

On 64-bit kernels (usize == u64) this is harmless, but on 32-bit kernels it walks the 8-byte entries in 4-byte steps, iterating an N-entry array 2N times, and reads the always-zero high word as offset 0, cleaning up the object at offset 0 N extra times. As a result the referenced node or handle ends up with a lower reference count than it actually has (a refcount over-decrement), and binder's reference accounting is corrupted; for example, the owner can be notified of a strong reference release (BR_RELEASE) even though references still remain.

Change the stride to u64, and read each entry as a u64, narrowing it to usize with try_into().

On 32-bit ARM, when this over-decrement would drive a count below zero, the driver's existing refcount guard refuses it and fires:

rust_binder: Failure: refcount underflow!

---
 drivers/android/binder/allocation.rs |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/android/binder/allocation.rs +3 -2
@@ -259,7 +259,7 @@ impl Drop for Allocation {
 
             if let Some(offsets) = info.offsets.clone() {
                 let view = AllocationView::new(self, offsets.start);
-                for i in offsets.step_by(size_of::<usize>()) {
+                for i in offsets.step_by(size_of::<u64>()) {
                     if view.cleanup_object(i).is_err() {
                         pr_warn!("Error cleaning up object at offset {}\n", i)
                     }
@@ -420,7 +420,8 @@ impl<'a> AllocationView<'a> {
     }
 
     fn cleanup_object(&self, index_offset: usize) -> Result {
-        let offset = self.alloc.read(index_offset)?;
+        let offset = self.alloc.read::<u64>(index_offset)?;
+        let offset: usize = offset.try_into().map_err(|_| EINVAL)?;
         let header = self.read::<BinderObjectHeader>(offset)?;
         match header.type_ {
             BINDER_TYPE_WEAK_BINDER | BINDER_TYPE_BINDER => {
author maintainer
#122 lore raw

PATCH 120/518 rust_binder: fix BINDER_GET_EXTENDED_ERROR

In reply to Greg Kroah-Hartman

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

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

From: Alice Ryhl <[email protected]>

commit 77bfebf110773f5a0d6b5ff8110896adb2c9c335 upstream.

This code currently copies the ExtendedError struct to the stack, modifies the copy, and then doesn't modify the original. Thus, fix it.

Furthermore, errors when replying must be delivered directly to the remote thread, so update deliver_reply() to take an extended error argument.

---
 drivers/android/binder/error.rs       |   13 ++----
 drivers/android/binder/thread.rs      |   65 ++++++++++++++++++++++++----------
 drivers/android/binder/transaction.rs |   15 +++----
 3 files changed, 58 insertions(+), 35 deletions(-)
drivers/android/binder/error.rs +5 -8
@@ -73,20 +73,17 @@ impl fmt::Debug for BinderError {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self.reply {
             BR_FAILED_REPLY => match self.source.as_ref() {
-                Some(source) => f
-                    .debug_struct("BR_FAILED_REPLY")
-                    .field("source", source)
-                    .finish(),
+                Some(source) => source.fmt(f),
                 None => f.pad("BR_FAILED_REPLY"),
             },
             BR_DEAD_REPLY => f.pad("BR_DEAD_REPLY"),
             BR_FROZEN_REPLY => f.pad("BR_FROZEN_REPLY"),
             BR_TRANSACTION_PENDING_FROZEN => f.pad("BR_TRANSACTION_PENDING_FROZEN"),
             BR_TRANSACTION_COMPLETE => f.pad("BR_TRANSACTION_COMPLETE"),
-            _ => f
-                .debug_struct("BinderError")
-                .field("reply", &self.reply)
-                .finish(),
+            _ => match self.source.as_ref() {
+                Some(source) => source.fmt(f),
+                None => self.reply.fmt(f),
+            },
         }
     }
 }
drivers/android/binder/thread.rs +46 -19

135 lines not on this page · raw message

drivers/android/binder/transaction.rs +7 -8
@@ -42,6 +42,7 @@ pub(crate) struct TransactionInfo {
     pub(crate) reply: u32,
     pub(crate) oneway_spam_suspect: bool,
     pub(crate) is_reply: bool,
+    pub(crate) debug_id: usize,
 }
 
 impl TransactionInfo {
@@ -93,7 +94,6 @@ impl Transaction {
         from: &Arc<Thread>,
         info: &mut TransactionInfo,
     ) -> BinderResult<DLArc<Self>> {
-        let debug_id = super::next_debug_id();
         let allow_fds = node_ref.node.flags & FLAT_BINDER_FLAG_ACCEPTS_FDS != 0;
         let txn_security_ctx = node_ref.node.flags & FLAT_BINDER_FLAG_TXN_SECURITY_CTX != 0;
         let mut txn_security_ctx_off = if txn_security_ctx { Some(0) } else { None };
@@ -101,7 +101,7 @@ impl Transaction {
         let mut alloc = match from.copy_transaction_data(
             to.clone(),
             info,
-            debug_id,
+            info.debug_id,
             allow_fds,
             txn_security_ctx_off.as_mut(),
         ) {
@@ -128,7 +128,7 @@ impl Transaction {
         let data_address = alloc.ptr;
 
         Ok(DTRWrap::arc_pin_init(pin_init!(Transaction {
-            debug_id,
+            debug_id: info.debug_id,
             target_node: Some(target_node),
             from_parent,
             sender_euid: Kuid::current_euid(),
@@ -152,9 +152,8 @@ impl Transaction {
         info: &mut TransactionInfo,
         allow_fds: bool,
     ) -> BinderResult<DLArc<Self>> {
-        let debug_id = super::next_debug_id();
         let mut alloc =
-            match from.copy_transaction_data(to.clone(), info, debug_id, allow_fds, None) {
+            match from.copy_transaction_data(to.clone(), info, info.debug_id, allow_fds, None) {
                 Ok(alloc) => alloc,
                 Err(err) => {
                     pr_warn!("Failure in copy_transaction_data: {:?}", err);
@@ -165,7 +164,7 @@ impl Transaction {
             alloc.set_info_clear_on_drop();
         }
         Ok(DTRWrap::arc_pin_init(pin_init!(Transaction {
-            debug_id,
+            debug_id: info.debug_id,
             target_node: None,
             from_parent: None,
             sender_euid: Kuid::current_euid(),
@@ -394,7 +393,7 @@ impl DeliverToRead for Transaction {
         let send_failed_reply = ScopeGuard::new(|| {
             if self.target_node.is_some() && self.flags & TF_ONE_WAY == 0 {
                 let reply = Err(BR_FAILED_REPLY);
-                self.from.deliver_reply(reply, &self);
+                self.from.deliver_reply(reply, &self, None);
             }
             self.drop_outstanding_txn();
         });
@@ -478,7 +477,7 @@ impl DeliverToRead for Transaction {
         // If this is not a reply or oneway transaction, then send a dead reply.
         if self.target_node.is_some() && self.flags & TF_ONE_WAY == 0 {
             let reply = Err(BR_DEAD_REPLY);
-            self.from.deliver_reply(reply, &self);
+            self.from.deliver_reply(reply, &self, None);
         }
 
         self.drop_outstanding_txn();
author maintainer
#123 lore raw

PATCH 121/518 rust_binder: reject context manager self-transaction

In reply to Greg Kroah-Hartman

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

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

From: Keshav Verma <[email protected]>

commit 6849cabfd30fb5727cfd31e8241e15801e17ebf9 upstream.

Rust binder resolved handle 0 to the context manager node, but it does not reject the case where the caller owns the same node.

The C binder driver rejects transactions from the context-manager process to handle 0 after resolving the target node. Match that behavior in Rust Binder by rejecting handle 0 transactions when the resolved context-manager node is owned by the calling process.

This applies to both synchronous and oneway transactions because both paths resolve the target through Process::get_transaction_node().

---
 drivers/android/binder/process.rs |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/android/binder/process.rs +5 -1
@@ -900,7 +900,11 @@ impl Process {
     pub(crate) fn get_transaction_node(&self, handle: u32) -> BinderResult<NodeRef> {
         // When handle is zero, try to get the context manager.
         if handle == 0 {
-            Ok(self.ctx.get_manager_node(true)?)
+            let node_ref = self.ctx.get_manager_node(true)?;
+            if core::ptr::eq(self, &*node_ref.node.owner) {
+                return Err(EINVAL.into());
+            }
+            Ok(node_ref)
         } else {
             Ok(self.get_node_from_handle(handle, true)?)
         }
author maintainer
#124 lore raw

PATCH 122/518 rust_binder: synchronize Rust Binder stats with freeze commands

In reply to Greg Kroah-Hartman

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

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

From: Keshav Verma <[email protected]>

commit eb1645bf10190e71f6f0316e37ff70755d719b53 upstream.

Rust Binder stats use BC_COUNT and BR_COUNT to size the command and return counters, and use event string tables when printing debug statistics.

The Binder protocol includes freeze-related commands and return codes, but the Rust Binder statistics code was not updated to cover them. As a result, those commands and return codes are not accounted for or printed by the stats debug output.

Update the counts and event string tables so these commands and return codes are included in the debug statistics output.

---
 drivers/android/binder/rust_binder_events.c |    7 ++++++-
 drivers/android/binder/stats.rs             |    4 ++--
 2 files changed, 8 insertions(+), 3 deletions(-)
drivers/android/binder/rust_binder_events.c +6 -1
@@ -28,6 +28,9 @@ const char * const binder_command_string
 	"BC_DEAD_BINDER_DONE",
 	"BC_TRANSACTION_SG",
 	"BC_REPLY_SG",
+	"BC_REQUEST_FREEZE_NOTIFICATION",
+	"BC_CLEAR_FREEZE_NOTIFICATION",
+	"BC_FREEZE_NOTIFICATION_DONE",
 };
 
 const char * const binder_return_strings[] = {
@@ -51,7 +54,9 @@ const char * const binder_return_strings
 	"BR_FAILED_REPLY",
 	"BR_FROZEN_REPLY",
 	"BR_ONEWAY_SPAM_SUSPECT",
-	"BR_TRANSACTION_PENDING_FROZEN"
+	"BR_TRANSACTION_PENDING_FROZEN",
+	"BR_FROZEN_BINDER",
+	"BR_CLEAR_FREEZE_NOTIFICATION_DONE",
 };
 
 #define CREATE_TRACE_POINTS
drivers/android/binder/stats.rs +2 -2
@@ -8,8 +8,8 @@ use crate::defs::*;
 use kernel::sync::atomic::{ordering::Relaxed, Atomic};
 use kernel::{ioctl::_IOC_NR, seq_file::SeqFile, seq_print};
 
-const BC_COUNT: usize = _IOC_NR(BC_REPLY_SG) as usize + 1;
-const BR_COUNT: usize = _IOC_NR(BR_TRANSACTION_PENDING_FROZEN) as usize + 1;
+const BC_COUNT: usize = _IOC_NR(BC_FREEZE_NOTIFICATION_DONE) as usize + 1;
+const BR_COUNT: usize = _IOC_NR(BR_CLEAR_FREEZE_NOTIFICATION_DONE) as usize + 1;
 
 pub(crate) static GLOBAL_STATS: BinderStats = BinderStats::new();
 
author maintainer
#125 lore raw

PATCH 123/518 rust_binder: clear freeze listener on node removal

In reply to Greg Kroah-Hartman

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

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

From: Alice Ryhl <[email protected]>

commit bc4a9828897871ff3e5a1f8a1d346decbf4ee95e upstream.

Generally userspace is supposed to explicitly clear freeze listeners before they drop the refcount on the node ref to zero, but there's nothing forcing that. Currently, in this scenario the freeze listener remains in the freeze_listeners rbtree and in the remote node's freeze listener list, even though the ref for which the listener is registered is gone. This could potentially lead to a memory leak due to a refcount cycle. Thus, remove the freeze listener in this scenario.

---
 drivers/android/binder/freeze.rs  |   11 +++++++++--
 drivers/android/binder/node.rs    |   10 ++++++----
 drivers/android/binder/process.rs |   12 +++++++++++-
 3 files changed, 26 insertions(+), 7 deletions(-)
drivers/android/binder/freeze.rs +9 -2
@@ -154,10 +154,17 @@ impl DeliverToRead for FreezeMessage {
 }
 
 impl FreezeListener {
-    pub(crate) fn on_process_exit(&self, proc: &Arc<Process>) {
+    /// Called when this freeze listener is cleared abnormally.
+    ///
+    /// This occurs either because the process exited or because the process dropped its last
+    /// refcount on the node ref without explicitly removing the freeze listener first.
+    ///
+    /// The returned `KVVec` is just a value that should be dropped outside of the lock.
+    pub(crate) fn on_process_cleanup(&self, proc: &Process) -> KVVec<Arc<Process>> {
         if !self.is_clearing {
-            self.node.remove_freeze_listener(proc);
+            return self.node.remove_freeze_listener(proc);
         }
+        KVVec::new()
     }
 }
 
drivers/android/binder/node.rs +6 -4
@@ -682,12 +682,13 @@ impl Node {
         }
     }
 
-    pub(crate) fn remove_freeze_listener(&self, p: &Arc<Process>) {
-        let _unused_capacity;
+    pub(crate) fn remove_freeze_listener(&self, p: &Process) -> KVVec<Arc<Process>> {
         let mut guard = self.owner.inner.lock();
         let inner = self.inner.access_mut(&mut guard);
         let len = inner.freeze_list.len();
-        inner.freeze_list.retain(|proc| !Arc::ptr_eq(proc, p));
+        inner
+            .freeze_list
+            .retain(|proc| !core::ptr::eq::<Process>(&**proc, p));
         if len == inner.freeze_list.len() {
             pr_warn!(
                 "Could not remove freeze listener for {}\n",
@@ -695,8 +696,9 @@ impl Node {
             );
         }
         if inner.freeze_list.is_empty() {
-            _unused_capacity = mem::take(&mut inner.freeze_list);
+            return mem::take(&mut inner.freeze_list);
         }
+        KVVec::new()
     }
 
     pub(crate) fn freeze_list<'a>(&'a self, guard: &'a ProcessInner) -> &'a [Arc<Process>] {
drivers/android/binder/process.rs +11 -1
@@ -946,6 +946,8 @@ impl Process {
 
         // To preserve original binder behaviour, we only fail requests where the manager tries to
         // increment references on itself.
+        let _to_free_freeze_listener;
+        let _to_free_freeze_listener_cleanup;
         let mut refs = self.node_refs.lock();
         if let Some(info) = refs.by_handle.get_mut(&handle) {
             if info.node_ref().update(inc, strong) {
@@ -961,6 +963,14 @@ impl Process {
                 unsafe { info.node_ref2().node.remove_node_info(info) };
 
                 let id = info.node_ref().node.global_id();
+
+                if let Some(freeze) = *info.freeze() {
+                    if let Some(fl) = refs.freeze_listeners.remove(&freeze) {
+                        _to_free_freeze_listener_cleanup = fl.on_process_cleanup(&self);
+                        _to_free_freeze_listener = fl;
+                    }
+                }
+
                 refs.by_handle.remove(&handle);
                 refs.by_node.remove(&id);
                 refs.handle_is_present.release_id(handle as usize);
@@ -1384,7 +1394,7 @@ impl Process {
         // Clean up freeze listeners.
         let freeze_listeners = take(&mut self.node_refs.lock().freeze_listeners);
         for listener in freeze_listeners.values() {
-            listener.on_process_exit(&self);
+            listener.on_process_cleanup(&self);
         }
         drop(freeze_listeners);
 
author maintainer
#126 lore raw

PATCH 124/518 usb: xhci: Fix sleep in atomic context in xhci_free_streams()

In reply to Greg Kroah-Hartman

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

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

From: 胡连勤 <[email protected]>

commit 42c37c4b75d38b51d84f31a8e29427f5e06a7c2a upstream.

When a USB device with active stream endpoints is disconnected, xhci_free_streams() is called from the hub_event workqueue to free the stream resources. It calls xhci_free_stream_info() while holding xhci->lock with irqs disabled.

xhci_free_stream_info() invokes xhci_free_stream_ctx(), which calls dma_free_coherent() for large stream context arrays.

dma_free_coherent() can sleep (e.g. via vunmap), triggering a BUG when called from atomic context.

Call trace:
 dma_free_attrs+0x174/0x220
 xhci_free_stream_info+0xd0/0x11c
 xhci_free_streams+0x278/0x37c
 usb_free_streams+0x98/0xc0
 usb_unbind_interface+0x1b8/0x2f8
 device_release_driver_internal+0x1d4/0x2cc
 device_release_driver+0x18/0x28
 bus_remove_device+0x160/0x1a4
 device_del+0x1ec/0x350
 usb_disable_device+0x98/0x214
 usb_disconnect+0xf0/0x35c
 hub_event+0xab4/0x19ec
 process_one_work+0x278/0x63c

Fix this by saving the stream_info pointers and clearing the ep references under the lock, then calling xhci_free_stream_info() outside the lock where sleeping is allowed.

Fixes 8df75f42f8e6 ("USB: xhci: Add memory allocation for USB3 bulk streams.")
Cc stable <[email protected]>
---
 drivers/usb/host/xhci.c |   11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/usb/host/xhci.c +10 -1
@@ -3788,6 +3788,7 @@ static int xhci_free_streams(struct usb_
 	struct xhci_virt_device *vdev;
 	struct xhci_command *command;
 	struct xhci_input_control_ctx *ctrl_ctx;
+	struct xhci_stream_info *stream_info[EP_CTX_PER_DEV];
 	unsigned int ep_index;
 	unsigned long flags;
 	u32 changed_ep_bitmask;
@@ -3848,10 +3849,15 @@ static int xhci_free_streams(struct usb_
 	if (ret < 0)
 		return ret;
 
+	/*
+	 * dma_free_coherent() called by xhci_free_stream_info() may sleep,
+	 * so save stream_info pointers and clear references under lock,
+	 * then free the memory outside lock.
+	 */
 	spin_lock_irqsave(&xhci->lock, flags);
 	for (i = 0; i < num_eps; i++) {
 		ep_index = xhci_get_endpoint_index(&eps[i]->desc);
-		xhci_free_stream_info(xhci, vdev->eps[ep_index].stream_info);
+		stream_info[i] = vdev->eps[ep_index].stream_info;
 		vdev->eps[ep_index].stream_info = NULL;
 		/* FIXME Unset maxPstreams in endpoint context and
 		 * update deq ptr to point to normal string ring.
@@ -3861,6 +3867,9 @@ static int xhci_free_streams(struct usb_
 	}
 	spin_unlock_irqrestore(&xhci->lock, flags);
 
+	for (i = 0; i < num_eps; i++)
+		xhci_free_stream_info(xhci, stream_info[i]);
+
 	return 0;
 }
 
author maintainer
#127 lore raw

PATCH 125/518 xhci: sideband: fix ring sg table pages leak

In reply to Greg Kroah-Hartman

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

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

From: Xu Rao <[email protected]>

commit 49f6e3c3ef19f04f6657ed8dce550e36c763abb8 upstream.

xhci_ring_to_sgtable() allocates a temporary pages array and uses it to build the returned sg_table with sg_alloc_table_from_pages().

The error paths free the pages array, but the success path returns the sg_table without freeing it. This leaks the temporary array every time a sideband client gets an endpoint or event ring buffer.

Free the pages array after sg_alloc_table_from_pages() succeeds. The returned sg_table has its own scatterlist entries and does not depend on the temporary array after construction.

Fixes de66754e9f80 ("xhci: sideband: add initial api to register a secondary interrupter entity")
Cc stable <[email protected]>
---
 drivers/usb/host/xhci-sideband.c |    2 ++
 1 file changed, 2 insertions(+)
drivers/usb/host/xhci-sideband.c +2 -0
@@ -58,6 +58,8 @@ xhci_ring_to_sgtable(struct xhci_sideban
 	if (sg_alloc_table_from_pages(sgt, pages, n_pages, 0, sz, GFP_KERNEL))
 		goto err;
 
+	kvfree(pages);
+
 	/*
 	 * Save first segment dma address to sg dma_address field for the sideband
 	 * client to have access to the IOVA of the ring.
author maintainer
#128 lore raw

PATCH 126/518 usb: typec: tcpci_rt1711h: unregister TCPCI port with devres

In reply to Greg Kroah-Hartman

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

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

From: Myeonghun Pak <[email protected]>

commit e8da46d99d3710106e7c44db14566bf9b57386b5 upstream.

rt1711h_probe() registers the TCPCI port before requesting the interrupt and enabling alert interrupts. If either of those later steps fails, the probe function returns without unregistering the TCPCI port. The explicit unregister currently only happens from the remove callback.

Register a devres action immediately after tcpci_register_port() succeeds, so tcpci_unregister_port() runs on later probe failures and on driver detach. Drop the remove callback to avoid unregistering the same port twice.

This issue was identified during our ongoing static-analysis research while reviewing kernel code.

Fixes 302c570bf36e ("usb: typec: tcpci_rt1711h: avoid screaming irq causing boot hangs")
Cc stable <[email protected]>
---
 drivers/usb/typec/tcpm/tcpci_rt1711h.c |   13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/usb/typec/tcpm/tcpci_rt1711h.c +8 -5
@@ -295,6 +295,8 @@ static int rt1711h_sw_reset(struct rt171
 	return 0;
 }
 
+static void rt1711h_unregister_tcpci_port(void *tcpci);
+
 static int rt1711h_probe(struct i2c_client *client)
 {
 	int ret;
@@ -340,6 +342,10 @@ static int rt1711h_probe(struct i2c_clie
 	if (IS_ERR_OR_NULL(chip->tcpci))
 		return PTR_ERR(chip->tcpci);
 
+	ret = devm_add_action_or_reset(chip->dev, rt1711h_unregister_tcpci_port, chip->tcpci);
+	if (ret)
+		return ret;
+
 	ret = devm_request_threaded_irq(chip->dev, client->irq, NULL,
 					rt1711h_irq,
 					IRQF_ONESHOT | IRQF_TRIGGER_LOW,
@@ -357,11 +363,9 @@ static int rt1711h_probe(struct i2c_clie
 	return 0;
 }
 
-static void rt1711h_remove(struct i2c_client *client)
+static void rt1711h_unregister_tcpci_port(void *tcpci)
 {
-	struct rt1711h_chip *chip = i2c_get_clientdata(client);
-
-	tcpci_unregister_port(chip->tcpci);
+	tcpci_unregister_port(tcpci);
 }
 
 static const struct rt1711h_chip_info rt1711h = {
@@ -394,7 +398,6 @@ static struct i2c_driver rt1711h_i2c_dri
 		.of_match_table = rt1711h_of_match,
 	},
 	.probe = rt1711h_probe,
-	.remove = rt1711h_remove,
 	.id_table = rt1711h_id,
 };
 module_i2c_driver(rt1711h_i2c_driver);
author maintainer
#129 lore raw

PATCH 127/518 riscv: dts: sophgo: Add dma-coherent to SG2042 PCIe controllers

In reply to Greg Kroah-Hartman

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

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

From: Han Gao <[email protected]>

commit 2647eabde8de748ee2c9a2816615d4af3bd4bf9d upstream.

SG2042's PCIe root complexes are cache-coherent with the CPU. Mark all four PCIe controller nodes (pcie_rc0 through pcie_rc3) as dma-coherent so the kernel uses coherent DMA mappings instead of non-coherent bounce buffering.

---
 arch/riscv/boot/dts/sophgo/sg2042.dtsi |    4 ++++
 1 file changed, 4 insertions(+)
arch/riscv/boot/dts/sophgo/sg2042.dtsi +4 -0
@@ -417,6 +417,7 @@
 			vendor-id = <0x1f1c>;
 			device-id = <0x2042>;
 			cdns,no-bar-match-nbits = <48>;
+			dma-coherent;
 			msi-parent = <&msi>;
 			status = "disabled";
 		};
@@ -439,6 +440,7 @@
 			vendor-id = <0x1f1c>;
 			device-id = <0x2042>;
 			cdns,no-bar-match-nbits = <48>;
+			dma-coherent;
 			msi-parent = <&msi>;
 			status = "disabled";
 		};
@@ -461,6 +463,7 @@
 			vendor-id = <0x1f1c>;
 			device-id = <0x2042>;
 			cdns,no-bar-match-nbits = <48>;
+			dma-coherent;
 			msi-parent = <&msi>;
 			status = "disabled";
 		};
@@ -483,6 +486,7 @@
 			vendor-id = <0x1f1c>;
 			device-id = <0x2042>;
 			cdns,no-bar-match-nbits = <48>;
+			dma-coherent;
 			msi-parent = <&msi>;
 			status = "disabled";
 		};
author maintainer
#130 lore raw

PATCH 128/518 PCI: loongson: Override PCIe bridge supported speeds for Loongson-3C6000 series

In reply to Greg Kroah-Hartman

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

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

From: Ziyao Li <[email protected]>

commit e373c789bac0ad73b472d8b44714df3bd18a4edf upstream.

Older steppings of the Loongson-3C6000 series incorrectly report the supported link speeds on their PCIe bridges (device IDs 0x3c19, 0x3c29) as only 2.5 GT/s, despite the upstream bus supporting speeds from 2.5 GT/s up to 16 GT/s.

As a result, since commit 774c71c52aa4 ("PCI/bwctrl: Enable only if more than one speed is supported"), bwctrl will be disabled if there's only one 2.5 GT/s value in vector 'supported_speeds'.

Manually override the 'supported_speeds' field for affected PCIe bridges with those found on the upstream bus to correctly reflect the supported link speeds. Updating the speeds to reflect what the hardware actually supports avoids quirks in drivers consuming the speed information.

This commit was originally found from AOSC OS[1].

Fixes cd89edda4002 ("PCI: loongson: Add ACPI init support")
[Ziyao Li: move from drivers/pci/quirks.c to drivers/pci/controller/pci-loongson.c]
[Xi Ruoyao: Fixed falling through logic, added debug log, Fixes tag and rebased to 7.0-rc7]
[bhelgaas: commit log, https://lore.kernel.org/all/[email protected]]
---
 drivers/pci/controller/pci-loongson.c |   36 ++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)
drivers/pci/controller/pci-loongson.c +36 -0
@@ -176,6 +176,42 @@ static void loongson_pci_msi_quirk(struc
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, DEV_LS7A_PCIE_PORT5, loongson_pci_msi_quirk);
 
+/*
+ * Older steppings of the Loongson-3C6000 series incorrectly report the
+ * supported link speeds on their PCIe bridges (device IDs 0x3c19,
+ * 0x3c29) as only 2.5 GT/s, despite the upstream bus supporting speeds
+ * from 2.5 GT/s up to 16 GT/s.
+ */
+static void loongson_pci_bridge_speed_quirk(struct pci_dev *pdev)
+{
+	u8 old_supported_speeds = pdev->supported_speeds;
+
+	switch (pdev->bus->max_bus_speed) {
+	case PCIE_SPEED_16_0GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_16_0GB;
+		fallthrough;
+	case PCIE_SPEED_8_0GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_8_0GB;
+		fallthrough;
+	case PCIE_SPEED_5_0GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_5_0GB;
+		fallthrough;
+	case PCIE_SPEED_2_5GT:
+		pdev->supported_speeds |= PCI_EXP_LNKCAP2_SLS_2_5GB;
+		break;
+	default:
+		pci_warn(pdev, "unexpected max bus speed");
+
+		return;
+	}
+
+	if (pdev->supported_speeds != old_supported_speeds)
+		pci_info(pdev, "fixed up supported link speeds: 0x%x => 0x%x",
+			 old_supported_speeds, pdev->supported_speeds);
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_LOONGSON, 0x3c19, loongson_pci_bridge_speed_quirk);
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_LOONGSON, 0x3c29, loongson_pci_bridge_speed_quirk);
+
 static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus)
 {
 	struct pci_config_window *cfg;
author maintainer
#131 lore raw

PATCH 129/518 PCI: altera: Do not dispose parent IRQ mapping

In reply to Greg Kroah-Hartman

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

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

From: Mahesh Vaidya <[email protected]>

commit 5ef4bac02189bee0b7c170e352d7a38e13fe9678 upstream.

altera_pcie_irq_teardown() calls irq_dispose_mapping() on pcie->irq. However, pcie->irq is the parent IRQ returned by platform_get_irq(), not the mapping created by Altera INTx irq_domain.

The Altera driver only sets the chained handler on the parent IRQ. It should detach that handler during teardown, but it should not dispose the parent IRQ mapping, which belongs to the parent interrupt controller's irq_domain.

Drop irq_dispose_mapping(pcie->irq) from the teardown path.

Note that during irqchip remove(), the child IRQs should've disposed. But since the chained handler itself is removed, there is no way the stale child IRQs (if exists) could fire. So it is safe here.

Fixes ec15c4d0d5d2 ("PCI: altera: Allow building as module")
[mani: added a note about IRQ disposal]
---
 drivers/pci/controller/pcie-altera.c |    1 -
 1 file changed, 1 deletion(-)
drivers/pci/controller/pcie-altera.c +0 -1
@@ -868,7 +868,6 @@ static void altera_pcie_irq_teardown(str
 {
 	irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
 	irq_domain_remove(pcie->irq_domain);
-	irq_dispose_mapping(pcie->irq);
 }
 
 static int altera_pcie_parse_dt(struct altera_pcie *pcie)
author maintainer
#132 lore raw

PATCH 130/518 PCI: altera: Fix resource leaks on probe failure

In reply to Greg Kroah-Hartman

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

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

From: Mahesh Vaidya <[email protected]>

commit 7a94138caeb27f3c49c1dbd93bf422098925bb28 upstream.

The chained IRQ handler is set during probe, but is only removed during the driver remove(). If pci_host_probe() fails, the handler and INTx IRQ domain remain set even though the devm-managed host bridge storage containing struct altera_pcie will be released, leaving the handler with a stale data pointer.

Interrupts are also enabled before pci_host_probe() is called. If probe fails after that point, the controller interrupt source should be disabled before the chained handler and INTx domain are removed.

So set the chained handler only after the INTx domain has been created. Disable controller interrupts during IRQ teardown, and tear the IRQ setup down if pci_host_probe() fails.

Fixes c63aed7334c2 ("PCI: altera: Use pci_host_probe() to register host")
[mani: commit log]
---
 drivers/pci/controller/pcie-altera.c |   35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)
drivers/pci/controller/pcie-altera.c +33 -2
@@ -864,8 +864,23 @@ static int altera_pcie_init_irq_domain(s
 	return 0;
 }
 
+static void altera_pcie_disable_irq(struct altera_pcie *pcie)
+{
+	if (pcie->pcie_data->version == ALTERA_PCIE_V1 ||
+	    pcie->pcie_data->version == ALTERA_PCIE_V2) {
+		/* Disable all P2A interrupts */
+		cra_writel(pcie, 0, P2A_INT_ENABLE);
+	} else if (pcie->pcie_data->version == ALTERA_PCIE_V3) {
+		/* Disable port-level interrupts (CFG_AER, etc.) */
+		writel(0, pcie->hip_base +
+			  pcie->pcie_data->port_conf_offset +
+			  pcie->pcie_data->port_irq_enable_offset);
+	}
+}
+
 static void altera_pcie_irq_teardown(struct altera_pcie *pcie)
 {
+	altera_pcie_disable_irq(pcie);
 	irq_set_chained_handler_and_data(pcie->irq, NULL, NULL);
 	irq_domain_remove(pcie->irq_domain);
 }
@@ -890,7 +905,6 @@ static int altera_pcie_parse_dt(struct a
 	if (pcie->irq < 0)
 		return pcie->irq;
 
-	irq_set_chained_handler_and_data(pcie->irq, pcie->pcie_data->ops->rp_isr, pcie);
 	return 0;
 }
 
@@ -1019,6 +1033,14 @@ static int altera_pcie_probe(struct plat
 		return ret;
 	}
 
+	/*
+	 * The chained handler uses pcie->irq_domain, so set it only after the
+	 * INTx domain has been created.
+	 */
+	irq_set_chained_handler_and_data(pcie->irq,
+					 pcie->pcie_data->ops->rp_isr,
+					 pcie);
+
 	if (pcie->pcie_data->version == ALTERA_PCIE_V1 ||
 	    pcie->pcie_data->version == ALTERA_PCIE_V2) {
 		/* clear all interrupts */
@@ -1036,7 +1058,16 @@ static int altera_pcie_probe(struct plat
 	bridge->busnr = pcie->root_bus_nr;
 	bridge->ops = &altera_pcie_ops;
 
-	return pci_host_probe(bridge);
+	ret = pci_host_probe(bridge);
+	if (ret)
+		goto err_teardown_irq;
+
+	return 0;
+
+err_teardown_irq:
+	altera_pcie_irq_teardown(pcie);
+
+	return ret;
 }
 
 static void altera_pcie_remove(struct platform_device *pdev)
author maintainer
#133 lore raw

PATCH 131/518 PCI: Always lift 2.5GT/s restriction in PCIe failed link retraining

In reply to Greg Kroah-Hartman

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

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

From: Maciej W. Rozycki <[email protected]>

commit 72780f7964684939d7d2f69c348876213b184484 upstream.

Discard Vendor:Device ID matching in the PCIe failed link retraining quirk and ignore the link status for the removal of the 2.5GT/s speed clamp, whether applied by the quirk itself or the firmware earlier on. Revert to the original target link speed if this final link retraining has failed.

This is so that link training noise in hot-plug scenarios does not make a link remain clamped to the 2.5GT/s speed where an event race has led the quirk to apply the speed clamp for one device, only to leave it in place for a subsequent device to be plugged in.

Refer to the Link Capabilities register directly for the maximum link speed determination so as to streamline backporting.

---
 drivers/pci/quirks.c |   51 ++++++++++++++++++---------------------------------
 1 file changed, 18 insertions(+), 33 deletions(-)
drivers/pci/quirks.c +18 -33
@@ -80,11 +80,10 @@ static bool pcie_lbms_seen(struct pci_de
  * Restrict the speed to 2.5GT/s then with the Target Link Speed field,
  * request a retrain and check the result.
  *
- * If this turns out successful and we know by the Vendor:Device ID it is
- * safe to do so, then lift the restriction, letting the devices negotiate
- * a higher speed.  Also check for a similar 2.5GT/s speed restriction the
- * firmware may have already arranged and lift it with ports that already
- * report their data link being up.
+ * If this turns out successful, or where a 2.5GT/s speed restriction has
+ * been previously arranged by the firmware and the port reports its link
+ * already being up, lift the restriction, in a hope it is safe to do so,
+ * letting the devices negotiate a higher speed.
  *
  * Otherwise revert the speed to the original setting and request a retrain
  * again to remove any residual state, ignoring the result as it's supposed
@@ -95,52 +94,38 @@ static bool pcie_lbms_seen(struct pci_de
  */
 int pcie_failed_link_retrain(struct pci_dev *dev)
 {
-	static const struct pci_device_id ids[] = {
-		{ PCI_VDEVICE(ASMEDIA, 0x2824) }, /* ASMedia ASM2824 */
-		{}
-	};
-	u16 lnksta, lnkctl2;
+	u16 lnksta, lnkctl2, oldlnkctl2;
 	int ret = -ENOTTY;
+	u32 lnkcap;
 
 	if (!pci_is_pcie(dev) || !pcie_downstream_port(dev) ||
 	    !pcie_cap_has_lnkctl2(dev) || !dev->link_active_reporting)
 		return ret;
 
 	pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
+	pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &oldlnkctl2);
 	if (!(lnksta & PCI_EXP_LNKSTA_DLLLA) && pcie_lbms_seen(dev, lnksta)) {
-		u16 oldlnkctl2;
-
 		pci_info(dev, "broken device, retraining non-functional downstream link at 2.5GT/s\n");
-
-		pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &oldlnkctl2);
 		ret = pcie_set_target_speed(dev, PCIE_SPEED_2_5GT, false);
-		if (ret) {
-			pci_info(dev, "retraining failed\n");
-			pcie_set_target_speed(dev, PCIE_LNKCTL2_TLS2SPEED(oldlnkctl2),
-					      true);
-			return ret;
-		}
-
-		pcie_capability_read_word(dev, PCI_EXP_LNKSTA, &lnksta);
+		if (ret)
+			goto err;
 	}
 
 	pcie_capability_read_word(dev, PCI_EXP_LNKCTL2, &lnkctl2);
-
-	if ((lnksta & PCI_EXP_LNKSTA_DLLLA) &&
-	    (lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT &&
-	    pci_match_id(ids, dev)) {
-		u32 lnkcap;
-
+	pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
+	if ((lnkctl2 & PCI_EXP_LNKCTL2_TLS) == PCI_EXP_LNKCTL2_TLS_2_5GT &&
+	    (lnkcap & PCI_EXP_LNKCAP_SLS) != PCI_EXP_LNKCAP_SLS_2_5GB) {
 		pci_info(dev, "removing 2.5GT/s downstream link speed restriction\n");
-		pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap);
 		ret = pcie_set_target_speed(dev, PCIE_LNKCAP_SLS2SPEED(lnkcap), false);
-		if (ret) {
-			pci_info(dev, "retraining failed\n");
-			return ret;
-		}
+		if (ret)
+			goto err;
 	}
 
 	return ret;
+err:
+	pci_info(dev, "retraining failed\n");
+	pcie_set_target_speed(dev, PCIE_LNKCTL2_TLS2SPEED(oldlnkctl2), true);
+	return ret;
 }
 
 static ktime_t fixup_debug_start(struct pci_dev *dev,
author maintainer
#134 lore raw

PATCH 132/518 PCI: host-common: Request bus reassignment when not probe-only

In reply to Greg Kroah-Hartman

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

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

From: Ratheesh Kannoth <[email protected]>

commit fda8749ba73638f5bbca3ffb39bc6861eb3b23fa upstream.

pci_host_common_init() is used by several generic ECAM host drivers. After PCI core changes around pci_flags and preserve_config, these hosts no longer opted into full bus number reassignment the way they did before, which broke enumeration of devices on a Marvell CN106XX board.

When PCI_PROBE_ONLY is not set, add PCI_REASSIGN_ALL_BUS so pci_scan_bridge_extend() takes the reassignment path: bus numbers can be assigned from firmware EA data (e.g. pci_ea_fixed_busnrs()). Skip the flag in probe-only mode so existing assignments are not overridden.

Fixes 7246a4520b4b ("PCI: Use preserve_config in place of pci_flags")
[mani: added stable tag]
[bhelgaas: add problem report link]
Cc Vidya Sagar <[email protected]>
---
 drivers/pci/controller/pci-host-common.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/pci/controller/pci-host-common.c +4 -0
@@ -68,6 +68,10 @@ int pci_host_common_init(struct platform
 	if (IS_ERR(cfg))
 		return PTR_ERR(cfg);
 
+	/* Do not reassign bus numbers if probe only */
+	if (!pci_has_flag(PCI_PROBE_ONLY))
+		pci_add_flags(PCI_REASSIGN_ALL_BUS);
+
 	bridge->sysdata = cfg;
 	bridge->ops = (struct pci_ops *)&ops->pci_ops;
 	bridge->enable_device = ops->enable_device;
author maintainer
#135 lore raw

PATCH 133/518 PCI: imx6: Configure REF_USE_PAD before PHY reset for i.MX95

In reply to Greg Kroah-Hartman

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

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

From: Richard Zhu <[email protected]>

commit 0c26b1c34d12d4debfb5363cc0be6cdf68e87ba2 upstream.

According to the i.MX95 PCIe PHY Databook, the ref_use_pad signal in the Common Block Signals section selects the reference clock source connected to the PHY pads. Per the specification, any change to this input must be followed by a PHY reset assertion to take effect.

Move the REF_USE_PAD configuration before the PHY reset toggle to comply with the required initialization sequence.

Fixes 47f54a902dcd ("PCI: imx6: Toggle the core reset for i.MX95 PCIe")
[mani: renamed the callback and helper to match the usecase]
---
 drivers/pci/controller/dwc/pci-imx6.c |   27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)
drivers/pci/controller/dwc/pci-imx6.c +24 -3
@@ -137,6 +137,7 @@ struct imx_pcie_drvdata {
 	const u32 mode_off[IMX_PCIE_MAX_INSTANCES];
 	const u32 mode_mask[IMX_PCIE_MAX_INSTANCES];
 	const struct pci_epc_features *epc_features;
+	int (*select_ref_clk_src)(struct imx_pcie *pcie);
 	int (*init_phy)(struct imx_pcie *pcie);
 	int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable);
 	int (*core_reset)(struct imx_pcie *pcie, bool assert);
@@ -247,6 +248,24 @@ static unsigned int imx_pcie_grp_offset(
 	return imx_pcie->controller_id == 1 ? IOMUXC_GPR16 : IOMUXC_GPR14;
 }
 
+static int imx95_pcie_select_ref_clk_src(struct imx_pcie *imx_pcie)
+{
+	bool ext = imx_pcie->enable_ext_refclk;
+
+	/*
+	 * Regarding the Signal Descriptions of i.MX95 PCIe PHY, ref_use_pad is
+	 * used to select reference clock connected to a pair of pads.
+	 *
+	 * Any change in this input must be followed by phy_reset assertion.
+	 */
+
+	regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_GEN_CTRL,
+			   IMX95_PCIE_REF_USE_PAD,
+			   ext ? IMX95_PCIE_REF_USE_PAD : 0);
+
+	return 0;
+}
+
 static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie)
 {
 	bool ext = imx_pcie->enable_ext_refclk;
@@ -269,9 +288,6 @@ static int imx95_pcie_init_phy(struct im
 			IMX95_PCIE_PHY_CR_PARA_SEL,
 			IMX95_PCIE_PHY_CR_PARA_SEL);
 
-	regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_PHY_GEN_CTRL,
-			   IMX95_PCIE_REF_USE_PAD,
-			   ext ? IMX95_PCIE_REF_USE_PAD : 0);
 	regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
 			   IMX95_PCIE_REF_CLKEN,
 			   ext ? 0 : IMX95_PCIE_REF_CLKEN);
@@ -1256,6 +1272,9 @@ static int imx_pcie_host_init(struct dw_
 		pp->bridge->disable_device = imx_pcie_disable_device;
 	}
 
+	if (imx_pcie->drvdata->select_ref_clk_src)
+		imx_pcie->drvdata->select_ref_clk_src(imx_pcie);
+
 	imx_pcie_assert_core_reset(imx_pcie);
 	imx_pcie_assert_perst(imx_pcie, true);
 
@@ -1967,6 +1986,7 @@ static const struct imx_pcie_drvdata drv
 		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
 		.core_reset = imx95_pcie_core_reset,
 		.init_phy = imx95_pcie_init_phy,
+		.select_ref_clk_src = imx95_pcie_select_ref_clk_src,
 		.wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
 		.enable_ref_clk = imx95_pcie_enable_ref_clk,
 		.clr_clkreq_override = imx95_pcie_clr_clkreq_override,
@@ -2022,6 +2042,7 @@ static const struct imx_pcie_drvdata drv
 		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
 		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
 		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
+		.select_ref_clk_src = imx95_pcie_select_ref_clk_src,
 		.init_phy = imx95_pcie_init_phy,
 		.core_reset = imx95_pcie_core_reset,
 		.wait_pll_lock = imx95_pcie_wait_for_phy_pll_lock,
author maintainer
#136 lore raw

PATCH 134/518 PCI: imx6: Fix IMX6SX_GPR12_PCIE_TEST_POWERDOWN handling

In reply to Greg Kroah-Hartman

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

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

From: Richard Zhu <[email protected]>

commit aad953fb4eed0df5486cd54ccad80ac197678e01 upstream.

The IMX6SX_GPR12_PCIE_TEST_POWERDOWN bit does not control the PCIe reference clock on i.MX6SX. Instead, it is part of i.MX6SX PCIe core reset sequence.

Move the IMX6SX_GPR12_PCIE_TEST_POWERDOWN assertion/deassertion into the core reset functions to properly reflect its purpose. Remove the .enable_ref_clk() callback for i.MX6SX since it was incorrectly manipulating this bit.

---
 drivers/pci/controller/dwc/pci-imx6.c |   12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)
drivers/pci/controller/dwc/pci-imx6.c +3 -9
@@ -681,14 +681,6 @@ static int imx_pcie_attach_pd(struct dev
 	return 0;
 }
 
-static int imx6sx_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
-{
-	regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
-			   IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
-			   enable ? 0 : IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
-	return 0;
-}
-
 static int imx6q_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
 {
 	if (enable) {
@@ -802,6 +794,9 @@ static int imx6sx_pcie_core_reset(struct
 	if (assert)
 		regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
 				IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
+	else
+		regmap_clear_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
+				  IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
 
 	/* Force PCIe PHY reset */
 	regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5, IMX6SX_GPR5_PCIE_BTNRST_RESET,
@@ -1896,7 +1891,6 @@ static const struct imx_pcie_drvdata drv
 		.mode_off[0] = IOMUXC_GPR12,
 		.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
 		.init_phy = imx6sx_pcie_init_phy,
-		.enable_ref_clk = imx6sx_pcie_enable_ref_clk,
 		.core_reset = imx6sx_pcie_core_reset,
 		.ops = &imx_pcie_host_ops,
 	},
author maintainer
#137 lore raw

PATCH 135/518 PCI: imx6: Assert ref_clk_en after reference clock stabilizes on i.MX95

In reply to Greg Kroah-Hartman

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

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

From: Richard Zhu <[email protected]>

commit 9dda3f83ba677b9cc2613cecd9120123000ae50f upstream.

According to the PHY Databook Common Block Signals section, the ref_clk_en signal must remain de-asserted until the reference clock is running at the appropriate frequency. Once the clock is stable, ref_clk_en can be asserted. For lower power states where the reference clock to the PHY is disabled, ref_clk_en should also be de-asserted.

Move the ref_clk_en bit manipulation into imx95_pcie_enable_ref_clk() to ensure the reference clock stabilizes before ref_clk_en is asserted and before the PHY reset is de-asserted. This aligns with the timing requirements specified in the PHY documentation.

Fixes d8574ce57d76 ("PCI: imx6: Add external reference clock input mode support")
---
 drivers/pci/controller/dwc/pci-imx6.c |   28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)
drivers/pci/controller/dwc/pci-imx6.c +22 -6
@@ -268,8 +268,6 @@ static int imx95_pcie_select_ref_clk_src
 
 static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie)
 {
-	bool ext = imx_pcie->enable_ext_refclk;
-
 	/*
 	 * ERR051624: The Controller Without Vaux Cannot Exit L23 Ready
 	 * Through Beacon or PERST# De-assertion
@@ -288,10 +286,6 @@ static int imx95_pcie_init_phy(struct im
 			IMX95_PCIE_PHY_CR_PARA_SEL,
 			IMX95_PCIE_PHY_CR_PARA_SEL);
 
-	regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
-			   IMX95_PCIE_REF_CLKEN,
-			   ext ? 0 : IMX95_PCIE_REF_CLKEN);
-
 	return 0;
 }
 
@@ -740,7 +734,29 @@ static void imx95_pcie_clkreq_override(s
 
 static int imx95_pcie_enable_ref_clk(struct imx_pcie *imx_pcie, bool enable)
 {
+	bool ext = imx_pcie->enable_ext_refclk;
+
 	imx95_pcie_clkreq_override(imx_pcie, enable);
+	/*
+	 * The ref_clk_en signal must remain de-asserted until the
+	 * reference clock is running at appropriate frequency, at which
+	 * point this bit can be asserted. For lower power states where
+	 * the reference clock to the PHY is disabled, it may also be
+	 * de-asserted.
+	 * +------------------- -+--------+----------------+
+	 * | External clock mode | Enable | PCIE_REF_CLKEN |
+	 * +---------------------+--------+----------------+
+	 * | TRUE                | X      | 1b'0           |
+	 * +---------------------+--------+----------------+
+	 * | FALSE               | TRUE   | 1b'1           |
+	 * +---------------------+--------+----------------+
+	 * | FALSE               | FALSE  | 1b'0           |
+	 * +---------------------+--------+----------------+
+	 */
+	regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0,
+			   IMX95_PCIE_REF_CLKEN,
+			   ext || !enable ? 0 : IMX95_PCIE_REF_CLKEN);
+
 	return 0;
 }