This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 6.15.5-rc1
Cyril Bur cyrilbur@tenstorrent.com riscv: uaccess: Only restore the CSR_STATUS SUM bit
Jens Axboe axboe@kernel.dk io_uring: gate REQ_F_ISREG on !S_ANON_INODE as well
Jens Axboe axboe@kernel.dk io_uring/kbuf: flag partial buffer mappings
Heiko Carstens hca@linux.ibm.com s390/ptrace: Fix pointer dereferencing in regs_get_kernel_stack_nth()
Chang S. Bae chang.seok.bae@intel.com x86/pkeys: Simplify PKRU update in signal frame
Chang S. Bae chang.seok.bae@intel.com x86/fpu: Refactor xfeature bitmask update code for sigframe XSAVE
Danilo Krummrich dakr@kernel.org rust: devres: do not dereference to the internal Revocable
Danilo Krummrich dakr@kernel.org rust: devres: fix race in Devres::drop()
Danilo Krummrich dakr@kernel.org rust: revocable: indicate whether `data` has been revoked already
Danilo Krummrich dakr@kernel.org rust: completion: implement initial abstraction
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Export full brightness range to userspace
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Optimize custom brightness curve
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Only read ACPI backlight caps once
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Fix default DC and AC levels
Michael Strauss michael.strauss@amd.com drm/amd/display: Get LTTPR IEEE OUI/Device ID From Closest LTTPR To Host
Michael Strauss michael.strauss@amd.com drm/amd/display: Add early 8b/10b channel equalization test pattern sequence
Sasha Levin sashal@kernel.org sched_ext: Make scx_group_set_weight() always update tg->scx.weight
Sasha Levin sashal@kernel.org arm64: dts: qcom: x1e78100-t14s: fix missing HID supplies
Alex Deucher alexander.deucher@amd.com drm/amdgpu/mes: add missing locking in helper functions
Eric Biggers ebiggers@google.com crypto: powerpc/poly1305 - add depends on BROKEN for now
Stephan Gerhold stephan.gerhold@linaro.org arm64: dts: qcom: x1-crd: Fix vreg_l2j_1p2 voltage
Sasha Levin sashal@kernel.org arm64: dts: qcom: x1e78100-t14s: mark l12b and l15b always-on
Johan Hovold johan+linaro@kernel.org arm64: dts: qcom: x1e80100-crd: mark l12b and l15b always-on
Konrad Dybcio konrad.dybcio@oss.qualcomm.com arm64: dts: qcom: Commonize X1 CRD DTSI
Alex Hung alex.hung@amd.com drm/amd/display: Fix mpv playback corruption on weston
Peichen Huang PeiChen.Huang@amd.com drm/amd/display: Add dc cap for dp tunneling
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Add more checks for DSC / HUBP ONO guarantees
Frank Min Frank.Min@amd.com drm/amdgpu: add kicker fws loading for gfx11/smu13/psp13
Alex Deucher alexander.deucher@amd.com drm/amdgpu: switch job hw_fence to amdgpu_fence
Jesse Zhang jesse.zhang@amd.com drm/amdgpu: Fix SDMA UTC_L1 handling during start/stop sequences
Ville Syrjälä ville.syrjala@linux.intel.com drm/i915/dsi: Fix off by one in BXT_MIPI_TRANS_VTOTAL
Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com drm/xe: Fix early wedge on GuC load failure
Lucas De Marchi lucas.demarchi@intel.com drm/xe: Fix taking invalid lock on wedge
Lucas De Marchi lucas.demarchi@intel.com drm/xe: Fix memset on iomem
Alex Hung alex.hung@amd.com drm/amd/display: Check dce_hwseq before dereferencing it
Frank Min Frank.Min@amd.com drm/amdgpu: Add kicker device detection
Sonny Jiang sonny.jiang@amd.com drm/amdgpu: VCN v5_0_1 to prevent FW checking RB during DPG pause
Yihan Zhu Yihan.Zhu@amd.com drm/amd/display: Fix RMCM programming seq errors
Matthew Auld matthew.auld@intel.com drm/xe/guc_submit: add back fix
Matthew Auld matthew.auld@intel.com drm/xe/sched: stop re-submitting signalled jobs
Matthew Auld matthew.auld@intel.com drm/xe/vm: move rebind_work init earlier
Zhongwei Zhang Zhongwei.Zhang@amd.com drm/amd/display: Correct non-OLED pre_T11_delay.
Alex Deucher alexander.deucher@amd.com drm/amdgpu: disable workload profile switching when OD is enabled
John Olender john.olender@gmail.com drm/amdgpu: amdgpu_vram_mgr_new(): Clamp lpfn to total vram
Wentao Liang vulab@iscas.ac.cn drm/amd/display: Add null pointer check for get_first_active_display()
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Wait for Clk and Data Lanes to be ready
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Check return value when getting default PHY config
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Fix connecting to next bridge
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Fix phy de-init and flag it so
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Fix the clock variable for mode_valid()
Imre Deak imre.deak@intel.com drm/i915/dp_mst: Work around Thunderbolt sink disconnect after SINK_COUNT_ESI read
Imre Deak imre.deak@intel.com drm/i915/ptl: Use everywhere the correct DDI port clock select mask
Jay Cornwall jay.cornwall@amd.com drm/amdkfd: Fix race in GWS queue scheduling
Stephan Gerhold stephan.gerhold@linaro.org drm/msm/gpu: Fix crash when throttling GPU immediately during boot
Thomas Zimmermann tzimmermann@suse.de drm/udl: Unregister device before cleaning up on disconnect
Qiu-ji Chen chenqiuji666@gmail.com drm/tegra: Fix a possible null pointer dereference
Thierry Reding treding@nvidia.com drm/tegra: Assign plane type before registration
Thomas Zimmermann tzimmermann@suse.de drm/simpledrm: Do not upcast in release helpers
Luca Ceresoli luca.ceresoli@bootlin.com drm/panel: simple: Tianma TM070JDHG34-00: add delays
Maíra Canal mcanal@igalia.com drm/etnaviv: Protect the scheduler's pending list with its lock
Thomas Zimmermann tzimmermann@suse.de drm/cirrus-qemu: Fix pitch programming
Thomas Zimmermann tzimmermann@suse.de drm/ast: Fix comment on modeset lock
Karan Tilak Kumar kartilak@cisco.com scsi: fnic: Turn off FDMI ACTIVE flags on link down
Karan Tilak Kumar kartilak@cisco.com scsi: fnic: Fix crash in fnic_wq_cmpl_handler when FDMI times out
anvithdosapati anvithdosapati@google.com scsi: ufs: core: Fix clk scaling to be conditional in reset and restore
Chen Yu yu.c.chen@intel.com scsi: megaraid_sas: Fix invalid node index
Qasim Ijaz qasdev00@gmail.com HID: wacom: fix kobject reference count leak
Qasim Ijaz qasdev00@gmail.com HID: wacom: fix memory leak on sysfs attribute creation failure
Qasim Ijaz qasdev00@gmail.com HID: wacom: fix memory leak on kobject creation failure
Iusico Maxim iusico.maxim@libero.it HID: lenovo: Restrict F7/9/11 mode to compact keyboards only
Qasim Ijaz qasdev00@gmail.com HID: appletb-kbd: fix "appletb_backlight" backlight device reference counting
Chao Yu chao@kernel.org f2fs: fix to zero post-eof page
David Hildenbrand david@redhat.com mm/gup: revert "mm: gup: fix infinite loop within __get_longterm_locked"
Kairui Song kasong@tencent.com mm/shmem, swap: fix softlockup with mTHP swapin
Kairui Song kasong@tencent.com mm: userfaultfd: fix race of userfaultfd_move and swap cache
Liam R. Howlett Liam.Howlett@oracle.com maple_tree: fix MA_STATE_PREALLOC flag in mas_preallocate()
Jiawen Wu jiawenwu@trustnetic.com net: libwx: fix the creation of page_pool
Khairul Anuar Romli khairul.anuar.romli@altera.com spi: spi-cadence-quadspi: Fix pm runtime unbalance
Stephen Smalley stephen.smalley.work@gmail.com selinux: change security_compute_sid to return the ssid or tsid on match
Kuan-Wei Chiu visitorckw@gmail.com Revert "bcache: remove heap-related macros and switch to generic min_heap"
Kuan-Wei Chiu visitorckw@gmail.com Revert "bcache: update min_heap_callbacks to use default builtin swap"
Filipe Manana fdmanana@suse.com btrfs: fix invalid inode pointer dereferences during log replay
Mark Harmstone maharmstone@fb.com btrfs: update superblock's device bytes_used when dropping chunk
Filipe Manana fdmanana@suse.com btrfs: fix a race between renames and directory logging
Kuan-Wei Chiu visitorckw@gmail.com bcache: remove unnecessary select MIN_HEAP
Heinz Mauelshagen heinzm@redhat.com dm-raid: fix variable in journal device check
Frédéric Danis frederic.danis@collabora.com Bluetooth: L2CAP: Fix L2CAP MTU negotiation
Fabio Estevam festevam@gmail.com serial: imx: Restore original RXTL for console to fix data loss
Aidan Stewart astewart@tektelic.com serial: core: restore of_node information in sysfs
Yao Zi ziyao@disroot.org dt-bindings: serial: 8250: Make clocks and clock-frequency exclusive
Nathan Chancellor nathan@kernel.org staging: rtl8723bs: Avoid memset() in aes_cipher() and aes_decipher()
Xin Li (Intel) xin@zytor.com x86/traps: Initialize DR6 by writing its architectural reset value
Avadhut Naik avadhut.naik@amd.com EDAC/amd64: Fix size calculation for Non-Power-of-Two DIMMs
Paulo Alcantara pc@manguebit.org smb: client: fix potential deadlock when reconnecting channels
Michal Wajdeczko michal.wajdeczko@intel.com drm/xe: Process deferred GGTT node removals on device unwind
Michal Wajdeczko michal.wajdeczko@intel.com drm/xe/guc: Explicitly exit CT safe mode on unwind
Jayesh Choudhary j-choudhary@ti.com drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
Wolfram Sang wsa+renesas@sang-engineering.com drm/bridge: ti-sn65dsi86: make use of debugfs_init callback
Arnd Bergmann arnd@arndb.de drm/i915: fix build error some more
Mario Limonciello mario.limonciello@amd.com drm/amd: Adjust output for discovery error handling
Louis Chauvet louis.chauvet@bootlin.com drm: writeback: Fix drm_writeback_connector_cleanup signature
Charles Mirabile cmirabil@redhat.com riscv: fix runtime constant support for nommu kernels
Christoph Hellwig hch@lst.de nvme: fix atomic write size validation
Christoph Hellwig hch@lst.de nvme: refactor the atomic write unit detection
Jakub Kicinski kuba@kernel.org net: selftests: fix TCP packet checksum
Salvatore Bonaccorso carnil@debian.org ALSA: hda/realtek: Fix built-in mic on ASUS VivoBook X507UAR
Kuniyuki Iwashima kuniyu@google.com atm: Release atm_dev_mutex after removing procfs in atm_dev_deregister().
Jakub Kicinski kuba@kernel.org netlink: specs: tc: replace underscores with dashes in names
Simon Horman horms@kernel.org net: enetc: Correct endianness handling in _enetc_rd_reg64
Adin Scannell amscanne@meta.com libbpf: Fix possible use-after-free for externs
Jens Axboe axboe@kernel.dk io_uring/net: mark iov as dynamically allocated even for single segments
Tiwei Bie tiwei.btw@antgroup.com um: ubd: Add missing error check in start_io_thread()
Yan Zhai yan@cloudflare.com bnxt: properly flush XDP redirect lists
Stefano Garzarella sgarzare@redhat.com vsock/uapi: fix linux/vm_sockets.h userspace compilation errors
Al Viro viro@zeniv.linux.org.uk userns and mnt_idmap leak in open_tree_attr(2)
Johannes Berg johannes.berg@intel.com wifi: mac80211: finish link init before RCU publish
Muna Sinada muna.sinada@oss.qualcomm.com wifi: mac80211: Create separate links for VLAN interfaces
Muna Sinada muna.sinada@oss.qualcomm.com wifi: mac80211: Add link iteration macro for link data
Kuniyuki Iwashima kuniyu@google.com af_unix: Don't set -ECONNRESET for consumed OOB skb.
Lachlan Hodges lachlan.hodges@morsemicro.com wifi: mac80211: fix beacon interval calculation overflow
Ido Schimmel idosch@nvidia.com bridge: mcast: Fix use-after-free during router port configuration
Thomas Fourier fourier.thomas@gmail.com ethernet: ionic: Fix DMA mapping tests
Breno Leitao leitao@debian.org net: netpoll: Initialize UDP checksum field before checksumming
Yuan Chen chenyuan@kylinos.cn libbpf: Fix null pointer dereference in btf_dump__free on allocation failure
Al Viro viro@zeniv.linux.org.uk attach_recursive_mnt(): do not lock the covering tree when sliding something under it
Youngjun Lee yjjuny.lee@samsung.com ALSA: usb-audio: Fix out-of-bounds read in snd_usb_get_audioformat_uac3()
Kuniyuki Iwashima kuniyu@google.com Bluetooth: hci_core: Fix use-after-free in vhci_flush()
Vijendar Mukunda Vijendar.Mukunda@amd.com ASoC: amd: ps: fix for soundwire failures during hibernation exit sequence
Eric Dumazet edumazet@google.com atm: clip: prevent NULL deref in clip_push()
Thomas Fourier fourier.thomas@gmail.com scsi: fnic: Fix missing DMA mapping error in fnic_send_frame()
Dan Williams dan.j.williams@intel.com cxl/ras: Fix CPER handler device confusion
Thomas Zeitlhofer thomas.zeitlhofer+lkml@ze-it.at HID: wacom: fix crash in wacom_aes_battery_handler()
Even Xu even.xu@intel.com HID: Intel-thc-hid: Intel-quicki2c: Enhance QuickI2C reset flow
Matthew Auld matthew.auld@intel.com drm/xe: move DPT l2 flush to a more sensible place
Maarten Lankhorst maarten.lankhorst@linux.intel.com drm/xe: Move DSB l2 flush to a more sensible place
Ankit Nautiyal ankit.k.nautiyal@intel.com drm/i915/snps_hdmi_pll: Fix 64-bit divisor truncation by using div64_u64
Haoxiang Li haoxiang_li2024@163.com drm/xe/display: Add check for alloc_ordered_workqueue()
Alex Deucher alexander.deucher@amd.com drm/amdgpu/mes: add compatibility checks for set_hw_resource_1
Takashi Iwai tiwai@suse.de drm/amd/display: Add sanity checks for drm_edid_raw()
Imre Deak imre.deak@intel.com drm/dp: Change AUX DPCD probe address from DPCD_REV to LANE0_1_STATUS
Nam Cao namcao@linutronix.de Revert "riscv: misaligned: fix sleeping function called during misaligned access handling"
Nam Cao namcao@linutronix.de Revert "riscv: Define TASK_SIZE_MAX for __access_ok()"
Yu Kuai yukuai3@huawei.com lib/group_cpus: fix NULL pointer dereference from group_cpus_evenly()
David Hildenbrand david@redhat.com fs/proc/task_mmu: fix PAGE_IS_PFNZERO detection for the huge zero folio
Pavel Begunkov asml.silence@gmail.com io_uring: don't assume uaddr alignment in io_vec_fill_bvec
Pavel Begunkov asml.silence@gmail.com io_uring/rsrc: don't rely on user vaddr alignment
Pavel Begunkov asml.silence@gmail.com io_uring/rsrc: fix folio unpinning
Fedor Pchelkin pchelkin@ispras.ru s390/pkey: Prevent overflow in size calculation for memdup_user()
Klara Modin klarasmodin@gmail.com riscv: export boot_cpu_hartid
Oliver Schramm oliver.schramm97@gmail.com ASoC: amd: yc: Add DMI quirk for Lenovo IdeaPad Slim 5 15
Han Gao rabenda.cn@gmail.com riscv: vector: Fix context save/restore with xtheadvector
Paulo Alcantara pc@manguebit.org smb: client: fix regression with native SMB symlinks
SeongJae Park sj@kernel.org mm/damon/sysfs-schemes: free old damon_sysfs_scheme_filter->memcg_path on write
Stefan Metzmacher metze@samba.org smb: client: remove \t from TP_printk statements
Niklas Cassel cassel@kernel.org ata: ahci: Use correct DMI identifier for ASUSPRO-D840SA LPM quirk
Florian Fainelli florian.fainelli@broadcom.com scripts/gdb: fix dentry_name() lookup
Haiyue Wang haiyuewa@163.com fuse: fix runtime warning on truncate_folio_batch_exceptionals()
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Check interrupt route from physical CPU
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Fix interrupt route update with EIOINTC
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Add address alignment check for IOCSR emulation
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Disable updating of "num_cpu" and "feature"
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Check validity of "num_cpu" from user space
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Avoid overflow with array index
Wolfram Sang wsa+renesas@sang-engineering.com i2c: robotfuzz-osif: disable zero-length read messages
Wolfram Sang wsa+renesas@sang-engineering.com i2c: tiny-usb: disable zero-length read messages
Lukasz Kucharczyk lukasz.kucharczyk@leica-geosystems.com i2c: imx: fix emulated smbus block read
Christophe JAILLET christophe.jaillet@wanadoo.fr i2c: omap: Fix an error handling path in omap_i2c_probe()
Kuniyuki Iwashima kuniyu@google.com af_unix: Don't leave consecutive consumed OOB skbs.
Haoxiang Li haoxiang_li2024@163.com drm/i915/display: Add check for alloc_ordered_workqueue() and alloc_workqueue()
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: fix area release on registration failure
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: split out memory holders from area
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: improve area validation
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: move io_zcrx_iov_page
Chao Yu chao@kernel.org f2fs: don't over-report free space or inodes in statvfs
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ASoC: codecs: wcd9335: Fix missing free of regulator supplies
Peng Fan peng.fan@nxp.com ASoC: codec: wcd9335: Convert to GPIO descriptors
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Rollback non processed entities on error
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Increase/decrease the PM counter per IOCTL
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Create uvc_pm_(get|put) functions
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Keep streaming state in the file handle
Filipe Manana fdmanana@suse.com btrfs: fix qgroup reservation leak on failure to allocate ordered extent
David Sterba dsterba@suse.com btrfs: use unsigned types for constants defined as bit shifts
Joonas Lahtinen joonas.lahtinen@linux.intel.com Revert "drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1"
Ville Syrjälä ville.syrjala@linux.intel.com drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1
Qu Wenruo wqu@suse.com btrfs: handle csum tree error with rescue=ibadroots correctly
Filipe Manana fdmanana@suse.com btrfs: fix race between async reclaim worker and close_ctree()
Kees Cook kees@kernel.org ovl: Check for NULL d_inode() in ovl_dentry_upper()
Ben Dooks ben.dooks@codethink.co.uk riscv: save the SR_SUM status over switches
Ziqi Chen quic_ziqichen@quicinc.com scsi: ufs: core: Don't perform UFS clkscaling during host async scan
Dmitry Kandybka d.kandybka@gmail.com ceph: fix possible integer overflow in ceph_zero_objects()
Shuming Fan shumingf@realtek.com ASoC: rt1320: fix speaker noise when volume bar is 100%
Mario Limonciello mario.limonciello@amd.com ALSA: usb-audio: Add a quirk for Lenovo Thinkpad Thunderbolt 3 dock
Vijendar Mukunda Vijendar.Mukunda@amd.com ALSA: hda: Add new pci id for AMD GPU display HD audio controller
Cezary Rojewski cezary.rojewski@intel.com ALSA: hda: Ignore unsol events for cards being shut down
Clément Léger cleger@rivosinc.com riscv: misaligned: declare misaligned_access_speed under CONFIG_RISCV_MISALIGNED
Heiko Carstens hca@linux.ibm.com s390/mm: Fix in_atomic() handling in do_secure_storage_access()
Andy Chiu andybnac@gmail.com riscv: add a data fence for CMODX in the kernel mode
Michael Grzeschik m.grzeschik@pengutronix.de usb: typec: mux: do not return on EOPNOTSUPP in {mux, switch}_set
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org usb: typec: tipd: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org usb: typec: tcpci: Fix wakeup source leaks on device unbind
Jos Wang joswang@lenovo.com usb: typec: displayport: Receive DP Status Update NAK request exit dp altmode
Peter Korsgaard peter@korsgaard.com usb: gadget: f_hid: wake up readers on disable/unbind
Robert Hodaszi robert.hodaszi@digi.com usb: cdc-wdm: avoid setting WDM_READ for ZLP-s
Andy Shevchenko andriy.shevchenko@linux.intel.com usb: Add checks for snprintf() calls in usb_alloc_dev()
Chance Yang chance.yang@kneron.us usb: common: usb-conn-gpio: use a unique name for usb connector device
Jakub Lewalski jakub.lewalski@nokia.com tty: serial: uartlite: register uart driver in init
Chen Yufeng chenyufeng@iie.ac.cn usb: potential integer overflow in usbg_make_tpg()
Chenyuan Yang chenyuan0y@gmail.com misc: tps6594-pfsm: Add NULL pointer check in tps6594_pfsm_probe()
Zhang Lixu lixu.zhang@intel.com iio: hid-sensor-prox: Add support for 16-bit report size
David Lechner dlechner@baylibre.com iio: adc: ad7606_spi: check error in ad7606B_sw_mode_config()
David Heidelberg david@ixit.cz iio: light: al3000a: Fix an error handling path in al3000a_probe()
Angelo Dureghello adureghello@baylibre.com iio: dac: adi-axi-dac: add cntrl chan check
Purva Yeshi purvayeshi550@gmail.com iio: adc: ad_sigma_delta: Fix use of uninitialized status_pos
Michael Grzeschik m.grzeschik@pengutronix.de usb: dwc2: also exit clock_gating when stopping udc while suspended
James Clark james.clark@linaro.org coresight: Only check bottom two claim bits
Rengarajan S rengarajan.s@microchip.com 8250: microchip: pci1xxxx: Add PCIe Hot reset disable support for Rev C0 and later devices
Benjamin Berg benjamin.berg@intel.com um: use proper care when taking mmap lock during segfault
Sami Tolvanen samitolvanen@google.com um: Add cmpxchg8b_emu and checksum functions to asm-prototypes.h
Daniele Palmas dnlplm@gmail.com bus: mhi: host: pci_generic: Add Telit FN920C04 modem support
Jonathan Cameron Jonathan.Cameron@huawei.com iio: pressure: zpa2326: Use aligned_s64 for the timestamp
Lin.Cao lincao12@amd.com drm/scheduler: signal scheduled fence when kill job
Philip Yang Philip.Yang@amd.com drm/amdgpu: seq64 memory unmap uses uninterruptible lock
Linggang Zeng linggang.zeng@easystack.cn bcache: fix NULL pointer in cache_set_flush()
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn2.5: read back register after written
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn3: read back register after written
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn4: read back register after written
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn5.0.1: read back register after written
Yifan Zhang yifan1.zhang@amd.com amd/amdkfd: fix a kfd_process ref leak
Yu Kuai yukuai3@huawei.com md/md-bitmap: fix dm-raid max_write_behind setting
Hannes Reinecke hare@kernel.org nvme-tcp: sanitize request list handling
Hannes Reinecke hare@kernel.org nvme-tcp: fix I/O stalls on congested sockets
Ilan Peer ilan.peer@intel.com wifi: iwlwifi: mld: Move regulatory domain initialization
Richard Zhu hongxing.zhu@nxp.com PCI: imx6: Add workaround for errata ERR051624
Hector Martin marcan@marcan.st PCI: apple: Fix missing OF node reference in apple_pcie_setup_port
Wenbin Yao quic_wenbyao@quicinc.com PCI: dwc: Make link training more robust by setting PORT_LOGIC_LINK_WIDTH to one lane
Thomas Gessler thomas.gessler@brueckmann-gmbh.de dmaengine: xilinx_dma: Set dma_device directions
Yi Sun yi.sun@intel.com dmaengine: idxd: Check availability of workqueue allocated by idxd wq driver before using
Lukas Wunner lukas@wunner.de Revert "iommu/amd: Prevent binding other PCI drivers to IOMMU PCI devices"
Rudraksha Gupta guptarud@gmail.com rust: arm: fix unknown (to Clang) argument '-mno-fdpic'
FUJITA Tomonori fujita.tomonori@gmail.com rust: module: place cleanup_module() in .exit.text section
Namjae Jeon linkinjeon@kernel.org ksmbd: provide zero as a unique ID to the Mac client
Namjae Jeon linkinjeon@kernel.org ksmbd: allow a filename to contain special characters on SMB3.1.1 posix extension
Alexis Czezar Torreno alexisczezar.torreno@analog.com hwmon: (pmbus/max34440) Fix support for max34451
Scott Mayhew smayhew@redhat.com NFSv4: xattr handlers should check for absent nfs filehandles
Gregory Price gourry@gourry.net cxl: core/region - ignore interleave granularity when ways=1
Robert Richter rrichter@amd.com cxl/region: Add a dev_err() on missing target list entries
Guang Yuan Wu gwu@ddn.com fuse: fix race between concurrent setattrs from multiple nodes
Sven Schwermer sven.schwermer@disruptive-technologies.com leds: multicolor: Fix intensity setting while SW blinking
Matthew Sakai msakai@redhat.com dm vdo indexer: don't read request structure after enqueuing
Yikai Tsai yikai.tsai.wiwynn@gmail.com hwmon: (isl28022) Fix current reading calculation
Nikhil Jha njha@janestreet.com sunrpc: don't immediately retransmit on seqno miss
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: sprd-sc27xx: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: 88pm886: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: max77705: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: max14577: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: max77541: Fix wakeup source leaks on device unbind
Peng Fan peng.fan@nxp.com mailbox: Not protect module_put with spin_lock_irqsave
Sagi Grimberg sagi@grimberg.me NFSv4.2: fix setattr caching of TIME_[MODIFY|ACCESS]_SET when timestamps are delegated
Olga Kornievskaia okorniev@redhat.com NFSv4.2: fix listxattr to return selinux security label
Han Young hanyang.tony@bytedance.com NFSv4: Always set NLINK even if the server doesn't support it
Pali Rohár pali@kernel.org cifs: Fix encoding of SMB1 Session Setup NTLMSSP Request in non-UNICODE mode
Pali Rohár pali@kernel.org cifs: Fix cifs_query_path_info() for Windows NT servers
Pali Rohár pali@kernel.org cifs: Correctly set SMB1 SessionKey field in Session Setup Request
-------------
Diffstat:
Documentation/devicetree/bindings/serial/8250.yaml | 2 +- Documentation/netlink/specs/tc.yaml | 4 +- Makefile | 4 +- arch/arm64/boot/dts/qcom/x1-crd.dtsi | 1277 ++++++++++++++++++++ .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 45 + arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 1270 +------------------ arch/arm64/boot/dts/qcom/x1e80100.dtsi | 2 +- arch/loongarch/kvm/intc/eiointc.c | 89 +- arch/powerpc/crypto/Kconfig | 1 + arch/riscv/include/asm/cpufeature.h | 5 +- arch/riscv/include/asm/pgtable.h | 1 - arch/riscv/include/asm/processor.h | 1 + arch/riscv/include/asm/runtime-const.h | 2 +- arch/riscv/include/asm/vector.h | 12 +- arch/riscv/kernel/asm-offsets.c | 5 + arch/riscv/kernel/entry.S | 9 + arch/riscv/kernel/setup.c | 1 + arch/riscv/kernel/traps_misaligned.c | 6 +- arch/riscv/mm/cacheflush.c | 15 +- arch/s390/kernel/ptrace.c | 2 +- arch/s390/mm/fault.c | 2 + arch/um/drivers/ubd_user.c | 2 +- arch/um/include/asm/asm-prototypes.h | 5 + arch/um/kernel/trap.c | 129 +- arch/x86/include/uapi/asm/debugreg.h | 21 +- arch/x86/kernel/cpu/common.c | 24 +- arch/x86/kernel/fpu/signal.c | 11 +- arch/x86/kernel/fpu/xstate.h | 22 +- arch/x86/kernel/traps.c | 34 +- arch/x86/um/asm/checksum.h | 3 + drivers/ata/ahci.c | 2 +- drivers/bus/mhi/host/pci_generic.c | 39 + drivers/cxl/core/ras.c | 47 +- drivers/cxl/core/region.c | 9 +- drivers/dma/idxd/cdev.c | 4 +- drivers/dma/xilinx/xilinx_dma.c | 2 + drivers/edac/amd64_edac.c | 57 +- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 28 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 30 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 8 + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 16 + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 16 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 16 + drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 17 + drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 6 + drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 2 +- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 5 + drivers/gpu/drm/amd/amdgpu/imu_v11_0.c | 9 +- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 10 +- drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 2 + drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 6 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 19 + drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 20 + drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 20 + drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 21 +- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 1 + drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 97 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 4 + drivers/gpu/drm/amd/display/dc/core/dc.c | 33 + drivers/gpu/drm/amd/display/dc/dc.h | 8 +- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 4 +- .../dc/dml2/dml21/dml21_translation_helper.c | 1 + .../dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 5 +- .../amd/display/dc/dml2/dml2_translation_helper.c | 1 + .../drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 9 +- .../drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 28 + .../display/dc/link/protocols/link_dp_capability.c | 46 +- .../display/dc/link/protocols/link_dp_capability.h | 3 + .../display/dc/link/protocols/link_dp_training.c | 1 - .../dc/link/protocols/link_dp_training_8b_10b.c | 52 +- .../amd/display/dc/resource/dcn31/dcn31_resource.c | 3 + .../display/dc/resource/dcn314/dcn314_resource.c | 3 + .../amd/display/dc/resource/dcn35/dcn35_resource.c | 3 + .../display/dc/resource/dcn351/dcn351_resource.c | 3 + .../amd/display/dc/resource/dcn36/dcn36_resource.c | 3 + .../drm/amd/display/include/link_service_types.h | 2 + .../gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 + drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 22 + drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 12 +- drivers/gpu/drm/ast/ast_mode.c | 6 +- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 32 +- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 109 +- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- drivers/gpu/drm/drm_writeback.c | 7 +- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 5 +- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 27 +- drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h | 15 +- .../gpu/drm/i915/display/intel_display_driver.c | 30 +- drivers/gpu/drm/i915/display/intel_dp.c | 17 + drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c | 4 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 4 +- drivers/gpu/drm/i915/i915_pmu.c | 2 +- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 1 + drivers/gpu/drm/panel/panel-simple.c | 6 + drivers/gpu/drm/scheduler/sched_entity.c | 1 + drivers/gpu/drm/tegra/dc.c | 17 +- drivers/gpu/drm/tegra/hub.c | 4 +- drivers/gpu/drm/tegra/hub.h | 3 +- drivers/gpu/drm/tiny/cirrus-qemu.c | 1 - drivers/gpu/drm/tiny/simpledrm.c | 4 +- drivers/gpu/drm/udl/udl_drv.c | 2 +- drivers/gpu/drm/xe/display/xe_display.c | 2 + drivers/gpu/drm/xe/display/xe_dsb_buffer.c | 11 +- drivers/gpu/drm/xe/display/xe_fb_pin.c | 5 +- drivers/gpu/drm/xe/xe_ggtt.c | 11 + drivers/gpu/drm/xe/xe_gpu_scheduler.h | 10 +- drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 8 + drivers/gpu/drm/xe/xe_guc_ct.c | 17 +- drivers/gpu/drm/xe/xe_guc_ct.h | 5 + drivers/gpu/drm/xe/xe_guc_pc.c | 2 +- drivers/gpu/drm/xe/xe_guc_submit.c | 23 + drivers/gpu/drm/xe/xe_guc_types.h | 5 + drivers/gpu/drm/xe/xe_vm.c | 8 +- drivers/hid/hid-appletb-kbd.c | 5 + drivers/hid/hid-lenovo.c | 11 +- .../intel-quicki2c/quicki2c-protocol.c | 26 +- drivers/hid/wacom_sys.c | 7 +- drivers/hwmon/isl28022.c | 6 +- drivers/hwmon/pmbus/max34440.c | 48 +- drivers/hwtracing/coresight/coresight-core.c | 3 +- drivers/hwtracing/coresight/coresight-priv.h | 1 + drivers/i2c/busses/i2c-imx.c | 3 +- drivers/i2c/busses/i2c-omap.c | 7 +- drivers/i2c/busses/i2c-robotfuzz-osif.c | 6 + drivers/i2c/busses/i2c-tiny-usb.c | 6 + drivers/iio/adc/ad7606_spi.c | 8 +- drivers/iio/adc/ad_sigma_delta.c | 4 + drivers/iio/dac/adi-axi-dac.c | 24 + drivers/iio/light/al3000a.c | 9 +- drivers/iio/light/hid-sensor-prox.c | 3 + drivers/iio/pressure/zpa2326.c | 2 +- drivers/iommu/amd/init.c | 3 - drivers/leds/led-class-multicolor.c | 3 +- drivers/mailbox/mailbox.c | 2 +- drivers/md/bcache/Kconfig | 1 - drivers/md/bcache/alloc.c | 57 +- drivers/md/bcache/bcache.h | 2 +- drivers/md/bcache/bset.c | 116 +- drivers/md/bcache/bset.h | 40 +- drivers/md/bcache/btree.c | 69 +- drivers/md/bcache/extents.c | 43 +- drivers/md/bcache/movinggc.c | 33 +- drivers/md/bcache/super.c | 10 +- drivers/md/bcache/sysfs.c | 4 +- drivers/md/bcache/util.h | 67 +- drivers/md/bcache/writeback.c | 13 +- drivers/md/dm-raid.c | 2 +- drivers/md/dm-vdo/indexer/volume.c | 24 +- drivers/md/md-bitmap.c | 2 +- drivers/media/usb/uvc/uvc_ctrl.c | 70 +- drivers/media/usb/uvc/uvc_v4l2.c | 93 +- drivers/media/usb/uvc/uvcvideo.h | 5 + drivers/mfd/88pm886.c | 6 +- drivers/mfd/max14577.c | 1 + drivers/mfd/max77541.c | 2 +- drivers/mfd/max77705.c | 4 +- drivers/mfd/sprd-sc27xx-spi.c | 5 +- drivers/misc/tps6594-pfsm.c | 3 + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 +- drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 +- drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 12 +- drivers/net/ethernet/wangxun/libwx/wx_lib.c | 2 +- drivers/net/wireless/intel/iwlwifi/mld/fw.c | 8 +- drivers/nvme/host/core.c | 83 +- drivers/nvme/host/nvme.h | 3 +- drivers/nvme/host/tcp.c | 22 +- drivers/pci/controller/dwc/pci-imx6.c | 15 + drivers/pci/controller/dwc/pcie-designware.c | 5 +- drivers/pci/controller/pcie-apple.c | 3 + drivers/s390/crypto/pkey_api.c | 2 +- drivers/scsi/fnic/fdls_disc.c | 122 +- drivers/scsi/fnic/fnic.h | 2 +- drivers/scsi/fnic/fnic_fcs.c | 2 + drivers/scsi/fnic/fnic_fdls.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 6 +- drivers/spi/spi-cadence-quadspi.c | 12 +- drivers/staging/rtl8723bs/core/rtw_security.c | 44 +- drivers/tty/serial/8250/8250_pci1xxxx.c | 10 + drivers/tty/serial/imx.c | 17 +- drivers/tty/serial/serial_base_bus.c | 1 + drivers/tty/serial/uartlite.c | 25 +- drivers/ufs/core/ufshcd.c | 6 +- drivers/usb/class/cdc-wdm.c | 23 +- drivers/usb/common/usb-conn-gpio.c | 25 +- drivers/usb/core/usb.c | 14 +- drivers/usb/dwc2/gadget.c | 6 + drivers/usb/gadget/function/f_hid.c | 19 +- drivers/usb/gadget/function/f_tcm.c | 4 +- drivers/usb/typec/altmodes/displayport.c | 4 + drivers/usb/typec/mux.c | 4 +- drivers/usb/typec/tcpm/tcpci_maxim_core.c | 5 +- drivers/usb/typec/tipd/core.c | 2 +- fs/btrfs/backref.h | 4 +- fs/btrfs/direct-io.c | 4 +- fs/btrfs/disk-io.c | 25 +- fs/btrfs/extent_io.h | 2 +- fs/btrfs/inode.c | 95 +- fs/btrfs/ordered-data.c | 14 +- fs/btrfs/raid56.c | 5 +- fs/btrfs/tests/extent-io-tests.c | 6 +- fs/btrfs/tree-log.c | 14 +- fs/btrfs/volumes.c | 6 + fs/btrfs/zstd.c | 2 +- fs/ceph/file.c | 2 +- fs/f2fs/file.c | 38 + fs/f2fs/super.c | 30 +- fs/fuse/dir.c | 11 + fs/fuse/inode.c | 4 + fs/namespace.c | 18 +- fs/nfs/inode.c | 51 +- fs/nfs/nfs4proc.c | 25 +- fs/overlayfs/util.c | 4 +- fs/proc/task_mmu.c | 2 +- fs/smb/client/cifsglob.h | 2 + fs/smb/client/cifspdu.h | 6 +- fs/smb/client/cifssmb.c | 1 + fs/smb/client/connect.c | 58 +- fs/smb/client/misc.c | 8 + fs/smb/client/reparse.c | 20 +- fs/smb/client/sess.c | 21 +- fs/smb/client/trace.h | 24 +- fs/smb/server/connection.h | 1 + fs/smb/server/smb2pdu.c | 72 +- fs/smb/server/smb2pdu.h | 3 + include/net/bluetooth/hci_core.h | 2 + include/uapi/linux/vm_sockets.h | 4 + io_uring/io_uring.c | 3 +- io_uring/kbuf.c | 1 + io_uring/kbuf.h | 1 + io_uring/net.c | 34 +- io_uring/rsrc.c | 57 +- io_uring/rsrc.h | 3 +- io_uring/zcrx.c | 101 +- io_uring/zcrx.h | 11 +- kernel/sched/ext.c | 12 +- lib/group_cpus.c | 9 +- lib/maple_tree.c | 4 +- mm/damon/sysfs-schemes.c | 1 + mm/gup.c | 14 +- mm/memory.c | 20 - mm/shmem.c | 6 +- mm/swap.h | 23 + mm/userfaultfd.c | 33 +- net/atm/clip.c | 11 +- net/atm/resources.c | 3 +- net/bluetooth/hci_core.c | 34 +- net/bluetooth/l2cap_core.c | 9 +- net/bridge/br_multicast.c | 9 + net/core/netpoll.c | 2 +- net/core/selftests.c | 5 +- net/mac80211/chan.c | 3 + net/mac80211/ieee80211_i.h | 12 + net/mac80211/iface.c | 12 +- net/mac80211/link.c | 94 +- net/mac80211/util.c | 2 +- net/sunrpc/clnt.c | 9 +- net/unix/af_unix.c | 31 +- rust/Makefile | 2 +- rust/bindings/bindings_helper.h | 1 + rust/helpers/completion.c | 8 + rust/helpers/helpers.c | 1 + rust/kernel/devres.rs | 53 +- rust/kernel/revocable.rs | 18 +- rust/kernel/sync.rs | 2 + rust/kernel/sync/completion.rs | 112 ++ rust/macros/module.rs | 1 + scripts/gdb/linux/vfs.py | 2 +- security/selinux/ss/services.c | 16 +- sound/pci/hda/hda_bind.c | 2 +- sound/pci/hda/hda_intel.c | 3 + sound/pci/hda/patch_realtek.c | 1 + sound/soc/amd/ps/acp63.h | 4 + sound/soc/amd/ps/ps-common.c | 18 + sound/soc/amd/yc/acp6x-mach.c | 7 + sound/soc/codecs/rt1320-sdw.c | 17 +- sound/soc/codecs/wcd9335.c | 40 +- sound/usb/quirks.c | 2 + sound/usb/stream.c | 2 + tools/lib/bpf/btf_dump.c | 3 + tools/lib/bpf/libbpf.c | 10 +- .../selftests/bpf/progs/test_global_map_resize.c | 16 + 289 files changed, 4527 insertions(+), 2538 deletions(-)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár pali@kernel.org
[ Upstream commit 89381c72d52094988e11d23ef24a00066a0fa458 ]
[MS-CIFS] specification in section 2.2.4.53.1 where is described SMB_COM_SESSION_SETUP_ANDX Request, for SessionKey field says:
The client MUST set this field to be equal to the SessionKey field in the SMB_COM_NEGOTIATE Response for this SMB connection.
Linux SMB client currently set this field to zero. This is working fine against Windows NT SMB servers thanks to [MS-CIFS] product behavior <94>:
Windows NT Server ignores the client's SessionKey.
For compatibility with [MS-CIFS], set this SessionKey field in Session Setup Request to value retrieved from Negotiate response.
Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/client/cifsglob.h | 1 + fs/smb/client/cifspdu.h | 6 +++--- fs/smb/client/cifssmb.c | 1 + fs/smb/client/sess.c | 1 + 4 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 0c80ca352f3fa..214e53acf72a8 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -773,6 +773,7 @@ struct TCP_Server_Info { char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; __u32 sequence_number; /* for signing, protected by srv_mutex */ __u32 reconnect_instance; /* incremented on each reconnect */ + __le32 session_key_id; /* retrieved from negotiate response and send in session setup request */ struct session_key session_key; unsigned long lstrp; /* when we got last response from this server */ struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ diff --git a/fs/smb/client/cifspdu.h b/fs/smb/client/cifspdu.h index 1b79fe07476f6..d9cf7db0ac35e 100644 --- a/fs/smb/client/cifspdu.h +++ b/fs/smb/client/cifspdu.h @@ -597,7 +597,7 @@ typedef union smb_com_session_setup_andx { __le16 MaxBufferSize; __le16 MaxMpxCount; __le16 VcNumber; - __u32 SessionKey; + __le32 SessionKey; __le16 SecurityBlobLength; __u32 Reserved; __le32 Capabilities; /* see below */ @@ -616,7 +616,7 @@ typedef union smb_com_session_setup_andx { __le16 MaxBufferSize; __le16 MaxMpxCount; __le16 VcNumber; - __u32 SessionKey; + __le32 SessionKey; __le16 CaseInsensitivePasswordLength; /* ASCII password len */ __le16 CaseSensitivePasswordLength; /* Unicode password length*/ __u32 Reserved; /* see below */ @@ -654,7 +654,7 @@ typedef union smb_com_session_setup_andx { __le16 MaxBufferSize; __le16 MaxMpxCount; __le16 VcNumber; - __u32 SessionKey; + __le32 SessionKey; __le16 PasswordLength; __u32 Reserved; /* encrypt key len and offset */ __le16 ByteCount; diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c index a3ba3346ed313..7216fcec79e8b 100644 --- a/fs/smb/client/cifssmb.c +++ b/fs/smb/client/cifssmb.c @@ -498,6 +498,7 @@ CIFSSMBNegotiate(const unsigned int xid, server->max_rw = le32_to_cpu(pSMBr->MaxRawSize); cifs_dbg(NOISY, "Max buf = %d\n", ses->server->maxBuf); server->capabilities = le32_to_cpu(pSMBr->Capabilities); + server->session_key_id = pSMBr->SessionKey; server->timeAdj = (int)(__s16)le16_to_cpu(pSMBr->ServerTimeZone); server->timeAdj *= 60;
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index 12c99fb4023dc..5a24b80dc146a 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -631,6 +631,7 @@ static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, USHRT_MAX)); pSMB->req.MaxMpxCount = cpu_to_le16(server->maxReq); pSMB->req.VcNumber = cpu_to_le16(1); + pSMB->req.SessionKey = server->session_key_id;
/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár pali@kernel.org
[ Upstream commit a3e771afbb3bce91c8296828304903e7348003fe ]
For TRANS2 QUERY_PATH_INFO request when the path does not exist, the Windows NT SMB server returns error response STATUS_OBJECT_NAME_NOT_FOUND or ERRDOS/ERRbadfile without the SMBFLG_RESPONSE flag set. Similarly it returns STATUS_DELETE_PENDING when the file is being deleted. And looks like that any error response from TRANS2 QUERY_PATH_INFO does not have SMBFLG_RESPONSE flag set.
So relax check in check_smb_hdr() for detecting if the packet is response for this special case.
This change fixes stat() operation against Windows NT SMB servers and also all operations which depends on -ENOENT result from stat like creat() or mkdir().
Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/client/misc.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index 7b6ed9b23e713..e77017f470845 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -326,6 +326,14 @@ check_smb_hdr(struct smb_hdr *smb) if (smb->Command == SMB_COM_LOCKING_ANDX) return 0;
+ /* + * Windows NT server returns error resposne (e.g. STATUS_DELETE_PENDING + * or STATUS_OBJECT_NAME_NOT_FOUND or ERRDOS/ERRbadfile or any other) + * for some TRANS2 requests without the RESPONSE flag set in header. + */ + if (smb->Command == SMB_COM_TRANSACTION2 && smb->Status.CifsError != 0) + return 0; + cifs_dbg(VFS, "Server sent request, not response. mid=%u\n", get_mid(smb)); return 1;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár pali@kernel.org
[ Upstream commit 6510ef4230b68c960309e0c1d6eb3e32eb785142 ]
SMB1 Session Setup NTLMSSP Request in non-UNICODE mode is similar to UNICODE mode, just strings are encoded in ASCII and not in UTF-16.
With this change it is possible to setup SMB1 session with NTLM authentication in non-UNICODE mode with Windows SMB server.
This change fixes mounting SMB1 servers with -o nounicode mount option together with -o sec=ntlmssp mount option (which is the default sec=).
Signed-off-by: Pali Rohár pali@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/client/sess.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index 5a24b80dc146a..330bc3d25badd 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -1688,22 +1688,22 @@ _sess_auth_rawntlmssp_assemble_req(struct sess_data *sess_data) pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
capabilities = cifs_ssetup_hdr(ses, server, pSMB); - if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) { - cifs_dbg(VFS, "NTLMSSP requires Unicode support\n"); - return -ENOSYS; - } - pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; capabilities |= CAP_EXTENDED_SECURITY; pSMB->req.Capabilities |= cpu_to_le32(capabilities);
bcc_ptr = sess_data->iov[2].iov_base; - /* unicode strings must be word aligned */ - if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) { - *bcc_ptr = 0; - bcc_ptr++; + + if (pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) { + /* unicode strings must be word aligned */ + if (!IS_ALIGNED(sess_data->iov[0].iov_len + sess_data->iov[1].iov_len, 2)) { + *bcc_ptr = 0; + bcc_ptr++; + } + unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp); + } else { + ascii_oslm_strings(&bcc_ptr, sess_data->nls_cp); } - unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp);
sess_data->iov[2].iov_len = (long) bcc_ptr - (long) sess_data->iov[2].iov_base;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Han Young hanyang.tony@bytedance.com
[ Upstream commit 3a3065352f73381d3a1aa0ccab44aec3a5a9b365 ]
fattr4_numlinks is a recommended attribute, so the client should emulate it even if the server doesn't support it. In decode_attr_nlink function in nfs4xdr.c, nlink is initialized to 1. However, this default value isn't set to the inode due to the check in nfs_fhget.
So if the server doesn't support numlinks, inode's nlink will be zero, the mount will fail with error "Stale file handle". Set the nlink to 1 if the server doesn't support it.
Signed-off-by: Han Young hanyang.tony@bytedance.com Signed-off-by: Anna Schumaker anna.schumaker@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/inode.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 119e447758b99..4695292378bbe 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -557,6 +557,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) set_nlink(inode, fattr->nlink); else if (fattr_supported & NFS_ATTR_FATTR_NLINK) nfs_set_cache_invalid(inode, NFS_INO_INVALID_NLINK); + else + set_nlink(inode, 1); if (fattr->valid & NFS_ATTR_FATTR_OWNER) inode->i_uid = fattr->uid; else if (fattr_supported & NFS_ATTR_FATTR_OWNER)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olga Kornievskaia okorniev@redhat.com
[ Upstream commit 243fea134633ba3d64aceb4c16129c59541ea2c6 ]
Currently, when NFS is queried for all the labels present on the file via a command example "getfattr -d -m . /mnt/testfile", it does not return the security label. Yet when asked specifically for the label (getfattr -n security.selinux) it will be returned. Include the security label when all attributes are queried.
Signed-off-by: Olga Kornievskaia okorniev@redhat.com Signed-off-by: Anna Schumaker anna.schumaker@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 9db317e7dea17..56f41ec327397 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -10861,7 +10861,7 @@ const struct nfs4_minor_version_ops *nfs_v4_minor_ops[] = {
static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size) { - ssize_t error, error2, error3; + ssize_t error, error2, error3, error4; size_t left = size;
error = generic_listxattr(dentry, list, left); @@ -10884,8 +10884,16 @@ static ssize_t nfs4_listxattr(struct dentry *dentry, char *list, size_t size) error3 = nfs4_listxattr_nfs4_user(d_inode(dentry), list, left); if (error3 < 0) return error3; + if (list) { + list += error3; + left -= error3; + } + + error4 = security_inode_listsecurity(d_inode(dentry), list, left); + if (error4 < 0) + return error4;
- error += error2 + error3; + error += error2 + error3 + error4; if (size && error > size) return -ERANGE; return error;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sagi Grimberg sagi@grimberg.me
[ Upstream commit aba41e90aadeca8d4656f90639aa5f91ce564f1c ]
nfs_setattr will flush all pending writes before updating a file time attributes. However when the client holds delegated timestamps, it can update its timestamps locally as it is the authority for the file times attributes. The client will later set the file attributes by adding a setattr to the delegreturn compound updating the server time attributes.
Fix nfs_setattr to avoid flushing pending writes when the file time attributes are delegated and the mtime/atime are set to a fixed timestamp (ATTR_[MODIFY|ACCESS]_SET. Also, when sending the setattr procedure over the wire, we need to clear the correct attribute bits from the bitmask.
I was able to measure a noticable speedup when measuring untar performance. Test: $ time tar xzf ~/dir.tgz Baseline: 1m13.072s Patched: 0m49.038s
Which is more than 30% latency improvement.
Signed-off-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Anna Schumaker anna.schumaker@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/inode.c | 49 +++++++++++++++++++++++++++++++++++++++++++---- fs/nfs/nfs4proc.c | 8 ++++---- 2 files changed, 49 insertions(+), 8 deletions(-)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 4695292378bbe..8ab7868807a7d 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c @@ -635,6 +635,34 @@ nfs_fattr_fixup_delegated(struct inode *inode, struct nfs_fattr *fattr) } }
+static void nfs_set_timestamps_to_ts(struct inode *inode, struct iattr *attr) +{ + unsigned int cache_flags = 0; + + if (attr->ia_valid & ATTR_MTIME_SET) { + struct timespec64 ctime = inode_get_ctime(inode); + struct timespec64 mtime = inode_get_mtime(inode); + struct timespec64 now; + int updated = 0; + + now = inode_set_ctime_current(inode); + if (!timespec64_equal(&now, &ctime)) + updated |= S_CTIME; + + inode_set_mtime_to_ts(inode, attr->ia_mtime); + if (!timespec64_equal(&now, &mtime)) + updated |= S_MTIME; + + inode_maybe_inc_iversion(inode, updated); + cache_flags |= NFS_INO_INVALID_CTIME | NFS_INO_INVALID_MTIME; + } + if (attr->ia_valid & ATTR_ATIME_SET) { + inode_set_atime_to_ts(inode, attr->ia_atime); + cache_flags |= NFS_INO_INVALID_ATIME; + } + NFS_I(inode)->cache_validity &= ~cache_flags; +} + static void nfs_update_timestamps(struct inode *inode, unsigned int ia_valid) { enum file_time_flags time_flags = 0; @@ -703,14 +731,27 @@ nfs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
if (nfs_have_delegated_mtime(inode) && attr->ia_valid & ATTR_MTIME) { spin_lock(&inode->i_lock); - nfs_update_timestamps(inode, attr->ia_valid); + if (attr->ia_valid & ATTR_MTIME_SET) { + nfs_set_timestamps_to_ts(inode, attr); + attr->ia_valid &= ~(ATTR_MTIME|ATTR_MTIME_SET| + ATTR_ATIME|ATTR_ATIME_SET); + } else { + nfs_update_timestamps(inode, attr->ia_valid); + attr->ia_valid &= ~(ATTR_MTIME|ATTR_ATIME); + } spin_unlock(&inode->i_lock); - attr->ia_valid &= ~(ATTR_MTIME | ATTR_ATIME); } else if (nfs_have_delegated_atime(inode) && attr->ia_valid & ATTR_ATIME && !(attr->ia_valid & ATTR_MTIME)) { - nfs_update_delegated_atime(inode); - attr->ia_valid &= ~ATTR_ATIME; + if (attr->ia_valid & ATTR_ATIME_SET) { + spin_lock(&inode->i_lock); + nfs_set_timestamps_to_ts(inode, attr); + spin_unlock(&inode->i_lock); + attr->ia_valid &= ~(ATTR_ATIME|ATTR_ATIME_SET); + } else { + nfs_update_delegated_atime(inode); + attr->ia_valid &= ~ATTR_ATIME; + } }
/* Optimization: if the end result is no change, don't RPC */ diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 56f41ec327397..6c3896a9b9d0f 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -325,14 +325,14 @@ static void nfs4_bitmap_copy_adjust(__u32 *dst, const __u32 *src,
if (nfs_have_delegated_mtime(inode)) { if (!(cache_validity & NFS_INO_INVALID_ATIME)) - dst[1] &= ~FATTR4_WORD1_TIME_ACCESS; + dst[1] &= ~(FATTR4_WORD1_TIME_ACCESS|FATTR4_WORD1_TIME_ACCESS_SET); if (!(cache_validity & NFS_INO_INVALID_MTIME)) - dst[1] &= ~FATTR4_WORD1_TIME_MODIFY; + dst[1] &= ~(FATTR4_WORD1_TIME_MODIFY|FATTR4_WORD1_TIME_MODIFY_SET); if (!(cache_validity & NFS_INO_INVALID_CTIME)) - dst[1] &= ~FATTR4_WORD1_TIME_METADATA; + dst[1] &= ~(FATTR4_WORD1_TIME_METADATA|FATTR4_WORD1_TIME_MODIFY_SET); } else if (nfs_have_delegated_atime(inode)) { if (!(cache_validity & NFS_INO_INVALID_ATIME)) - dst[1] &= ~FATTR4_WORD1_TIME_ACCESS; + dst[1] &= ~(FATTR4_WORD1_TIME_ACCESS|FATTR4_WORD1_TIME_ACCESS_SET); } }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan peng.fan@nxp.com
[ Upstream commit dddbd233e67e792bb0a3f9694a4707e6be29b2c6 ]
&chan->lock is not supposed to protect 'chan->mbox'. And in __mbox_bind_client, try_module_get is also not protected by &chan->lock. So move module_put out of the lock protected region.
Signed-off-by: Peng Fan peng.fan@nxp.com Signed-off-by: Jassi Brar jassisinghbrar@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/mailbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c index 0593b4d036859..aea0e690b63ee 100644 --- a/drivers/mailbox/mailbox.c +++ b/drivers/mailbox/mailbox.c @@ -486,8 +486,8 @@ void mbox_free_channel(struct mbox_chan *chan) if (chan->txdone_method == TXDONE_BY_ACK) chan->txdone_method = TXDONE_BY_POLL;
- module_put(chan->mbox->dev->driver->owner); spin_unlock_irqrestore(&chan->lock, flags); + module_put(chan->mbox->dev->driver->owner); } EXPORT_SYMBOL_GPL(mbox_free_channel);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 6c7115cdf6440e1e2f15e21efe92e2b757940627 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-4-318e14bdba0a... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/max77541.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mfd/max77541.c b/drivers/mfd/max77541.c index d77c31c86e435..f91b4f5373ce9 100644 --- a/drivers/mfd/max77541.c +++ b/drivers/mfd/max77541.c @@ -152,7 +152,7 @@ static int max77541_pmic_setup(struct device *dev) if (ret) return dev_err_probe(dev, ret, "Failed to initialize IRQ\n");
- ret = device_init_wakeup(dev, true); + ret = devm_device_init_wakeup(dev); if (ret) return dev_err_probe(dev, ret, "Unable to init wakeup\n");
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit d905d06e64b0eb3da43af6186c132f5282197998 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-3-318e14bdba0a... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/max14577.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/mfd/max14577.c b/drivers/mfd/max14577.c index 6fce79ec2dc64..7e7e8af9af224 100644 --- a/drivers/mfd/max14577.c +++ b/drivers/mfd/max14577.c @@ -456,6 +456,7 @@ static void max14577_i2c_remove(struct i2c_client *i2c) { struct max14577 *max14577 = i2c_get_clientdata(i2c);
+ device_init_wakeup(max14577->dev, false); mfd_remove_devices(max14577->dev); regmap_del_irq_chip(max14577->irq, max14577->irq_data); if (max14577->dev_type == MAXIM_DEVICE_TYPE_MAX77836)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit a59a56cc4fb1f7d101f7ce1f5396ceaa2e304b71 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-5-318e14bdba0a... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/max77705.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/mfd/max77705.c b/drivers/mfd/max77705.c index 60c457c21d952..6b263bacb8c28 100644 --- a/drivers/mfd/max77705.c +++ b/drivers/mfd/max77705.c @@ -131,7 +131,9 @@ static int max77705_i2c_probe(struct i2c_client *i2c) if (ret) return dev_err_probe(dev, ret, "Failed to register child devices\n");
- device_init_wakeup(dev, true); + ret = devm_device_init_wakeup(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to init wakeup\n");
return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 6d0b2398b2638208d68ba06601f776cd5d983b75 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Karel Balej balejk@matfyz.cz Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-1-318e14bdba0a... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/88pm886.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/mfd/88pm886.c b/drivers/mfd/88pm886.c index 891fdce5d8c12..177878aa32f86 100644 --- a/drivers/mfd/88pm886.c +++ b/drivers/mfd/88pm886.c @@ -124,7 +124,11 @@ static int pm886_probe(struct i2c_client *client) if (err) return dev_err_probe(dev, err, "Failed to register power off handler\n");
- device_init_wakeup(dev, device_property_read_bool(dev, "wakeup-source")); + if (device_property_read_bool(dev, "wakeup-source")) { + err = devm_device_init_wakeup(dev); + if (err) + return dev_err_probe(dev, err, "Failed to init wakeup\n"); + }
return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 37ef4aa4039c42f4b15dc7e40d3e437b7f031522 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Baolin Wang baolin.wang@linux.alibaba.com Link: https://lore.kernel.org/r/20250406-mfd-device-wakekup-leak-v1-8-318e14bdba0a... Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mfd/sprd-sc27xx-spi.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mfd/sprd-sc27xx-spi.c b/drivers/mfd/sprd-sc27xx-spi.c index 7186e2108108f..d6b4350779e6a 100644 --- a/drivers/mfd/sprd-sc27xx-spi.c +++ b/drivers/mfd/sprd-sc27xx-spi.c @@ -210,7 +210,10 @@ static int sprd_pmic_probe(struct spi_device *spi) return ret; }
- device_init_wakeup(&spi->dev, true); + ret = devm_device_init_wakeup(&spi->dev); + if (ret) + return dev_err_probe(&spi->dev, ret, "Failed to init wakeup\n"); + return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikhil Jha njha@janestreet.com
[ Upstream commit fadc0f3bb2de8c570ced6d9c1f97222213d93140 ]
RFC2203 requires that retransmitted messages use a new gss sequence number, but the same XID. This means that if the server is just slow (e.x. overloaded), the client might receive a response using an older seqno than the one it has recorded.
Currently, Linux's client immediately retransmits in this case. However, this leads to a lot of wasted retransmits until the server eventually responds faster than the client can resend.
Client -> SEQ 1 -> Server Client -> SEQ 2 -> Server Client <- SEQ 1 <- Server (misses, expecting seqno = 2) Client -> SEQ 3 -> Server (immediate retransmission on miss) Client <- SEQ 2 <- Server (misses, expecting seqno = 3) Client -> SEQ 4 -> Server (immediate retransmission on miss) ... and so on ...
This commit makes it so that we ignore messages with bad checksums due to seqnum mismatch, and rely on the usual timeout behavior for retransmission instead of doing so immediately.
Signed-off-by: Nikhil Jha njha@janestreet.com Acked-by: Chuck Lever chuck.lever@oracle.com Signed-off-by: Anna Schumaker anna.schumaker@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/sunrpc/clnt.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 6f75862d97820..21426c3049d35 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -2771,8 +2771,13 @@ rpc_decode_header(struct rpc_task *task, struct xdr_stream *xdr) case -EPROTONOSUPPORT: goto out_err; case -EACCES: - /* Re-encode with a fresh cred */ - fallthrough; + /* possible RPCSEC_GSS out-of-sequence event (RFC2203), + * reset recv state and keep waiting, don't retransmit + */ + task->tk_rqstp->rq_reply_bytes_recvd = 0; + task->tk_status = xprt_request_enqueue_receive(task); + task->tk_action = call_transmit_status; + return -EBADMSG; default: goto out_garbage; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yikai Tsai yikai.tsai.wiwynn@gmail.com
[ Upstream commit b2446a16dbf2347a07af0cf994ca36576d94df77 ]
According to the ISL28022 datasheet, bit15 of the current register is representing -32768. Fix the calculation to properly handle this bit, ensuring correct measurements for negative values.
Signed-off-by: Yikai Tsai yikai.tsai.wiwynn@gmail.com Link: https://lore.kernel.org/r/20250519084055.3787-2-yikai.tsai.wiwynn@gmail.com Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/isl28022.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/isl28022.c b/drivers/hwmon/isl28022.c index 1fb9864635db9..1b4fb0824d6c0 100644 --- a/drivers/hwmon/isl28022.c +++ b/drivers/hwmon/isl28022.c @@ -154,6 +154,7 @@ static int isl28022_read_current(struct device *dev, u32 attr, long *val) struct isl28022_data *data = dev_get_drvdata(dev); unsigned int regval; int err; + u16 sign_bit;
switch (attr) { case hwmon_curr_input: @@ -161,8 +162,9 @@ static int isl28022_read_current(struct device *dev, u32 attr, long *val) ISL28022_REG_CURRENT, ®val); if (err < 0) return err; - *val = ((long)regval * 1250L * (long)data->gain) / - (long)data->shunt; + sign_bit = (regval >> 15) & 0x01; + *val = (((long)(((u16)regval) & 0x7FFF) - (sign_bit * 32768)) * + 1250L * (long)data->gain) / (long)data->shunt; break; default: return -EOPNOTSUPP;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Sakai msakai@redhat.com
[ Upstream commit 3da732687d72078e52cc7f334a482383e84ca156 ]
The function get_volume_page_protected may place a request on a queue for another thread to process asynchronously. When this happens, the volume should not read the request from the original thread. This can not currently cause problems, due to the way request processing is handled, but it is not safe in general.
Reviewed-by: Ken Raeburn raeburn@redhat.com Signed-off-by: Matthew Sakai msakai@redhat.com Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/dm-vdo/indexer/volume.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/drivers/md/dm-vdo/indexer/volume.c b/drivers/md/dm-vdo/indexer/volume.c index 655453bb276be..425b3a74f4dba 100644 --- a/drivers/md/dm-vdo/indexer/volume.c +++ b/drivers/md/dm-vdo/indexer/volume.c @@ -754,10 +754,11 @@ static int get_volume_page_protected(struct volume *volume, struct uds_request * u32 physical_page, struct cached_page **page_ptr) { struct cached_page *page; + unsigned int zone_number = request->zone_number;
get_page_from_cache(&volume->page_cache, physical_page, &page); if (page != NULL) { - if (request->zone_number == 0) { + if (zone_number == 0) { /* Only one zone is allowed to update the LRU. */ make_page_most_recent(&volume->page_cache, page); } @@ -767,7 +768,7 @@ static int get_volume_page_protected(struct volume *volume, struct uds_request * }
/* Prepare to enqueue a read for the page. */ - end_pending_search(&volume->page_cache, request->zone_number); + end_pending_search(&volume->page_cache, zone_number); mutex_lock(&volume->read_threads_mutex);
/* @@ -787,8 +788,7 @@ static int get_volume_page_protected(struct volume *volume, struct uds_request * * the order does not matter for correctness as it does below. */ mutex_unlock(&volume->read_threads_mutex); - begin_pending_search(&volume->page_cache, physical_page, - request->zone_number); + begin_pending_search(&volume->page_cache, physical_page, zone_number); return UDS_QUEUED; }
@@ -797,7 +797,7 @@ static int get_volume_page_protected(struct volume *volume, struct uds_request * * "search pending" state in careful order so no other thread can mess with the data before * the caller gets to look at it. */ - begin_pending_search(&volume->page_cache, physical_page, request->zone_number); + begin_pending_search(&volume->page_cache, physical_page, zone_number); mutex_unlock(&volume->read_threads_mutex); *page_ptr = page; return UDS_SUCCESS; @@ -849,6 +849,7 @@ static int search_cached_index_page(struct volume *volume, struct uds_request *r { int result; struct cached_page *page = NULL; + unsigned int zone_number = request->zone_number; u32 physical_page = map_to_physical_page(volume->geometry, chapter, index_page_number);
@@ -858,18 +859,18 @@ static int search_cached_index_page(struct volume *volume, struct uds_request *r * invalidation by the reader thread, before the reader thread has noticed that the * invalidate_counter has been incremented. */ - begin_pending_search(&volume->page_cache, physical_page, request->zone_number); + begin_pending_search(&volume->page_cache, physical_page, zone_number);
result = get_volume_page_protected(volume, request, physical_page, &page); if (result != UDS_SUCCESS) { - end_pending_search(&volume->page_cache, request->zone_number); + end_pending_search(&volume->page_cache, zone_number); return result; }
result = uds_search_chapter_index_page(&page->index_page, volume->geometry, &request->record_name, record_page_number); - end_pending_search(&volume->page_cache, request->zone_number); + end_pending_search(&volume->page_cache, zone_number); return result; }
@@ -882,6 +883,7 @@ int uds_search_cached_record_page(struct volume *volume, struct uds_request *req { struct cached_page *record_page; struct index_geometry *geometry = volume->geometry; + unsigned int zone_number = request->zone_number; int result; u32 physical_page, page_number;
@@ -905,11 +907,11 @@ int uds_search_cached_record_page(struct volume *volume, struct uds_request *req * invalidation by the reader thread, before the reader thread has noticed that the * invalidate_counter has been incremented. */ - begin_pending_search(&volume->page_cache, physical_page, request->zone_number); + begin_pending_search(&volume->page_cache, physical_page, zone_number);
result = get_volume_page_protected(volume, request, physical_page, &record_page); if (result != UDS_SUCCESS) { - end_pending_search(&volume->page_cache, request->zone_number); + end_pending_search(&volume->page_cache, zone_number); return result; }
@@ -917,7 +919,7 @@ int uds_search_cached_record_page(struct volume *volume, struct uds_request *req &request->record_name, geometry, &request->old_metadata)) *found = true;
- end_pending_search(&volume->page_cache, request->zone_number); + end_pending_search(&volume->page_cache, zone_number); return UDS_SUCCESS; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Schwermer sven.schwermer@disruptive-technologies.com
[ Upstream commit e35ca991a777ef513040cbb36bc8245a031a2633 ]
When writing to the multi_intensity file, don't unconditionally call led_set_brightness. By only doing this if blinking is inactive we prevent blinking from stopping if the blinking is in its off phase while the file is written.
Instead, if blinking is active, the changed intensity values are applied upon the next blink. This is consistent with changing the brightness on monochrome LEDs with active blinking.
Suggested-by: Jacek Anaszewski jacek.anaszewski@gmail.com Acked-by: Jacek Anaszewski jacek.anaszewski@gmail.com Acked-by: Pavel Machek pavel@ucw.cz Reviewed-by: Tobias Deiminger tobias.deiminger@linutronix.de Tested-by: Sven Schuchmann schuchmann@schleissheimer.de Signed-off-by: Sven Schwermer sven.schwermer@disruptive-technologies.com Link: https://lore.kernel.org/r/20250404184043.227116-1-sven@svenschwermer.de Signed-off-by: Lee Jones lee@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/leds/led-class-multicolor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/leds/led-class-multicolor.c b/drivers/leds/led-class-multicolor.c index b2a87c9948165..fd66d2bdeace8 100644 --- a/drivers/leds/led-class-multicolor.c +++ b/drivers/leds/led-class-multicolor.c @@ -59,7 +59,8 @@ static ssize_t multi_intensity_store(struct device *dev, for (i = 0; i < mcled_cdev->num_colors; i++) mcled_cdev->subled_info[i].intensity = intensity_value[i];
- led_set_brightness(led_cdev, led_cdev->brightness); + if (!test_bit(LED_BLINK_SW, &led_cdev->work_flags)) + led_set_brightness(led_cdev, led_cdev->brightness); ret = size; err_out: mutex_unlock(&led_cdev->led_access);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guang Yuan Wu gwu@ddn.com
[ Upstream commit 69efbff69f89c9b2b72c4d82ad8b59706add768a ]
When mounting a user-space filesystem on multiple clients, after concurrent ->setattr() calls from different node, stale inode attributes may be cached in some node.
This is caused by fuse_setattr() racing with fuse_reverse_inval_inode().
When filesystem server receives setattr request, the client node with valid iattr cached will be required to update the fuse_inode's attr_version and invalidate the cache by fuse_reverse_inval_inode(), and at the next call to ->getattr() they will be fetched from user space.
The race scenario is: 1. client-1 sends setattr (iattr-1) request to server 2. client-1 receives the reply from server 3. before client-1 updates iattr-1 to the cached attributes by fuse_change_attributes_common(), server receives another setattr (iattr-2) request from client-2 4. server requests client-1 to update the inode attr_version and invalidate the cached iattr, and iattr-1 becomes staled 5. client-2 receives the reply from server, and caches iattr-2 6. continue with step 2, client-1 invokes fuse_change_attributes_common(), and caches iattr-1
The issue has been observed from concurrent of chmod, chown, or truncate, which all invoke ->setattr() call.
The solution is to use fuse_inode's attr_version to check whether the attributes have been modified during the setattr request's lifetime. If so, mark the attributes as invalid in the function fuse_change_attributes_common().
Signed-off-by: Guang Yuan Wu gwu@ddn.com Reviewed-by: Bernd Schubert bschubert@ddn.com Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/fuse/dir.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 83ac192e7fdd1..fa90309030e21 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1946,6 +1946,7 @@ int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry, int err; bool trust_local_cmtime = is_wb; bool fault_blocked = false; + u64 attr_version;
if (!fc->default_permissions) attr->ia_valid |= ATTR_FORCE; @@ -2030,6 +2031,8 @@ int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry, if (fc->handle_killpriv_v2 && !capable(CAP_FSETID)) inarg.valid |= FATTR_KILL_SUIDGID; } + + attr_version = fuse_get_attr_version(fm->fc); fuse_setattr_fill(fc, &args, inode, &inarg, &outarg); err = fuse_simple_request(fm, &args); if (err) { @@ -2055,6 +2058,14 @@ int fuse_do_setattr(struct mnt_idmap *idmap, struct dentry *dentry, /* FIXME: clear I_DIRTY_SYNC? */ }
+ if (fi->attr_version > attr_version) { + /* + * Apply attributes, for example for fsnotify_change(), but set + * attribute timeout to zero. + */ + outarg.attr_valid = outarg.attr_valid_nsec = 0; + } + fuse_change_attributes_common(inode, &outarg.attr, NULL, ATTR_TIMEOUT(&outarg), fuse_get_cache_mask(inode), 0);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Richter rrichter@amd.com
[ Upstream commit d90acdf49e18029cfe4194475c45ef143657737a ]
Broken target lists are hard to discover as the driver fails at a later initialization stage. Add an error message for this.
Example log messages:
cxl_mem mem1: failed to find endpoint6:0000:e0:01.3 in target list of decoder1.1 cxl_port endpoint6: failed to register decoder6.0: -6 cxl_port endpoint6: probe: 0
Signed-off-by: Robert Richter rrichter@amd.com Reviewed-by: Gregory Price gourry@gourry.net Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Dave Jiang dave.jiang@intel.com Reviewed-by: Dan Williams dan.j.williams@intel.com Reviewed-by: Alison Schofield alison.schofield@intel.com Reviewed-by: "Fabio M. De Francesco" fabio.m.de.francesco@linux.intel.com Tested-by: Gregory Price gourry@gourry.net Acked-by: Dan Williams dan.j.williams@intel.com Link: https://patch.msgid.link/20250509150700.2817697-14-rrichter@amd.com Signed-off-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/core/region.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index c3f4dc244df77..24b161c7749f9 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -1805,6 +1805,13 @@ static int find_pos_and_ways(struct cxl_port *port, struct range *range, } put_device(dev);
+ if (rc) + dev_err(port->uport_dev, + "failed to find %s:%s in target list of %s\n", + dev_name(&port->dev), + dev_name(port->parent_dport->dport_dev), + dev_name(&cxlsd->cxld.dev)); + return rc; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory Price gourry@gourry.net
[ Upstream commit ce32b0c9c522e5a69ef9c62a56d6ca08fb036d67 ]
When validating decoder IW/IG when setting up regions, the granularity is irrelevant when iw=1 - all accesses will always route to the only target anyway - so all ig values are "correct". Loosen the requirement that `ig = (parent_iw * parent_ig)` when iw=1.
On some Zen5 platforms, the platform BIOS specifies a 256-byte interleave granularity window for host bridges when there is only one target downstream. This leads to Linux rejecting the configuration of a region with a x2 root with two x1 hostbridges.
Decoder Programming: root - iw:2 ig:256 hb1 - iw:1 ig:256 (Linux expects 512) hb2 - iw:1 ig:256 (Linux expects 512) ep1 - iw:2 ig:256 ep2 - iw:2 ig:256
This change allows all decoders downstream of a passthrough decoder to also be configured as passthrough (iw:1 ig:X), but still disallows downstream decoders from applying subsequent interleaves.
e.g. in the above example if there was another decoder south of hb1 attempting to interleave 2 endpoints - Linux would enforce hb1.ig=512 because the southern decoder would have iw:2 and require ig=pig*piw.
[DJ: Fixed up against 6.15-rc1]
Signed-off-by: Gregory Price gourry@gourry.net Reviewed-by: Dave Jiang dave.jiang@intel.com Tested-by: Li Zhijian lizhijian@fujitsu.com Reviewed-by: Davidlohr Bueso dave@stgolabs.net Reviewed-by: Jonathan Cameron Jonathan.Cameron@huawei.com Reviewed-by: Dan Williams dan.j.williams@intel.com Link: https://patch.msgid.link/20250402232552.999634-1-gourry@gourry.net Signed-off-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/core/region.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c index 24b161c7749f9..7585f0302f3a2 100644 --- a/drivers/cxl/core/region.c +++ b/drivers/cxl/core/region.c @@ -1446,7 +1446,7 @@ static int cxl_port_setup_targets(struct cxl_port *port,
if (test_bit(CXL_REGION_F_AUTO, &cxlr->flags)) { if (cxld->interleave_ways != iw || - cxld->interleave_granularity != ig || + (iw > 1 && cxld->interleave_granularity != ig) || !region_res_match_cxl_range(p, &cxld->hpa_range) || ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) { dev_err(&cxlr->dev,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Scott Mayhew smayhew@redhat.com
[ Upstream commit 6e9a2f8dbe93c8004c2af2c0158888628b7ca034 ]
The nfs inodes for referral anchors that have not yet been followed have their filehandles zeroed out.
Attempting to call getxattr() on one of these will cause the nfs client to send a GETATTR to the nfs server with the preceding PUTFH sans filehandle. The server will reply NFS4ERR_NOFILEHANDLE, leading to -EIO being returned to the application.
For example:
$ strace -e trace=getxattr getfattr -n system.nfs4_acl /mnt/t/ref getxattr("/mnt/t/ref", "system.nfs4_acl", NULL, 0) = -1 EIO (Input/output error) /mnt/t/ref: system.nfs4_acl: Input/output error +++ exited with 1 +++
Have the xattr handlers return -ENODATA instead.
Signed-off-by: Scott Mayhew smayhew@redhat.com Signed-off-by: Anna Schumaker anna.schumaker@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/nfs/nfs4proc.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6c3896a9b9d0f..2f5a6aa3fd48e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -6220,6 +6220,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen, struct nfs_server *server = NFS_SERVER(inode); int ret;
+ if (unlikely(NFS_FH(inode)->size == 0)) + return -ENODATA; if (!nfs4_server_supports_acls(server, type)) return -EOPNOTSUPP; ret = nfs_revalidate_inode(inode, NFS_INO_INVALID_CHANGE); @@ -6294,6 +6296,9 @@ static int nfs4_proc_set_acl(struct inode *inode, const void *buf, { struct nfs4_exception exception = { }; int err; + + if (unlikely(NFS_FH(inode)->size == 0)) + return -ENODATA; do { err = __nfs4_proc_set_acl(inode, buf, buflen, type); trace_nfs4_set_acl(inode, err);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexis Czezar Torreno alexisczezar.torreno@analog.com
[ Upstream commit 19932f844f3f51646f762f3eac4744ec3a405064 ]
The max344** family has an issue with some PMBUS address being switched. This includes max34451 however version MAX34451-NA6 and later has this issue fixed and this commit supports that update.
Signed-off-by: Alexis Czezar Torreno alexisczezar.torreno@analog.com Link: https://lore.kernel.org/r/20250407-dev_adpm12160-v3-1-9cd3095445c8@analog.co... Signed-off-by: Guenter Roeck linux@roeck-us.net Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwmon/pmbus/max34440.c | 48 +++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 4 deletions(-)
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c index c9dda33831ff2..d6d556b013853 100644 --- a/drivers/hwmon/pmbus/max34440.c +++ b/drivers/hwmon/pmbus/max34440.c @@ -34,16 +34,21 @@ enum chips { max34440, max34441, max34446, max34451, max34460, max34461 }; /* * The whole max344* family have IOUT_OC_WARN_LIMIT and IOUT_OC_FAULT_LIMIT * swapped from the standard pmbus spec addresses. + * For max34451, version MAX34451ETNA6+ and later has this issue fixed. */ #define MAX34440_IOUT_OC_WARN_LIMIT 0x46 #define MAX34440_IOUT_OC_FAULT_LIMIT 0x4A
+#define MAX34451ETNA6_MFR_REV 0x0012 + #define MAX34451_MFR_CHANNEL_CONFIG 0xe4 #define MAX34451_MFR_CHANNEL_CONFIG_SEL_MASK 0x3f
struct max34440_data { int id; struct pmbus_driver_info info; + u8 iout_oc_warn_limit; + u8 iout_oc_fault_limit; };
#define to_max34440_data(x) container_of(x, struct max34440_data, info) @@ -60,11 +65,11 @@ static int max34440_read_word_data(struct i2c_client *client, int page, switch (reg) { case PMBUS_IOUT_OC_FAULT_LIMIT: ret = pmbus_read_word_data(client, page, phase, - MAX34440_IOUT_OC_FAULT_LIMIT); + data->iout_oc_fault_limit); break; case PMBUS_IOUT_OC_WARN_LIMIT: ret = pmbus_read_word_data(client, page, phase, - MAX34440_IOUT_OC_WARN_LIMIT); + data->iout_oc_warn_limit); break; case PMBUS_VIRT_READ_VOUT_MIN: ret = pmbus_read_word_data(client, page, phase, @@ -133,11 +138,11 @@ static int max34440_write_word_data(struct i2c_client *client, int page,
switch (reg) { case PMBUS_IOUT_OC_FAULT_LIMIT: - ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_FAULT_LIMIT, + ret = pmbus_write_word_data(client, page, data->iout_oc_fault_limit, word); break; case PMBUS_IOUT_OC_WARN_LIMIT: - ret = pmbus_write_word_data(client, page, MAX34440_IOUT_OC_WARN_LIMIT, + ret = pmbus_write_word_data(client, page, data->iout_oc_warn_limit, word); break; case PMBUS_VIRT_RESET_POUT_HISTORY: @@ -235,6 +240,25 @@ static int max34451_set_supported_funcs(struct i2c_client *client, */
int page, rv; + bool max34451_na6 = false; + + rv = i2c_smbus_read_word_data(client, PMBUS_MFR_REVISION); + if (rv < 0) + return rv; + + if (rv >= MAX34451ETNA6_MFR_REV) { + max34451_na6 = true; + data->info.format[PSC_VOLTAGE_IN] = direct; + data->info.format[PSC_CURRENT_IN] = direct; + data->info.m[PSC_VOLTAGE_IN] = 1; + data->info.b[PSC_VOLTAGE_IN] = 0; + data->info.R[PSC_VOLTAGE_IN] = 3; + data->info.m[PSC_CURRENT_IN] = 1; + data->info.b[PSC_CURRENT_IN] = 0; + data->info.R[PSC_CURRENT_IN] = 2; + data->iout_oc_fault_limit = PMBUS_IOUT_OC_FAULT_LIMIT; + data->iout_oc_warn_limit = PMBUS_IOUT_OC_WARN_LIMIT; + }
for (page = 0; page < 16; page++) { rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); @@ -251,16 +275,30 @@ static int max34451_set_supported_funcs(struct i2c_client *client, case 0x20: data->info.func[page] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; + + if (max34451_na6) + data->info.func[page] |= PMBUS_HAVE_VIN | + PMBUS_HAVE_STATUS_INPUT; break; case 0x21: data->info.func[page] = PMBUS_HAVE_VOUT; + + if (max34451_na6) + data->info.func[page] |= PMBUS_HAVE_VIN; break; case 0x22: data->info.func[page] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; + + if (max34451_na6) + data->info.func[page] |= PMBUS_HAVE_IIN | + PMBUS_HAVE_STATUS_INPUT; break; case 0x23: data->info.func[page] = PMBUS_HAVE_IOUT; + + if (max34451_na6) + data->info.func[page] |= PMBUS_HAVE_IIN; break; default: break; @@ -494,6 +532,8 @@ static int max34440_probe(struct i2c_client *client) return -ENOMEM; data->id = i2c_match_id(max34440_id, client)->driver_data; data->info = max34440_info[data->id]; + data->iout_oc_fault_limit = MAX34440_IOUT_OC_FAULT_LIMIT; + data->iout_oc_warn_limit = MAX34440_IOUT_OC_WARN_LIMIT;
if (data->id == max34451) { rv = max34451_set_supported_funcs(client, data);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit dc3e0f17f74558e8a2fce00608855f050de10230 ]
If client send SMB2_CREATE_POSIX_CONTEXT to ksmbd, Allow a filename to contain special characters.
Reported-by: Philipp Kerling pkerling@casix.org Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/smb2pdu.c | 53 +++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index c6b990c93bfa7..a9f9426e91acb 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -2875,7 +2875,7 @@ int smb2_open(struct ksmbd_work *work) int req_op_level = 0, open_flags = 0, may_flags = 0, file_info = 0; int rc = 0; int contxt_cnt = 0, query_disk_id = 0; - int maximal_access_ctxt = 0, posix_ctxt = 0; + bool maximal_access_ctxt = false, posix_ctxt = false; int s_type = 0; int next_off = 0; char *name = NULL; @@ -2904,6 +2904,27 @@ int smb2_open(struct ksmbd_work *work) return create_smb2_pipe(work); }
+ if (req->CreateContextsOffset && tcon->posix_extensions) { + context = smb2_find_context_vals(req, SMB2_CREATE_TAG_POSIX, 16); + if (IS_ERR(context)) { + rc = PTR_ERR(context); + goto err_out2; + } else if (context) { + struct create_posix *posix = (struct create_posix *)context; + + if (le16_to_cpu(context->DataOffset) + + le32_to_cpu(context->DataLength) < + sizeof(struct create_posix) - 4) { + rc = -EINVAL; + goto err_out2; + } + ksmbd_debug(SMB, "get posix context\n"); + + posix_mode = le32_to_cpu(posix->Mode); + posix_ctxt = true; + } + } + if (req->NameLength) { name = smb2_get_name((char *)req + le16_to_cpu(req->NameOffset), le16_to_cpu(req->NameLength), @@ -2926,9 +2947,11 @@ int smb2_open(struct ksmbd_work *work) goto err_out2; }
- rc = ksmbd_validate_filename(name); - if (rc < 0) - goto err_out2; + if (posix_ctxt == false) { + rc = ksmbd_validate_filename(name); + if (rc < 0) + goto err_out2; + }
if (ksmbd_share_veto_filename(share, name)) { rc = -ENOENT; @@ -3086,28 +3109,6 @@ int smb2_open(struct ksmbd_work *work) rc = -EBADF; goto err_out2; } - - if (tcon->posix_extensions) { - context = smb2_find_context_vals(req, - SMB2_CREATE_TAG_POSIX, 16); - if (IS_ERR(context)) { - rc = PTR_ERR(context); - goto err_out2; - } else if (context) { - struct create_posix *posix = - (struct create_posix *)context; - if (le16_to_cpu(context->DataOffset) + - le32_to_cpu(context->DataLength) < - sizeof(struct create_posix) - 4) { - rc = -EINVAL; - goto err_out2; - } - ksmbd_debug(SMB, "get posix context\n"); - - posix_mode = le32_to_cpu(posix->Mode); - posix_ctxt = 1; - } - } }
if (ksmbd_override_fsids(work)) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 571781eb7ffefa65b0e922c8031e42b4411a40d4 ]
The Mac SMB client code seems to expect the on-disk file identifier to have the semantics of HFS+ Catalog Node Identifier (CNID). ksmbd provides the inode number as a unique ID to the client, but in the case of subvolumes of btrfs, there are cases where different files have the same inode number, so the mac smb client treats it as an error. There is a report that a similar problem occurs when the share is ZFS. Returning UniqueId of zero will make the Mac client to stop using and trusting the file id returned from the server.
Reported-by: Justin Turner Arthur justinarthur@gmail.com Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/server/connection.h | 1 + fs/smb/server/smb2pdu.c | 19 +++++++++++++++++-- fs/smb/server/smb2pdu.h | 3 +++ 3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h index 572102098c108..dd3e0e3f7bf04 100644 --- a/fs/smb/server/connection.h +++ b/fs/smb/server/connection.h @@ -108,6 +108,7 @@ struct ksmbd_conn { __le16 signing_algorithm; bool binding; atomic_t refcnt; + bool is_aapl; };
struct ksmbd_conn_ops { diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c index a9f9426e91acb..ad2b15ec3b561 100644 --- a/fs/smb/server/smb2pdu.c +++ b/fs/smb/server/smb2pdu.c @@ -3541,6 +3541,15 @@ int smb2_open(struct ksmbd_work *work) ksmbd_debug(SMB, "get query on disk id context\n"); query_disk_id = 1; } + + if (conn->is_aapl == false) { + context = smb2_find_context_vals(req, SMB2_CREATE_AAPL, 4); + if (IS_ERR(context)) { + rc = PTR_ERR(context); + goto err_out1; + } else if (context) + conn->is_aapl = true; + } }
rc = ksmbd_vfs_getattr(&path, &stat); @@ -3980,7 +3989,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, if (dinfo->EaSize) dinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE; dinfo->Reserved = 0; - dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); + if (conn->is_aapl) + dinfo->UniqueId = 0; + else + dinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); if (d_info->hide_dot_file && d_info->name[0] == '.') dinfo->ExtFileAttributes |= FILE_ATTRIBUTE_HIDDEN_LE; memcpy(dinfo->FileName, conv_name, conv_len); @@ -3997,7 +4009,10 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, smb2_get_reparse_tag_special_file(ksmbd_kstat->kstat->mode); if (fibdinfo->EaSize) fibdinfo->ExtFileAttributes = FILE_ATTRIBUTE_REPARSE_POINT_LE; - fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); + if (conn->is_aapl) + fibdinfo->UniqueId = 0; + else + fibdinfo->UniqueId = cpu_to_le64(ksmbd_kstat->kstat->ino); fibdinfo->ShortNameLength = 0; fibdinfo->Reserved = 0; fibdinfo->Reserved2 = cpu_to_le16(0); diff --git a/fs/smb/server/smb2pdu.h b/fs/smb/server/smb2pdu.h index 17a0b18a8406b..16ae8a10490be 100644 --- a/fs/smb/server/smb2pdu.h +++ b/fs/smb/server/smb2pdu.h @@ -63,6 +63,9 @@ struct preauth_integrity_info {
#define SMB2_SESSION_TIMEOUT (10 * HZ)
+/* Apple Defined Contexts */ +#define SMB2_CREATE_AAPL "AAPL" + struct create_durable_req_v2 { struct create_context_hdr ccontext; __u8 Name[8];
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: FUJITA Tomonori fujita.tomonori@gmail.com
[ Upstream commit 249c3a0e53acefc2b06d3b3e1fc28fb2081f878d ]
Place cleanup_module() in .exit.text section. Currently, cleanup_module() is likely placed in the .text section. It's inconsistent with the layout of C modules, where cleanup_module() is placed in .exit.text.
[ Boqun asked for an example of how the section changed to be put in the log. Tomonori provided the following examples:
C module:
$ objdump -t ~/build/x86/drivers/block/loop.o|grep clean 0000000000000000 l O .exit.data 0000000000000008 __UNIQUE_ID___addressable_cleanup_module412 0000000000000000 g F .exit.text 000000000000009c cleanup_module
Rust module without this patch:
$ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean 00000000000002b0 g F .text 00000000000000c6 cleanup_module 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module
Rust module with this patch:
$ objdump -t ~/build/x86/samples/rust/rust_minimal.o|grep clean 0000000000000000 g F .exit.text 00000000000000c6 cleanup_module 0000000000000000 g O .exit.data 0000000000000008 _R...___UNIQUE_ID___addressable_cleanup_module
- Miguel ]
Signed-off-by: FUJITA Tomonori fujita.tomonori@gmail.com Acked-by: Jarkko Sakkinen jarkko@kernel.org Link: https://lore.kernel.org/r/20250308044506.14458-1-fujita.tomonori@gmail.com Signed-off-by: Miguel Ojeda ojeda@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- rust/macros/module.rs | 1 + 1 file changed, 1 insertion(+)
diff --git a/rust/macros/module.rs b/rust/macros/module.rs index 2f66107847f78..44e5cb108cea7 100644 --- a/rust/macros/module.rs +++ b/rust/macros/module.rs @@ -278,6 +278,7 @@ pub(crate) fn module(ts: TokenStream) -> TokenStream { #[cfg(MODULE)] #[doc(hidden)] #[no_mangle] + #[link_section = ".exit.text"] pub extern "C" fn cleanup_module() {{ // SAFETY: // - This function is inaccessible to the outside due to the double
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rudraksha Gupta guptarud@gmail.com
[ Upstream commit 977c4308ee4270cf46e2c66b37de8e04670daa0c ]
Currently rust on arm fails to compile due to '-mno-fdpic'. This flag disables a GCC feature that we don't want for kernel builds, so let's skip it as it doesn't apply to Clang.
UPD include/generated/asm-offsets.h CALL scripts/checksyscalls.sh RUSTC L rust/core.o BINDGEN rust/bindings/bindings_generated.rs BINDGEN rust/bindings/bindings_helpers_generated.rs CC rust/helpers/helpers.o Unable to generate bindings: clang diagnosed error: error: unknown argument: '-mno-fdpic' make[2]: *** [rust/Makefile:369: rust/bindings/bindings_helpers_generated.rs] Error 1 make[2]: *** Deleting file 'rust/bindings/bindings_helpers_generated.rs' make[2]: *** Waiting for unfinished jobs.... Unable to generate bindings: clang diagnosed error: error: unknown argument: '-mno-fdpic' make[2]: *** [rust/Makefile:349: rust/bindings/bindings_generated.rs] Error 1 make[2]: *** Deleting file 'rust/bindings/bindings_generated.rs' make[1]: *** [/home/pmos/build/src/linux-next-next-20250521/Makefile:1285: prepare] Error 2 make: *** [Makefile:248: __sub-make] Error 2
[ Naresh provided the draft diff [1].
Ben explained [2]:
FDPIC is only relevant with no-MMU targets, and then only for userspace. When configured for the arm-*-uclinuxfdpiceabi target, GCC enables FDPIC by default to facilitate compiling userspace programs. FDPIC is never used for the kernel, and we pass -mno-fdpic when building the kernel to override the default and make sure FDPIC is disabled.
and [3]:
-mno-fdpic disables a GCC feature that we don't want for kernel builds. clang does not support this feature, so it always behaves as though -mno-fdpic is passed. Therefore, it should be fine to mix the two, at least as far as FDPIC is concerned.
[1] https://lore.kernel.org/rust-for-linux/CA+G9fYt4otQK4pHv8pJBW9e28yHSGCDncKqu... [2] https://lore.kernel.org/rust-for-linux/aAKrq2InExQk7f_k@dell-precision-5540/ [3] https://lore.kernel.org/rust-for-linux/aAo_F_UP1Gd4jHlZ@dell-precision-5540/
- Miguel ]
Reported-by: Linux Kernel Functional Testing lkft@linaro.org Closes: https://lore.kernel.org/all/CA+G9fYvOanQBYXKSg7C6EU30k8sTRC0JRPJXYu7wWK51w38... Suggested-by: Miguel Ojeda ojeda@kernel.org Acked-by: Naresh Kamboju naresh.kamboju@linaro.org Signed-off-by: Rudraksha Gupta guptarud@gmail.com Link: https://lore.kernel.org/r/20250522-rust-mno-fdpic-arm-fix-v2-1-a6f691d9c198@... [ Reworded title. - Miguel ] Signed-off-by: Miguel Ojeda ojeda@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- rust/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rust/Makefile b/rust/Makefile index 313a200112ce1..d62b58d0a55cc 100644 --- a/rust/Makefile +++ b/rust/Makefile @@ -275,7 +275,7 @@ bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \ -fzero-call-used-regs=% -fno-stack-clash-protection \ -fno-inline-functions-called-once -fsanitize=bounds-strict \ -fstrict-flex-arrays=% -fmin-function-alignment=% \ - -fzero-init-padding-bits=% \ + -fzero-init-padding-bits=% -mno-fdpic \ --param=% --param asan-%
# Derived from `scripts/Makefile.clang`.
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner lukas@wunner.de
[ Upstream commit 3be5fa236649da6404f1bca1491bf02d4b0d5cce ]
Commit 991de2e59090 ("PCI, x86: Implement pcibios_alloc_irq() and pcibios_free_irq()") changed IRQ handling on PCI driver probing. It inadvertently broke resume from system sleep on AMD platforms:
https://lore.kernel.org/r/20150926164651.GA3640@pd.tnic/
This was fixed by two independent commits:
* 8affb487d4a4 ("x86/PCI: Don't alloc pcibios-irq when MSI is enabled") * cbbc00be2ce3 ("iommu/amd: Prevent binding other PCI drivers to IOMMU PCI devices")
The breaking change and one of these two fixes were subsequently reverted:
* fe25d078874f ("Revert "x86/PCI: Don't alloc pcibios-irq when MSI is enabled"") * 6c777e8799a9 ("Revert "PCI, x86: Implement pcibios_alloc_irq() and pcibios_free_irq()"")
This rendered the second fix unnecessary, so revert it as well. It used the match_driver flag in struct pci_dev, which is internal to the PCI core and not supposed to be touched by arbitrary drivers.
Signed-off-by: Lukas Wunner lukas@wunner.de Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Krzysztof Wilczyński kwilczynski@kernel.org Acked-by: Joerg Roedel jroedel@suse.de Link: https://patch.msgid.link/9a3ddff5cc49512044f963ba0904347bd404094d.1745572340... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd/init.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c index 14aa0d77df26d..f9037dad53f31 100644 --- a/drivers/iommu/amd/init.c +++ b/drivers/iommu/amd/init.c @@ -2030,9 +2030,6 @@ static int __init iommu_init_pci(struct amd_iommu *iommu) if (!iommu->dev) return -ENODEV;
- /* Prevent binding other PCI device drivers to IOMMU devices */ - iommu->dev->match_driver = false; - /* ACPI _PRT won't have an IRQ for IOMMU */ iommu->dev->irq_managed = 1;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yi Sun yi.sun@intel.com
[ Upstream commit 17502e7d7b7113346296f6758324798d536c31fd ]
Running IDXD workloads in a container with the /dev directory mounted can trigger a call trace or even a kernel panic when the parent process of the container is terminated.
This issue occurs because, under certain configurations, Docker does not properly propagate the mount replica back to the original mount point.
In this case, when the user driver detaches, the WQ is destroyed but it still calls destroy_workqueue() attempting to completes all pending work. It's necessary to check wq->wq and skip the drain if it no longer exists.
Signed-off-by: Yi Sun yi.sun@intel.com Reviewed-by: Dave Jiang dave.jiang@intel.com Reviewed-by: Anil S Keshavamurthy anil.s.keshavamurthy@intel.com
Link: https://lore.kernel.org/r/20250509000304.1402863-1-yi.sun@intel.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/idxd/cdev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/dma/idxd/cdev.c b/drivers/dma/idxd/cdev.c index 6d12033649f81..bc934bc249df1 100644 --- a/drivers/dma/idxd/cdev.c +++ b/drivers/dma/idxd/cdev.c @@ -349,7 +349,9 @@ static void idxd_cdev_evl_drain_pasid(struct idxd_wq *wq, u32 pasid) set_bit(h, evl->bmap); h = (h + 1) % size; } - drain_workqueue(wq->wq); + if (wq->wq) + drain_workqueue(wq->wq); + mutex_unlock(&evl->lock); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gessler thomas.gessler@brueckmann-gmbh.de
[ Upstream commit 7e01511443c30a55a5ae78d3debd46d4d872517e ]
Coalesce the direction bits from the enabled TX and/or RX channels into the directions bit mask of dma_device. Without this mask set, dma_get_slave_caps() in the DMAEngine fails, which prevents the driver from being used with an IIO DMAEngine buffer.
Signed-off-by: Thomas Gessler thomas.gessler@brueckmann-gmbh.de Reviewed-by: Suraj Gupta suraj.gupta2@amd.com Tested-by: Folker Schwesinger dev@folker-schwesinger.de Link: https://lore.kernel.org/r/20250507182101.909010-1-thomas.gessler@brueckmann-... Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/xilinx/xilinx_dma.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c index 3ad44afd0e74e..8f26b6eff3f3e 100644 --- a/drivers/dma/xilinx/xilinx_dma.c +++ b/drivers/dma/xilinx/xilinx_dma.c @@ -2909,6 +2909,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev, return -EINVAL; }
+ xdev->common.directions |= chan->direction; + /* Request the interrupt */ chan->irq = of_irq_get(node, chan->tdest); if (chan->irq < 0)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenbin Yao quic_wenbyao@quicinc.com
[ Upstream commit af3c6eacce0c464f28fe0e3d365b3860aba07931 ]
As per DWC PCIe registers description 4.30a, section 1.13.43, NUM_OF_LANES named as PORT_LOGIC_LINK_WIDTH in PCIe DWC driver, is referred to as the "Predetermined Number of Lanes" in PCIe r6.0, sec 4.2.7.2.1, which explains the conditions required to enter Polling.Configuration:
Next state is Polling.Configuration after at least 1024 TS1 Ordered Sets were transmitted, and all Lanes that detected a Receiver during Detect receive eight consecutive training sequences ...
Otherwise, after a 24 ms timeout the next state is:
Polling.Configuration if,
(i) Any Lane, which detected a Receiver during Detect, received eight consecutive training sequences ... and a minimum of 1024 TS1 Ordered Sets are transmitted after receiving one TS1 or TS2 Ordered Set.
And
(ii) At least a predetermined set of Lanes that detected a Receiver during Detect have detected an exit from Electrical Idle at least once since entering Polling.Active.
Note: This may prevent one or more bad Receivers or Transmitters from holding up a valid Link from being configured, and allow for additional training in Polling.Configuration. The exact set of predetermined Lanes is implementation specific.
Note: Any Lane that receives eight consecutive TS1 or TS2 Ordered Sets should have detected an exit from Electrical Idle at least once since entering Polling.Active.
In a PCIe link supporting multiple lanes, if PORT_LOGIC_LINK_WIDTH is set to lane width the hardware supports, all lanes that detect a receiver during the Detect phase must receive eight consecutive training sequences. Otherwise, LTSSM will not enter Polling.Configuration and link training will fail.
Therefore, always set PORT_LOGIC_LINK_WIDTH to 1, regardless of the number of lanes the port actually supports, to make link up more robust. This setting will not affect the intended link width if all lanes are functional. Additionally, the link can still be established with at least one lane if other lanes are faulty.
Co-developed-by: Qiang Yu quic_qianyu@quicinc.com Signed-off-by: Qiang Yu quic_qianyu@quicinc.com Signed-off-by: Wenbin Yao quic_wenbyao@quicinc.com [mani: subject change] Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org [bhelgaas: update PCIe spec citation, format quote] Signed-off-by: Bjorn Helgaas bhelgaas@google.com Tested-by: Niklas Cassel cassel@kernel.org Link: https://patch.msgid.link/20250422103623.462277-1-quic_wenbyao@quicinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pcie-designware.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 97d76d3dc066e..be348b341e3cf 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -797,22 +797,19 @@ static void dw_pcie_link_set_max_link_width(struct dw_pcie *pci, u32 num_lanes) /* Set link width speed control register */ lwsc = dw_pcie_readl_dbi(pci, PCIE_LINK_WIDTH_SPEED_CONTROL); lwsc &= ~PORT_LOGIC_LINK_WIDTH_MASK; + lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES; switch (num_lanes) { case 1: plc |= PORT_LINK_MODE_1_LANES; - lwsc |= PORT_LOGIC_LINK_WIDTH_1_LANES; break; case 2: plc |= PORT_LINK_MODE_2_LANES; - lwsc |= PORT_LOGIC_LINK_WIDTH_2_LANES; break; case 4: plc |= PORT_LINK_MODE_4_LANES; - lwsc |= PORT_LOGIC_LINK_WIDTH_4_LANES; break; case 8: plc |= PORT_LINK_MODE_8_LANES; - lwsc |= PORT_LOGIC_LINK_WIDTH_8_LANES; break; default: dev_err(pci->dev, "num-lanes %u: invalid value\n", num_lanes);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hector Martin marcan@marcan.st
[ Upstream commit 7fa9fbf39116b061f8a41cd84f1884c545f322c4 ]
In the success path, we hang onto a reference to the node, so make sure to grab one. The caller iterator puts our borrowed reference when we return.
Signed-off-by: Hector Martin marcan@marcan.st Signed-off-by: Alyssa Rosenzweig alyssa@rosenzweig.io Signed-off-by: Marc Zyngier maz@kernel.org Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Tested-by: Janne Grunau j@jannau.net Reviewed-by: Rob Herring (Arm) robh@kernel.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Acked-by: Alyssa Rosenzweig alyssa@rosenzweig.io Link: https://patch.msgid.link/20250401091713.2765724-9-maz@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/pcie-apple.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c index 32f57b8a6ecbd..8f7fc9161760c 100644 --- a/drivers/pci/controller/pcie-apple.c +++ b/drivers/pci/controller/pcie-apple.c @@ -584,6 +584,9 @@ static int apple_pcie_setup_port(struct apple_pcie *pcie, list_add_tail(&port->entry, &pcie->ports); init_completion(&pcie->event);
+ /* In the success path, we keep a reference to np around */ + of_node_get(np); + ret = apple_pcie_port_register_irqs(port); WARN_ON(ret);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Zhu hongxing.zhu@nxp.com
[ Upstream commit ce0c43e855c7f652b6351110aaaabf9b521debd7 ]
ERR051624: The Controller Without Vaux Cannot Exit L23 Ready Through Beacon or PERST# De-assertion
When the auxiliary power is not available, the controller cannot exit from L23 Ready with beacon or PERST# de-assertion when main power is not removed. So the workaround is to set SS_RW_REG_1[SYS_AUX_PWR_DET] to 1.
This workaround is required irrespective of whether Vaux is supplied to the link partner or not.
Signed-off-by: Richard Zhu hongxing.zhu@nxp.com [mani: subject and description rewording] Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Frank Li Frank.Li@nxp.com Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://patch.msgid.link/20250416081314.3929794-5-hongxing.zhu@nxp.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/controller/dwc/pci-imx6.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c index ea5c06371171f..1b6fbf507166f 100644 --- a/drivers/pci/controller/dwc/pci-imx6.c +++ b/drivers/pci/controller/dwc/pci-imx6.c @@ -48,6 +48,8 @@ #define IMX95_PCIE_SS_RW_REG_0 0xf0 #define IMX95_PCIE_REF_CLKEN BIT(23) #define IMX95_PCIE_PHY_CR_PARA_SEL BIT(9) +#define IMX95_PCIE_SS_RW_REG_1 0xf4 +#define IMX95_PCIE_SYS_AUX_PWR_DET BIT(31)
#define IMX95_PE0_GEN_CTRL_1 0x1050 #define IMX95_PCIE_DEVICE_TYPE GENMASK(3, 0) @@ -231,6 +233,19 @@ static unsigned int imx_pcie_grp_offset(const struct imx_pcie *imx_pcie)
static int imx95_pcie_init_phy(struct imx_pcie *imx_pcie) { + /* + * ERR051624: The Controller Without Vaux Cannot Exit L23 Ready + * Through Beacon or PERST# De-assertion + * + * When the auxiliary power is not available, the controller + * cannot exit from L23 Ready with beacon or PERST# de-assertion + * when main power is not removed. + * + * Workaround: Set SS_RW_REG_1[SYS_AUX_PWR_DET] to 1. + */ + regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_1, + IMX95_PCIE_SYS_AUX_PWR_DET); + regmap_update_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_SS_RW_REG_0, IMX95_PCIE_PHY_CR_PARA_SEL,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilan Peer ilan.peer@intel.com
[ Upstream commit f81aa834bfa91c827f290b62a245e23c5ad2813c ]
The regulatory domain information was initialized every time the FW was loaded and the device was restarted. This was unnecessary and useless as at this stage the wiphy channels information was not setup yet so while the regulatory domain was set to the wiphy, the channel information was not updated.
In case that a specific MCC was configured during FW initialization then following updates with this MCC are ignored, and thus the wiphy channels information is left with information not matching the regulatory domain.
This commit moves the regulatory domain initialization to after the operational firmware is started, i.e., after the wiphy channels were configured and the regulatory information is needed.
Signed-off-by: Ilan Peer ilan.peer@intel.com Reviewed-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Miri Korenblit miriam.rachel.korenblit@intel.com Link: https://patch.msgid.link/20250604061200.f138a7382093.I2fd8b3e99be13c2687da48... Signed-off-by: Miri Korenblit miriam.rachel.korenblit@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/wireless/intel/iwlwifi/mld/fw.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/mld/fw.c b/drivers/net/wireless/intel/iwlwifi/mld/fw.c index 4b083d447ee2f..6be9366bd4b14 100644 --- a/drivers/net/wireless/intel/iwlwifi/mld/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mld/fw.c @@ -339,10 +339,6 @@ int iwl_mld_load_fw(struct iwl_mld *mld) if (ret) goto err;
- ret = iwl_mld_init_mcc(mld); - if (ret) - goto err; - mld->fw_status.running = true;
return 0; @@ -535,6 +531,10 @@ int iwl_mld_start_fw(struct iwl_mld *mld) if (ret) goto error;
+ ret = iwl_mld_init_mcc(mld); + if (ret) + goto error; + return 0;
error:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke hare@kernel.org
[ Upstream commit f42d4796ee100fade86086d1cf98537fb4d326c8 ]
When the socket is busy processing nvme_tcp_try_recv() might return -EAGAIN, but this doesn't automatically imply that the sending side is blocked, too. So check if there are pending requests once nvme_tcp_try_recv() returns -EAGAIN and continue with the sending loop to avoid I/O stalls.
Signed-off-by: Hannes Reinecke hare@kernel.org Acked-by: Chris Leech cleech@redhat.com Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/tcp.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 947fac9128b30..9f4f6464dee04 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -1348,7 +1348,7 @@ static int nvme_tcp_try_recv(struct nvme_tcp_queue *queue) queue->nr_cqe = 0; consumed = sock->ops->read_sock(sk, &rd_desc, nvme_tcp_recv_skb); release_sock(sk); - return consumed; + return consumed == -EAGAIN ? 0 : consumed; }
static void nvme_tcp_io_work(struct work_struct *w) @@ -1376,6 +1376,11 @@ static void nvme_tcp_io_work(struct work_struct *w) else if (unlikely(result < 0)) return;
+ /* did we get some space after spending time in recv? */ + if (nvme_tcp_queue_has_pending(queue) && + sk_stream_is_writeable(queue->sock->sk)) + pending = true; + if (!pending || !queue->rd_enabled) return;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke hare@kernel.org
[ Upstream commit 0bf04c874fcb1ae46a863034296e4b33d8fbd66c ]
Validate the request in nvme_tcp_handle_r2t() to ensure it's not part of any list, otherwise a malicious R2T PDU might inject a loop in request list processing.
Signed-off-by: Hannes Reinecke hare@kernel.org Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/tcp.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c index 9f4f6464dee04..b882ee6ef40f6 100644 --- a/drivers/nvme/host/tcp.c +++ b/drivers/nvme/host/tcp.c @@ -452,7 +452,8 @@ nvme_tcp_fetch_request(struct nvme_tcp_queue *queue) return NULL; }
- list_del(&req->entry); + list_del_init(&req->entry); + init_llist_node(&req->lentry); return req; }
@@ -560,6 +561,8 @@ static int nvme_tcp_init_request(struct blk_mq_tag_set *set, req->queue = queue; nvme_req(rq)->ctrl = &ctrl->ctrl; nvme_req(rq)->cmd = &pdu->cmd; + init_llist_node(&req->lentry); + INIT_LIST_HEAD(&req->entry);
return 0; } @@ -764,6 +767,14 @@ static int nvme_tcp_handle_r2t(struct nvme_tcp_queue *queue, return -EPROTO; }
+ if (llist_on_list(&req->lentry) || + !list_empty(&req->entry)) { + dev_err(queue->ctrl->ctrl.device, + "req %d unexpected r2t while processing request\n", + rq->tag); + return -EPROTO; + } + req->pdu_len = 0; req->h2cdata_left = r2t_length; req->h2cdata_offset = r2t_offset; @@ -2641,6 +2652,8 @@ static void nvme_tcp_submit_async_event(struct nvme_ctrl *arg) ctrl->async_req.offset = 0; ctrl->async_req.curr_bio = NULL; ctrl->async_req.data_len = 0; + init_llist_node(&ctrl->async_req.lentry); + INIT_LIST_HEAD(&ctrl->async_req.entry);
nvme_tcp_queue_request(&ctrl->async_req, true, true); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai yukuai3@huawei.com
[ Upstream commit 2afe17794cfed5f80295b1b9facd66e6f65e5002 ]
It's supposed to be COUNTER_MAX / 2, not COUNTER_MAX.
Link: https://lore.kernel.org/linux-raid/20250524061320.370630-14-yukuai1@huaweicl... Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Christoph Hellwig hch@lst.de Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/md-bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c index 37b08f26c62f5..45dd3d9f01a8e 100644 --- a/drivers/md/md-bitmap.c +++ b/drivers/md/md-bitmap.c @@ -789,7 +789,7 @@ static int md_bitmap_new_disk_sb(struct bitmap *bitmap) * is a good choice? We choose COUNTER_MAX / 2 arbitrarily. */ write_behind = bitmap->mddev->bitmap_info.max_write_behind; - if (write_behind > COUNTER_MAX) + if (write_behind > COUNTER_MAX / 2) write_behind = COUNTER_MAX / 2; sb->write_behind = cpu_to_le32(write_behind); bitmap->mddev->bitmap_info.max_write_behind = write_behind;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifan Zhang yifan1.zhang@amd.com
[ Upstream commit 90237b16ec1d7afa16e2173cc9a664377214cdd9 ]
This patch is to fix a kfd_prcess ref leak.
Signed-off-by: Yifan Zhang yifan1.zhang@amd.com Reviewed-by: Philip Yang Philip.Yang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c index fecdb67940750..3a926eb82379b 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c @@ -1331,6 +1331,7 @@ void kfd_signal_poison_consumed_event(struct kfd_node *dev, u32 pasid) user_gpu_id = kfd_process_get_user_gpu_id(p, dev->id); if (unlikely(user_gpu_id == -EINVAL)) { WARN_ONCE(1, "Could not get user_gpu_id from dev->id:%x\n", dev->id); + kfd_unref_process(p); return; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David (Ming Qiang) Wu David.Wu3@amd.com
[ Upstream commit bf394d28548c3c0a01e113fdef20ddb6cd2df106 ]
The addition of register read-back in VCN v5.0.1 is intended to prevent potential race conditions.
Reviewed-by: Ruijing Dong ruijing.dong@amd.com Signed-off-by: David (Ming Qiang) Wu David.Wu3@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c index e0e84ef7f5686..9a142a21aaea8 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c @@ -809,6 +809,11 @@ static int vcn_v5_0_1_start(struct amdgpu_vcn_inst *vinst) WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS); + return 0; }
@@ -843,6 +848,11 @@ static void vcn_v5_0_1_stop_dpg_mode(struct amdgpu_vcn_inst *vinst) /* disable dynamic power gating mode */ WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 0, ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); + + /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS); }
/** @@ -918,6 +928,11 @@ static int vcn_v5_0_1_stop(struct amdgpu_vcn_inst *vinst) /* clear status */ WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS); + return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David (Ming Qiang) Wu David.Wu3@amd.com
[ Upstream commit a3810a5e37c58329aa2c7992f3172a423f4ae194 ]
The addition of register read-back in VCN v4.0.0 is intended to prevent potential race conditions.
Reviewed-by: Ruijing Dong ruijing.dong@amd.com Signed-off-by: David (Ming Qiang) Wu David.Wu3@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c index 1f777c125b00d..4a88a4d37aeeb 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c @@ -1122,6 +1122,11 @@ static int vcn_v4_0_start_dpg_mode(struct amdgpu_vcn_inst *vinst, bool indirect) ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT | VCN_RB1_DB_CTRL__EN_MASK);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, inst_idx, regUVD_STATUS); + return 0; }
@@ -1303,6 +1308,11 @@ static int vcn_v4_0_start(struct amdgpu_vcn_inst *vinst) WREG32_SOC15(VCN, i, regVCN_RB_ENABLE, tmp); fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, i, regUVD_STATUS); + return 0; }
@@ -1583,6 +1593,11 @@ static void vcn_v4_0_stop_dpg_mode(struct amdgpu_vcn_inst *vinst) /* disable dynamic power gating mode */ WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, regUVD_POWER_STATUS), 0, ~UVD_POWER_STATUS__UVD_PG_MODE_MASK); + + /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, inst_idx, regUVD_STATUS); }
/** @@ -1666,6 +1681,11 @@ static int vcn_v4_0_stop(struct amdgpu_vcn_inst *vinst) /* enable VCN power gating */ vcn_v4_0_enable_static_power_gating(vinst);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, i, regUVD_STATUS); + done: if (adev->pm.dpm_enabled) amdgpu_dpm_enable_vcn(adev, false, i);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David (Ming Qiang) Wu David.Wu3@amd.com
[ Upstream commit b7a4842a917e3a251b5a6aa1a21a5daf6d396ef3 ]
The addition of register read-back in VCN v3.0 is intended to prevent potential race conditions.
Reviewed-by: Ruijing Dong ruijing.dong@amd.com Signed-off-by: David (Ming Qiang) Wu David.Wu3@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c index 0b19f0ab4480d..9fb0d53805892 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c @@ -1173,6 +1173,11 @@ static int vcn_v3_0_start_dpg_mode(struct amdgpu_vcn_inst *vinst, bool indirect) WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, inst_idx, mmUVD_STATUS); + return 0; }
@@ -1360,6 +1365,11 @@ static int vcn_v3_0_start(struct amdgpu_vcn_inst *vinst) fw_shared->multi_queue.encode_lowlatency_queue_mode &= cpu_to_le32(~FW_QUEUE_RING_RESET); }
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, i, mmUVD_STATUS); + return 0; }
@@ -1602,6 +1612,11 @@ static int vcn_v3_0_stop_dpg_mode(struct amdgpu_vcn_inst *vinst) WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0, ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, inst_idx, mmUVD_STATUS); + return 0; }
@@ -1674,6 +1689,11 @@ static int vcn_v3_0_stop(struct amdgpu_vcn_inst *vinst) /* enable VCN power gating */ vcn_v3_0_enable_static_power_gating(vinst);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, i, mmUVD_STATUS); + done: if (adev->pm.dpm_enabled) amdgpu_dpm_enable_vcn(adev, false, i);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David (Ming Qiang) Wu David.Wu3@amd.com
[ Upstream commit d9e688b9148bb23629d32017344888dd67ec2ab1 ]
The addition of register read-back in VCN v2.5 is intended to prevent potential race conditions.
Reviewed-by: Ruijing Dong ruijing.dong@amd.com Signed-off-by: David (Ming Qiang) Wu David.Wu3@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c index 3eec1b8feaeea..58b527a6b795f 100644 --- a/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c @@ -1158,6 +1158,11 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_vcn_inst *vinst, bool indirect) WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, inst_idx, mmUVD_STATUS); + return 0; }
@@ -1343,6 +1348,11 @@ static int vcn_v2_5_start(struct amdgpu_vcn_inst *vinst) WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4); fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, i, mmUVD_STATUS); + return 0; }
@@ -1569,6 +1579,11 @@ static int vcn_v2_5_stop_dpg_mode(struct amdgpu_vcn_inst *vinst) WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0, ~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, inst_idx, mmUVD_STATUS); + return 0; }
@@ -1635,6 +1650,10 @@ static int vcn_v2_5_stop(struct amdgpu_vcn_inst *vinst) UVD_POWER_STATUS__UVD_POWER_STATUS_MASK, ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
+ /* Keeping one read-back to ensure all register writes are done, + * otherwise it may introduce race conditions. + */ + RREG32_SOC15(VCN, i, mmUVD_STATUS); done: if (adev->pm.dpm_enabled) amdgpu_dpm_enable_vcn(adev, false, i);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linggang Zeng linggang.zeng@easystack.cn
[ Upstream commit 1e46ed947ec658f89f1a910d880cd05e42d3763e ]
1. LINE#1794 - LINE#1887 is some codes about function of bch_cache_set_alloc(). 2. LINE#2078 - LINE#2142 is some codes about function of register_cache_set(). 3. register_cache_set() will call bch_cache_set_alloc() in LINE#2098.
1794 struct cache_set *bch_cache_set_alloc(struct cache_sb *sb) 1795 { ... 1860 if (!(c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL)) || 1861 mempool_init_slab_pool(&c->search, 32, bch_search_cache) || 1862 mempool_init_kmalloc_pool(&c->bio_meta, 2, 1863 sizeof(struct bbio) + sizeof(struct bio_vec) * 1864 bucket_pages(c)) || 1865 mempool_init_kmalloc_pool(&c->fill_iter, 1, iter_size) || 1866 bioset_init(&c->bio_split, 4, offsetof(struct bbio, bio), 1867 BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER) || 1868 !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) || 1869 !(c->moving_gc_wq = alloc_workqueue("bcache_gc", 1870 WQ_MEM_RECLAIM, 0)) || 1871 bch_journal_alloc(c) || 1872 bch_btree_cache_alloc(c) || 1873 bch_open_buckets_alloc(c) || 1874 bch_bset_sort_state_init(&c->sort, ilog2(c->btree_pages))) 1875 goto err; ^^^^^^^^ 1876 ... 1883 return c; 1884 err: 1885 bch_cache_set_unregister(c); ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 1886 return NULL; 1887 } ... 2078 static const char *register_cache_set(struct cache *ca) 2079 { ... 2098 c = bch_cache_set_alloc(&ca->sb); 2099 if (!c) 2100 return err; ^^^^^^^^^^ ... 2128 ca->set = c; 2129 ca->set->cache[ca->sb.nr_this_dev] = ca; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ... 2138 return NULL; 2139 err: 2140 bch_cache_set_unregister(c); 2141 return err; 2142 }
(1) If LINE#1860 - LINE#1874 is true, then do 'goto err'(LINE#1875) and call bch_cache_set_unregister()(LINE#1885). (2) As (1) return NULL(LINE#1886), LINE#2098 - LINE#2100 would return. (3) As (2) has returned, LINE#2128 - LINE#2129 would do *not* give the value to c->cache[], it means that c->cache[] is NULL.
LINE#1624 - LINE#1665 is some codes about function of cache_set_flush(). As (1), in LINE#1885 call bch_cache_set_unregister() ---> bch_cache_set_stop() ---> closure_queue() -.-> cache_set_flush() (as below LINE#1624)
1624 static void cache_set_flush(struct closure *cl) 1625 { ... 1654 for_each_cache(ca, c, i) 1655 if (ca->alloc_thread) ^^ 1656 kthread_stop(ca->alloc_thread); ... 1665 }
(4) In LINE#1655 ca is NULL(see (3)) in cache_set_flush() then the kernel crash occurred as below: [ 846.712887] bcache: register_cache() error drbd6: cannot allocate memory [ 846.713242] bcache: register_bcache() error : failed to register device [ 846.713336] bcache: cache_set_free() Cache set 2f84bdc1-498a-4f2f-98a7-01946bf54287 unregistered [ 846.713768] BUG: unable to handle kernel NULL pointer dereference at 00000000000009f8 [ 846.714790] PGD 0 P4D 0 [ 846.715129] Oops: 0000 [#1] SMP PTI [ 846.715472] CPU: 19 PID: 5057 Comm: kworker/19:16 Kdump: loaded Tainted: G OE --------- - - 4.18.0-147.5.1.el8_1.5es.3.x86_64 #1 [ 846.716082] Hardware name: ESPAN GI-25212/X11DPL-i, BIOS 2.1 06/15/2018 [ 846.716451] Workqueue: events cache_set_flush [bcache] [ 846.716808] RIP: 0010:cache_set_flush+0xc9/0x1b0 [bcache] [ 846.717155] Code: 00 4c 89 a5 b0 03 00 00 48 8b 85 68 f6 ff ff a8 08 0f 84 88 00 00 00 31 db 66 83 bd 3c f7 ff ff 00 48 8b 85 48 ff ff ff 74 28 <48> 8b b8 f8 09 00 00 48 85 ff 74 05 e8 b6 58 a2 e1 0f b7 95 3c f7 [ 846.718026] RSP: 0018:ffffb56dcf85fe70 EFLAGS: 00010202 [ 846.718372] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 846.718725] RDX: 0000000000000001 RSI: 0000000040000001 RDI: 0000000000000000 [ 846.719076] RBP: ffffa0ccc0f20df8 R08: ffffa0ce1fedb118 R09: 000073746e657665 [ 846.719428] R10: 8080808080808080 R11: 0000000000000000 R12: ffffa0ce1fee8700 [ 846.719779] R13: ffffa0ccc0f211a8 R14: ffffa0cd1b902840 R15: ffffa0ccc0f20e00 [ 846.720132] FS: 0000000000000000(0000) GS:ffffa0ce1fec0000(0000) knlGS:0000000000000000 [ 846.720726] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 846.721073] CR2: 00000000000009f8 CR3: 00000008ba00a005 CR4: 00000000007606e0 [ 846.721426] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 846.721778] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 846.722131] PKRU: 55555554 [ 846.722467] Call Trace: [ 846.722814] process_one_work+0x1a7/0x3b0 [ 846.723157] worker_thread+0x30/0x390 [ 846.723501] ? create_worker+0x1a0/0x1a0 [ 846.723844] kthread+0x112/0x130 [ 846.724184] ? kthread_flush_work_fn+0x10/0x10 [ 846.724535] ret_from_fork+0x35/0x40
Now, check whether that ca is NULL in LINE#1655 to fix the issue.
Signed-off-by: Linggang Zeng linggang.zeng@easystack.cn Signed-off-by: Mingzhe Zou mingzhe.zou@easystack.cn Signed-off-by: Coly Li colyli@kernel.org Link: https://lore.kernel.org/r/20250527051601.74407-2-colyli@kernel.org Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/bcache/super.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 813b38aec3e4e..37f5e31618c0a 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1733,7 +1733,12 @@ static CLOSURE_CALLBACK(cache_set_flush) mutex_unlock(&b->write_lock); }
- if (ca->alloc_thread) + /* + * If the register_cache_set() call to bch_cache_set_alloc() failed, + * ca has not been assigned a value and return error. + * So we need check ca is not NULL during bch_cache_set_unregister(). + */ + if (ca && ca->alloc_thread) kthread_stop(ca->alloc_thread);
if (c->journal.cur) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang Philip.Yang@amd.com
[ Upstream commit a359288ccb4dd8edb086e7de8fdf6e36f544c922 ]
To unmap and free seq64 memory when drm node close to free vm, if there is signal accepted, then taking vm lock failed and leaking seq64 va mapping, and then dmesg has error log "still active bo inside vm".
Change to use uninterruptible lock fix the mapping leaking and no dmesg error log.
Signed-off-by: Philip Yang Philip.Yang@amd.com Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c index e22cb2b5cd926..dba8051b8c14b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c @@ -133,7 +133,7 @@ void amdgpu_seq64_unmap(struct amdgpu_device *adev, struct amdgpu_fpriv *fpriv)
vm = &fpriv->vm;
- drm_exec_init(&exec, DRM_EXEC_INTERRUPTIBLE_WAIT, 0); + drm_exec_init(&exec, 0, 0); drm_exec_until_all_locked(&exec) { r = amdgpu_vm_lock_pd(vm, &exec, 0); if (likely(!r))
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lin.Cao lincao12@amd.com
[ Upstream commit 471db2c2d4f80ee94225a1ef246e4f5011733e50 ]
When an entity from application B is killed, drm_sched_entity_kill() removes all jobs belonging to that entity through drm_sched_entity_kill_jobs_work(). If application A's job depends on a scheduled fence from application B's job, and that fence is not properly signaled during the killing process, application A's dependency cannot be cleared.
This leads to application A hanging indefinitely while waiting for a dependency that will never be resolved. Fix this issue by ensuring that scheduled fences are properly signaled when an entity is killed, allowing dependent applications to continue execution.
Signed-off-by: Lin.Cao lincao12@amd.com Reviewed-by: Philipp Stanner phasta@kernel.org Signed-off-by: Christian König christian.koenig@amd.com Link: https://lore.kernel.org/r/20250515020713.1110476-1-lincao12@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/scheduler/sched_entity.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/scheduler/sched_entity.c b/drivers/gpu/drm/scheduler/sched_entity.c index bd39db7bb2408..e671aa2417206 100644 --- a/drivers/gpu/drm/scheduler/sched_entity.c +++ b/drivers/gpu/drm/scheduler/sched_entity.c @@ -176,6 +176,7 @@ static void drm_sched_entity_kill_jobs_work(struct work_struct *wrk) { struct drm_sched_job *job = container_of(wrk, typeof(*job), work);
+ drm_sched_fence_scheduled(job->s_fence, NULL); drm_sched_fence_finished(job->s_fence, -ESRCH); WARN_ON(job->s_fence->parent); job->sched->ops->free_job(job);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 886a446b76afddfad307488e95e87f23a08ffd51 ]
On x86_32 s64 fields are only 32-bit aligned. Hence force the alignment of the field and padding in the structure by using aligned_s64 instead.
Reviewed-by: David Lechner dlechner@baylibre.com Link: https://patch.msgid.link/20250413103443.2420727-19-jic23@kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/pressure/zpa2326.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iio/pressure/zpa2326.c b/drivers/iio/pressure/zpa2326.c index 9db1c94dfc188..b2e04368532a0 100644 --- a/drivers/iio/pressure/zpa2326.c +++ b/drivers/iio/pressure/zpa2326.c @@ -582,7 +582,7 @@ static int zpa2326_fill_sample_buffer(struct iio_dev *indio_dev, struct { u32 pressure; u16 temperature; - u64 timestamp; + aligned_s64 timestamp; } sample; int err;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniele Palmas dnlplm@gmail.com
[ Upstream commit 6348f62ef7ecc5855b710a7d4ea682425c38bb80 ]
Add SDX35 based modem Telit FN920C04.
$ lspci -vv 01:00.0 Unassigned class [ff00]: Qualcomm Device 011a Subsystem: Device 1c5d:2020
Signed-off-by: Daniele Palmas dnlplm@gmail.com Signed-off-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://patch.msgid.link/20250401093458.2953872-1-dnlplm@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/bus/mhi/host/pci_generic.c | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/drivers/bus/mhi/host/pci_generic.c b/drivers/bus/mhi/host/pci_generic.c index 03aa887952098..059cfd77382f0 100644 --- a/drivers/bus/mhi/host/pci_generic.c +++ b/drivers/bus/mhi/host/pci_generic.c @@ -782,6 +782,42 @@ static const struct mhi_pci_dev_info mhi_telit_fe990a_info = { .mru_default = 32768, };
+static const struct mhi_channel_config mhi_telit_fn920c04_channels[] = { + MHI_CHANNEL_CONFIG_UL_SBL(2, "SAHARA", 32, 0), + MHI_CHANNEL_CONFIG_DL_SBL(3, "SAHARA", 32, 0), + MHI_CHANNEL_CONFIG_UL(4, "DIAG", 64, 1), + MHI_CHANNEL_CONFIG_DL(5, "DIAG", 64, 1), + MHI_CHANNEL_CONFIG_UL(14, "QMI", 32, 0), + MHI_CHANNEL_CONFIG_DL(15, "QMI", 32, 0), + MHI_CHANNEL_CONFIG_UL(32, "DUN", 32, 0), + MHI_CHANNEL_CONFIG_DL(33, "DUN", 32, 0), + MHI_CHANNEL_CONFIG_UL_FP(34, "FIREHOSE", 32, 0), + MHI_CHANNEL_CONFIG_DL_FP(35, "FIREHOSE", 32, 0), + MHI_CHANNEL_CONFIG_UL(92, "DUN2", 32, 1), + MHI_CHANNEL_CONFIG_DL(93, "DUN2", 32, 1), + MHI_CHANNEL_CONFIG_HW_UL(100, "IP_HW0", 128, 2), + MHI_CHANNEL_CONFIG_HW_DL(101, "IP_HW0", 128, 3), +}; + +static const struct mhi_controller_config modem_telit_fn920c04_config = { + .max_channels = 128, + .timeout_ms = 50000, + .num_channels = ARRAY_SIZE(mhi_telit_fn920c04_channels), + .ch_cfg = mhi_telit_fn920c04_channels, + .num_events = ARRAY_SIZE(mhi_telit_fn990_events), + .event_cfg = mhi_telit_fn990_events, +}; + +static const struct mhi_pci_dev_info mhi_telit_fn920c04_info = { + .name = "telit-fn920c04", + .config = &modem_telit_fn920c04_config, + .bar_num = MHI_PCI_DEFAULT_BAR_NUM, + .dma_data_width = 32, + .sideband_wake = false, + .mru_default = 32768, + .edl_trigger = true, +}; + static const struct mhi_pci_dev_info mhi_netprisma_lcur57_info = { .name = "netprisma-lcur57", .edl = "qcom/prog_firehose_sdx24.mbn", @@ -806,6 +842,9 @@ static const struct mhi_pci_dev_info mhi_netprisma_fcun69_info = { static const struct pci_device_id mhi_pci_id_table[] = { {PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0116), .driver_data = (kernel_ulong_t) &mhi_qcom_sa8775p_info }, + /* Telit FN920C04 (sdx35) */ + {PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x011a, 0x1c5d, 0x2020), + .driver_data = (kernel_ulong_t) &mhi_telit_fn920c04_info }, { PCI_DEVICE(PCI_VENDOR_ID_QCOM, 0x0304), .driver_data = (kernel_ulong_t) &mhi_qcom_sdx24_info }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x0306, PCI_VENDOR_ID_QCOM, 0x010c),
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sami Tolvanen samitolvanen@google.com
[ Upstream commit 674d03f6bd6b0f8327f1a4920ff5893557facfbd ]
With CONFIG_GENDWARFKSYMS, um builds fail due to missing prototypes in asm/asm-prototypes.h. Add declarations for cmpxchg8b_emu and the exported checksum functions, including csum_partial_copy_generic as it's also exported.
Cc: Masahiro Yamada masahiroy@kernel.org Cc: linux-kbuild@vger.kernel.org Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202503251216.lE4t9Ikj-lkp@intel.com/ Signed-off-by: Sami Tolvanen samitolvanen@google.com Link: https://patch.msgid.link/20250326190500.847236-2-samitolvanen@google.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/include/asm/asm-prototypes.h | 5 +++++ arch/x86/um/asm/checksum.h | 3 +++ 2 files changed, 8 insertions(+)
diff --git a/arch/um/include/asm/asm-prototypes.h b/arch/um/include/asm/asm-prototypes.h index 5898a26daa0dd..408b31d591279 100644 --- a/arch/um/include/asm/asm-prototypes.h +++ b/arch/um/include/asm/asm-prototypes.h @@ -1 +1,6 @@ #include <asm-generic/asm-prototypes.h> +#include <asm/checksum.h> + +#ifdef CONFIG_UML_X86 +extern void cmpxchg8b_emu(void); +#endif diff --git a/arch/x86/um/asm/checksum.h b/arch/x86/um/asm/checksum.h index b07824500363f..ddc144657efad 100644 --- a/arch/x86/um/asm/checksum.h +++ b/arch/x86/um/asm/checksum.h @@ -20,6 +20,9 @@ */ extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+/* Do not call this directly. Declared for export type visibility. */ +extern __visible __wsum csum_partial_copy_generic(const void *src, void *dst, int len); + /** * csum_fold - Fold and invert a 32bit checksum. * sum: 32bit unfolded sum
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg benjamin.berg@intel.com
[ Upstream commit 6767e8784cd2e8b386a62330ea6864949d983a3e ]
Segfaults can occur at times where the mmap lock cannot be taken. If that happens the segfault handler may not be able to take the mmap lock.
Fix the code to use the same approach as most other architectures. Unfortunately, this requires copying code from mm/memory.c and modifying it slightly as UML does not have exception tables.
Signed-off-by: Benjamin Berg benjamin.berg@intel.com Link: https://patch.msgid.link/20250408074524.300153-2-benjamin@sipsolutions.net Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/kernel/trap.c | 129 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 117 insertions(+), 12 deletions(-)
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index ef2272e92a432..8a2e68d07de61 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -18,6 +18,122 @@ #include <skas.h> #include <arch.h>
+/* + * NOTE: UML does not have exception tables. As such, this is almost a copy + * of the code in mm/memory.c, only adjusting the logic to simply check whether + * we are coming from the kernel instead of doing an additional lookup in the + * exception table. + * We can do this simplification because we never get here if the exception was + * fixable. + */ +static inline bool get_mmap_lock_carefully(struct mm_struct *mm, bool is_user) +{ + if (likely(mmap_read_trylock(mm))) + return true; + + if (!is_user) + return false; + + return !mmap_read_lock_killable(mm); +} + +static inline bool mmap_upgrade_trylock(struct mm_struct *mm) +{ + /* + * We don't have this operation yet. + * + * It should be easy enough to do: it's basically a + * atomic_long_try_cmpxchg_acquire() + * from RWSEM_READER_BIAS -> RWSEM_WRITER_LOCKED, but + * it also needs the proper lockdep magic etc. + */ + return false; +} + +static inline bool upgrade_mmap_lock_carefully(struct mm_struct *mm, bool is_user) +{ + mmap_read_unlock(mm); + if (!is_user) + return false; + + return !mmap_write_lock_killable(mm); +} + +/* + * Helper for page fault handling. + * + * This is kind of equivalend to "mmap_read_lock()" followed + * by "find_extend_vma()", except it's a lot more careful about + * the locking (and will drop the lock on failure). + * + * For example, if we have a kernel bug that causes a page + * fault, we don't want to just use mmap_read_lock() to get + * the mm lock, because that would deadlock if the bug were + * to happen while we're holding the mm lock for writing. + * + * So this checks the exception tables on kernel faults in + * order to only do this all for instructions that are actually + * expected to fault. + * + * We can also actually take the mm lock for writing if we + * need to extend the vma, which helps the VM layer a lot. + */ +static struct vm_area_struct * +um_lock_mm_and_find_vma(struct mm_struct *mm, + unsigned long addr, bool is_user) +{ + struct vm_area_struct *vma; + + if (!get_mmap_lock_carefully(mm, is_user)) + return NULL; + + vma = find_vma(mm, addr); + if (likely(vma && (vma->vm_start <= addr))) + return vma; + + /* + * Well, dang. We might still be successful, but only + * if we can extend a vma to do so. + */ + if (!vma || !(vma->vm_flags & VM_GROWSDOWN)) { + mmap_read_unlock(mm); + return NULL; + } + + /* + * We can try to upgrade the mmap lock atomically, + * in which case we can continue to use the vma + * we already looked up. + * + * Otherwise we'll have to drop the mmap lock and + * re-take it, and also look up the vma again, + * re-checking it. + */ + if (!mmap_upgrade_trylock(mm)) { + if (!upgrade_mmap_lock_carefully(mm, is_user)) + return NULL; + + vma = find_vma(mm, addr); + if (!vma) + goto fail; + if (vma->vm_start <= addr) + goto success; + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto fail; + } + + if (expand_stack_locked(vma, addr)) + goto fail; + +success: + mmap_write_downgrade(mm); + return vma; + +fail: + mmap_write_unlock(mm); + return NULL; +} + /* * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by * segv(). @@ -44,21 +160,10 @@ int handle_page_fault(unsigned long address, unsigned long ip, if (is_user) flags |= FAULT_FLAG_USER; retry: - mmap_read_lock(mm); - vma = find_vma(mm, address); - if (!vma) - goto out; - if (vma->vm_start <= address) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto out; - if (is_user && !ARCH_IS_STACKGROW(address)) - goto out; - vma = expand_stack(mm, address); + vma = um_lock_mm_and_find_vma(mm, address, is_user); if (!vma) goto out_nosemaphore;
-good_area: *code_out = SEGV_ACCERR; if (is_write) { if (!(vma->vm_flags & VM_WRITE))
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rengarajan S rengarajan.s@microchip.com
[ Upstream commit c40b91e38eb8d4489def095d62ab476d45871323 ]
Systems that issue PCIe hot reset requests during a suspend/resume cycle cause PCI1XXXX device revisions prior to C0 to get its UART configuration registers reset to hardware default values. This results in device inaccessibility and data transfer failures. Starting with Revision C0, support was added in the device hardware (via the Hot Reset Disable Bit) to allow resetting only the PCIe interface and its associated logic, but preserving the UART configuration during a hot reset. This patch enables the hot reset disable feature during suspend/ resume for C0 and later revisions of the device.
Signed-off-by: Rengarajan S rengarajan.s@microchip.com Reviewed-by: Jiri Slaby jirislaby@kernel.org Link: https://lore.kernel.org/r/20250425145500.29036-1-rengarajan.s@microchip.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/8250/8250_pci1xxxx.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_pci1xxxx.c b/drivers/tty/serial/8250/8250_pci1xxxx.c index e9c51d4e447dd..4c149db846925 100644 --- a/drivers/tty/serial/8250/8250_pci1xxxx.c +++ b/drivers/tty/serial/8250/8250_pci1xxxx.c @@ -115,6 +115,7 @@
#define UART_RESET_REG 0x94 #define UART_RESET_D3_RESET_DISABLE BIT(16) +#define UART_RESET_HOT_RESET_DISABLE BIT(17)
#define UART_BURST_STATUS_REG 0x9C #define UART_TX_BURST_FIFO 0xA0 @@ -620,6 +621,10 @@ static int pci1xxxx_suspend(struct device *dev) }
data = readl(p + UART_RESET_REG); + + if (priv->dev_rev >= 0xC0) + data |= UART_RESET_HOT_RESET_DISABLE; + writel(data | UART_RESET_D3_RESET_DISABLE, p + UART_RESET_REG);
if (wakeup) @@ -647,7 +652,12 @@ static int pci1xxxx_resume(struct device *dev) }
data = readl(p + UART_RESET_REG); + + if (priv->dev_rev >= 0xC0) + data &= ~UART_RESET_HOT_RESET_DISABLE; + writel(data & ~UART_RESET_D3_RESET_DISABLE, p + UART_RESET_REG); + iounmap(p);
for (i = 0; i < priv->nr; i++) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Clark james.clark@linaro.org
[ Upstream commit a4e65842e1142aa18ef36113fbd81d614eaefe5a ]
The use of the whole register and == could break the claim mechanism if any of the other bits are used in the future. The referenced doc "PSCI - ARM DEN 0022D" also says to only read and clear the bottom two bits.
Use FIELD_GET() to extract only the relevant part.
Reviewed-by: Leo Yan leo.yan@arm.com Reviewed-by: Yeoreum Yun yeoreum.yun@arm.com Signed-off-by: James Clark james.clark@linaro.org Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Link: https://lore.kernel.org/r/20250325-james-coresight-claim-tags-v4-2-dfbd3822b... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hwtracing/coresight/coresight-core.c | 3 ++- drivers/hwtracing/coresight/coresight-priv.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c index d3523f0262af8..dfcb30da2e20b 100644 --- a/drivers/hwtracing/coresight/coresight-core.c +++ b/drivers/hwtracing/coresight/coresight-core.c @@ -131,7 +131,8 @@ coresight_find_out_connection(struct coresight_device *csdev,
static inline u32 coresight_read_claim_tags(struct coresight_device *csdev) { - return csdev_access_relaxed_read32(&csdev->access, CORESIGHT_CLAIMCLR); + return FIELD_GET(CORESIGHT_CLAIM_MASK, + csdev_access_relaxed_read32(&csdev->access, CORESIGHT_CLAIMCLR)); }
static inline bool coresight_is_claimed_self_hosted(struct coresight_device *csdev) diff --git a/drivers/hwtracing/coresight/coresight-priv.h b/drivers/hwtracing/coresight/coresight-priv.h index 82644aff8d2b7..38bb4e8b50ef6 100644 --- a/drivers/hwtracing/coresight/coresight-priv.h +++ b/drivers/hwtracing/coresight/coresight-priv.h @@ -35,6 +35,7 @@ extern const struct device_type coresight_dev_type[]; * Coresight device CLAIM protocol. * See PSCI - ARM DEN 0022D, Section: 6.8.1 Debug and Trace save and restore. */ +#define CORESIGHT_CLAIM_MASK GENMASK(1, 0) #define CORESIGHT_CLAIM_SELF_HOSTED BIT(1)
#define TIMEOUT_US 100
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik m.grzeschik@pengutronix.de
[ Upstream commit af076a41f8a28faf9ceb9dd2d88aef2c202ef39a ]
It is possible that the gadget will be disabled, while the udc is suspended. When enabling the udc in that case, the clock gating will not be enabled again. Leaving the phy unclocked. Even when the udc is not enabled, connecting this powered but not clocked phy leads to enumeration errors on the host side.
To ensure that the clock gating will be in an valid state, we ensure that the clock gating will be enabled before stopping the udc.
Signed-off-by: Michael Grzeschik m.grzeschik@pengutronix.de Acked-by: Minas Harutyunyan hminas@synopsys.com Link: https://lore.kernel.org/r/20250417-dwc2_clock_gating-v1-1-8ea7c4d53d73@pengu... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc2/gadget.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c index 300ea4969f0cf..f323fb5597b32 100644 --- a/drivers/usb/dwc2/gadget.c +++ b/drivers/usb/dwc2/gadget.c @@ -4604,6 +4604,12 @@ static int dwc2_hsotg_udc_stop(struct usb_gadget *gadget) if (!hsotg) return -ENODEV;
+ /* Exit clock gating when driver is stopped. */ + if (hsotg->params.power_down == DWC2_POWER_DOWN_PARAM_NONE && + hsotg->bus_suspended && !hsotg->params.no_clock_gating) { + dwc2_gadget_exit_clock_gating(hsotg, 0); + } + /* all endpoints should be shutdown */ for (ep = 1; ep < hsotg->num_of_eps; ep++) { if (hsotg->eps_in[ep])
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Purva Yeshi purvayeshi550@gmail.com
[ Upstream commit e5cdb098a3cb165d52282ffc3a6448642953ea13 ]
Fix Smatch-detected issue: drivers/iio/adc/ad_sigma_delta.c:604 ad_sd_trigger_handler() error: uninitialized symbol 'status_pos'.
The variable `status_pos` was only initialized in specific switch cases (1, 2, 3, 4), which could leave it uninitialized if `reg_size` had an unexpected value.
Fix by adding a default case to the switch block to catch unexpected values of `reg_size`. Use `dev_err_ratelimited()` for error logging and `goto irq_handled` instead of returning early.
Signed-off-by: Purva Yeshi purvayeshi550@gmail.com Link: https://patch.msgid.link/20250410170408.8585-1-purvayeshi550@gmail.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad_sigma_delta.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/iio/adc/ad_sigma_delta.c b/drivers/iio/adc/ad_sigma_delta.c index 6c37f8e21120b..4c5f8d29a559f 100644 --- a/drivers/iio/adc/ad_sigma_delta.c +++ b/drivers/iio/adc/ad_sigma_delta.c @@ -587,6 +587,10 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p) * byte set to zero. */ ad_sd_read_reg_raw(sigma_delta, data_reg, transfer_size, &data[1]); break; + + default: + dev_err_ratelimited(&indio_dev->dev, "Unsupported reg_size: %u\n", reg_size); + goto irq_handled; }
/*
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Angelo Dureghello adureghello@baylibre.com
[ Upstream commit 029035636de37395124a602c830152ef39a35fab ]
Add validity check on CNTRL_X channels (valid as 0 to 15).
Reviewed-by: Nuno Sá nuno.sa@analog.com Signed-off-by: Angelo Dureghello adureghello@baylibre.com Link: https://patch.msgid.link/20250409-wip-bl-ad3552r-fixes-v5-1-fb429c3a6515@bay... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/dac/adi-axi-dac.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/drivers/iio/dac/adi-axi-dac.c b/drivers/iio/dac/adi-axi-dac.c index 05b374e137d35..fd93ed3132835 100644 --- a/drivers/iio/dac/adi-axi-dac.c +++ b/drivers/iio/dac/adi-axi-dac.c @@ -84,6 +84,7 @@ #define AXI_DAC_CHAN_CNTRL_7_REG(c) (0x0418 + (c) * 0x40) #define AXI_DAC_CHAN_CNTRL_7_DATA_SEL GENMASK(3, 0)
+#define AXI_DAC_CHAN_CNTRL_MAX 15 #define AXI_DAC_RD_ADDR(x) (BIT(7) | (x))
/* 360 degrees in rad */ @@ -186,6 +187,9 @@ static int __axi_dac_frequency_get(struct axi_dac_state *st, unsigned int chan, u32 reg, raw; int ret;
+ if (chan > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; + if (!st->dac_clk) { dev_err(st->dev, "Sampling rate is 0...\n"); return -EINVAL; @@ -230,6 +234,9 @@ static int axi_dac_scale_get(struct axi_dac_state *st, int ret, vals[2]; u32 reg, raw;
+ if (chan->channel > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; + if (tone_2) reg = AXI_DAC_CHAN_CNTRL_3_REG(chan->channel); else @@ -264,6 +271,9 @@ static int axi_dac_phase_get(struct axi_dac_state *st, u32 reg, raw, phase; int ret, vals[2];
+ if (chan->channel > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; + if (tone_2) reg = AXI_DAC_CHAN_CNTRL_4_REG(chan->channel); else @@ -291,6 +301,9 @@ static int __axi_dac_frequency_set(struct axi_dac_state *st, unsigned int chan, u16 raw; int ret;
+ if (chan > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; + if (!sample_rate || freq > sample_rate / 2) { dev_err(st->dev, "Invalid frequency(%u) dac_clk(%llu)\n", freq, sample_rate); @@ -342,6 +355,9 @@ static int axi_dac_scale_set(struct axi_dac_state *st, u32 raw = 0, reg; int ret;
+ if (chan->channel > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; + ret = iio_str_to_fixpoint(buf, 100000, &integer, &frac); if (ret) return ret; @@ -385,6 +401,9 @@ static int axi_dac_phase_set(struct axi_dac_state *st, u32 raw, reg; int ret;
+ if (chan->channel > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; + ret = iio_str_to_fixpoint(buf, 100000, &integer, &frac); if (ret) return ret; @@ -493,6 +512,9 @@ static int axi_dac_data_source_set(struct iio_backend *back, unsigned int chan, { struct axi_dac_state *st = iio_backend_get_priv(back);
+ if (chan > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; + switch (data) { case IIO_BACKEND_INTERNAL_CONTINUOUS_WAVE: return regmap_update_bits(st->regmap, @@ -521,6 +543,8 @@ static int axi_dac_set_sample_rate(struct iio_backend *back, unsigned int chan, unsigned int freq; int ret, tone;
+ if (chan > AXI_DAC_CHAN_CNTRL_MAX) + return -EINVAL; if (!sample_rate) return -EINVAL; if (st->reg_config & AXI_DAC_CONFIG_DDS_DISABLE)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Heidelberg david@ixit.cz
[ Upstream commit c0461f8e842495041c18b2c67647501d55c17441 ]
If regmap_write() fails in al3000a_init(), al3000a_set_pwr_off is not called.
In order to avoid such a situation, move the devm_add_action_or_reset() which calls al3000a_set_pwr_off right after a successful al3000a_set_pwr_on.
Signed-off-by: David Heidelberg david@ixit.cz Link: https://patch.msgid.link/20250402-al3010-iio-regmap-v4-2-d189bea87261@ixit.c... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/light/al3000a.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/light/al3000a.c b/drivers/iio/light/al3000a.c index e2fbb1270040f..6d5115b2a06c5 100644 --- a/drivers/iio/light/al3000a.c +++ b/drivers/iio/light/al3000a.c @@ -85,12 +85,17 @@ static void al3000a_set_pwr_off(void *_data)
static int al3000a_init(struct al3000a_data *data) { + struct device *dev = regmap_get_device(data->regmap); int ret;
ret = al3000a_set_pwr_on(data); if (ret) return ret;
+ ret = devm_add_action_or_reset(dev, al3000a_set_pwr_off, data); + if (ret) + return dev_err_probe(dev, ret, "failed to add action\n"); + ret = regmap_write(data->regmap, AL3000A_REG_SYSTEM, AL3000A_CONFIG_RESET); if (ret) return ret; @@ -157,10 +162,6 @@ static int al3000a_probe(struct i2c_client *client) if (ret) return dev_err_probe(dev, ret, "failed to init ALS\n");
- ret = devm_add_action_or_reset(dev, al3000a_set_pwr_off, data); - if (ret) - return dev_err_probe(dev, ret, "failed to add action\n"); - return devm_iio_device_register(dev, indio_dev); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner dlechner@baylibre.com
[ Upstream commit 4d71bf6021818a039a534c5954acefdfc4d6962c ]
Add missing error check in ad7606B_sw_mode_config().
Reviewed-by: Nuno Sá nuno.sa@analog.com Signed-off-by: David Lechner dlechner@baylibre.com Link: https://patch.msgid.link/20250318-iio-adc-ad7606-improvements-v2-2-4b6054277... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7606_spi.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/iio/adc/ad7606_spi.c b/drivers/iio/adc/ad7606_spi.c index b37458ce3c708..5553a44ff83bc 100644 --- a/drivers/iio/adc/ad7606_spi.c +++ b/drivers/iio/adc/ad7606_spi.c @@ -174,11 +174,13 @@ static int ad7616_sw_mode_config(struct iio_dev *indio_dev) static int ad7606B_sw_mode_config(struct iio_dev *indio_dev) { struct ad7606_state *st = iio_priv(indio_dev); + int ret;
/* Configure device spi to output on a single channel */ - st->bops->reg_write(st, - AD7606_CONFIGURATION_REGISTER, - AD7606_SINGLE_DOUT); + ret = st->bops->reg_write(st, AD7606_CONFIGURATION_REGISTER, + AD7606_SINGLE_DOUT); + if (ret) + return ret;
/* * Scale can be configured individually for each channel
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Lixu lixu.zhang@intel.com
[ Upstream commit ad02ca57e44e9936fca5095840fad9d4b47c5559 ]
On Intel platforms, the HID_USAGE_SENSOR_HUMAN_PROXIMITY report size is 16 bits. This patch adds support for handling 16-bit report sizes for the HID_USAGE_SENSOR_HUMAN_PROXIMITY usage in the HID sensor proximity driver.
Previously, the driver only supported 8-bit and 32-bit report sizes. With this change, the driver can now correctly process 16-bit proximity data, ensuring accurate human presence detection on platforms where this report size is used.
Signed-off-by: Zhang Lixu lixu.zhang@intel.com Acked-by: Srinivas Pandruvada srinivas.pandruvada@linux.intel.com Link: https://patch.msgid.link/20250317013634.4117399-1-lixu.zhang@intel.com Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/light/hid-sensor-prox.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/iio/light/hid-sensor-prox.c b/drivers/iio/light/hid-sensor-prox.c index 4c65b32d34ce4..46f788b0bc3e2 100644 --- a/drivers/iio/light/hid-sensor-prox.c +++ b/drivers/iio/light/hid-sensor-prox.c @@ -215,6 +215,9 @@ static int prox_capture_sample(struct hid_sensor_hub_device *hsdev, case 1: prox_state->human_presence[chan] = *(u8 *)raw_data * multiplier; return 0; + case 2: + prox_state->human_presence[chan] = *(u16 *)raw_data * multiplier; + return 0; case 4: prox_state->human_presence[chan] = *(u32 *)raw_data * multiplier; return 0;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang chenyuan0y@gmail.com
[ Upstream commit a99b598d836c9c6411110c70a2da134c78d96e67 ]
The returned value, pfsm->miscdev.name, from devm_kasprintf() could be NULL. A pointer check is added to prevent potential NULL pointer dereference. This is similar to the fix in commit 3027e7b15b02 ("ice: Fix some null pointer dereference issues in ice_ptp.c").
This issue is found by our static analysis tool.
Signed-off-by: Chenyuan Yang chenyuan0y@gmail.com Link: https://lore.kernel.org/r/20250311010511.1028269-1-chenyuan0y@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/tps6594-pfsm.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/misc/tps6594-pfsm.c b/drivers/misc/tps6594-pfsm.c index 0a24ce44cc37c..6db1c9d48f8fc 100644 --- a/drivers/misc/tps6594-pfsm.c +++ b/drivers/misc/tps6594-pfsm.c @@ -281,6 +281,9 @@ static int tps6594_pfsm_probe(struct platform_device *pdev) pfsm->miscdev.minor = MISC_DYNAMIC_MINOR; pfsm->miscdev.name = devm_kasprintf(dev, GFP_KERNEL, "pfsm-%ld-0x%02x", tps->chip_id, tps->reg); + if (!pfsm->miscdev.name) + return -ENOMEM; + pfsm->miscdev.fops = &tps6594_pfsm_fops; pfsm->miscdev.parent = dev->parent; pfsm->chip_id = tps->chip_id;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Yufeng chenyufeng@iie.ac.cn
[ Upstream commit 153874010354d050f62f8ae25cbb960c17633dc5 ]
The variable tpgt in usbg_make_tpg() is defined as unsigned long and is assigned to tpgt->tport_tpgt, which is defined as u16. This may cause an integer overflow when tpgt is greater than USHRT_MAX (65535). I haven't tried to trigger it myself, but it is possible to trigger it by calling usbg_make_tpg() with a large value for tpgt.
I modified the type of tpgt to match tpgt->tport_tpgt and adjusted the relevant code accordingly.
This patch is similar to commit 59c816c1f24d ("vhost/scsi: potential memory corruption").
Signed-off-by: Chen Yufeng chenyufeng@iie.ac.cn Link: https://lore.kernel.org/r/20250415065857.1619-1-chenyufeng@iie.ac.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_tcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/function/f_tcm.c b/drivers/usb/gadget/function/f_tcm.c index 5a2e1237f85c3..6e8804f04baa7 100644 --- a/drivers/usb/gadget/function/f_tcm.c +++ b/drivers/usb/gadget/function/f_tcm.c @@ -1641,14 +1641,14 @@ static struct se_portal_group *usbg_make_tpg(struct se_wwn *wwn, struct usbg_tport *tport = container_of(wwn, struct usbg_tport, tport_wwn); struct usbg_tpg *tpg; - unsigned long tpgt; + u16 tpgt; int ret; struct f_tcm_opts *opts; unsigned i;
if (strstr(name, "tpgt_") != name) return ERR_PTR(-EINVAL); - if (kstrtoul(name + 5, 0, &tpgt) || tpgt > UINT_MAX) + if (kstrtou16(name + 5, 0, &tpgt)) return ERR_PTR(-EINVAL); ret = -ENODEV; mutex_lock(&tpg_instances_lock);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Lewalski jakub.lewalski@nokia.com
[ Upstream commit 6bd697b5fc39fd24e2aa418c7b7d14469f550a93 ]
When two instances of uart devices are probing, a concurrency race can occur. If one thread calls uart_register_driver function, which first allocates and assigns memory to 'uart_state' member of uart_driver structure, the other instance can bypass uart driver registration and call ulite_assign. This calls uart_add_one_port, which expects the uart driver to be fully initialized. This leads to a kernel panic due to a null pointer dereference:
[ 8.143581] BUG: kernel NULL pointer dereference, address: 00000000000002b8 [ 8.156982] #PF: supervisor write access in kernel mode [ 8.156984] #PF: error_code(0x0002) - not-present page [ 8.156986] PGD 0 P4D 0 ... [ 8.180668] RIP: 0010:mutex_lock+0x19/0x30 [ 8.188624] Call Trace: [ 8.188629] ? __die_body.cold+0x1a/0x1f [ 8.195260] ? page_fault_oops+0x15c/0x290 [ 8.209183] ? __irq_resolve_mapping+0x47/0x80 [ 8.209187] ? exc_page_fault+0x64/0x140 [ 8.209190] ? asm_exc_page_fault+0x22/0x30 [ 8.209196] ? mutex_lock+0x19/0x30 [ 8.223116] uart_add_one_port+0x60/0x440 [ 8.223122] ? proc_tty_register_driver+0x43/0x50 [ 8.223126] ? tty_register_driver+0x1ca/0x1e0 [ 8.246250] ulite_probe+0x357/0x4b0 [uartlite]
To prevent it, move uart driver registration in to init function. This will ensure that uart_driver is always registered when probe function is called.
Signed-off-by: Jakub Lewalski jakub.lewalski@nokia.com Signed-off-by: Elodie Decerle elodie.decerle@nokia.com Link: https://lore.kernel.org/r/20250331160732.2042-1-elodie.decerle@nokia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/tty/serial/uartlite.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c index a41e7fc373b7c..39c1fd1ff9ced 100644 --- a/drivers/tty/serial/uartlite.c +++ b/drivers/tty/serial/uartlite.c @@ -880,16 +880,6 @@ static int ulite_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev);
- if (!ulite_uart_driver.state) { - dev_dbg(&pdev->dev, "uartlite: calling uart_register_driver()\n"); - ret = uart_register_driver(&ulite_uart_driver); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register driver\n"); - clk_disable_unprepare(pdata->clk); - return ret; - } - } - ret = ulite_assign(&pdev->dev, id, res->start, irq, pdata);
pm_runtime_mark_last_busy(&pdev->dev); @@ -929,16 +919,25 @@ static struct platform_driver ulite_platform_driver = {
static int __init ulite_init(void) { + int ret; + + pr_debug("uartlite: calling uart_register_driver()\n"); + ret = uart_register_driver(&ulite_uart_driver); + if (ret) + return ret;
pr_debug("uartlite: calling platform_driver_register()\n"); - return platform_driver_register(&ulite_platform_driver); + ret = platform_driver_register(&ulite_platform_driver); + if (ret) + uart_unregister_driver(&ulite_uart_driver); + + return ret; }
static void __exit ulite_exit(void) { platform_driver_unregister(&ulite_platform_driver); - if (ulite_uart_driver.state) - uart_unregister_driver(&ulite_uart_driver); + uart_unregister_driver(&ulite_uart_driver); }
module_init(ulite_init);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chance Yang chance.yang@kneron.us
[ Upstream commit d4e5b10c55627e2f3fc9e5b337a28b4e2f02a55e ]
The current implementation of the usb-conn-gpio driver uses a fixed "usb-charger" name for all USB connector devices. This causes conflicts in the power supply subsystem when multiple USB connectors are present, as duplicate names are not allowed.
Use IDA to manage unique IDs for naming usb connectors (e.g., usb-charger-0, usb-charger-1).
Signed-off-by: Chance Yang chance.yang@kneron.us Link: https://lore.kernel.org/r/20250411-work-next-v3-1-7cd9aa80190c@kneron.us Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/common/usb-conn-gpio.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/common/usb-conn-gpio.c b/drivers/usb/common/usb-conn-gpio.c index 1e36be2a28fd5..421c3af38e069 100644 --- a/drivers/usb/common/usb-conn-gpio.c +++ b/drivers/usb/common/usb-conn-gpio.c @@ -21,6 +21,9 @@ #include <linux/regulator/consumer.h> #include <linux/string_choices.h> #include <linux/usb/role.h> +#include <linux/idr.h> + +static DEFINE_IDA(usb_conn_ida);
#define USB_GPIO_DEB_MS 20 /* ms */ #define USB_GPIO_DEB_US ((USB_GPIO_DEB_MS) * 1000) /* us */ @@ -30,6 +33,7 @@
struct usb_conn_info { struct device *dev; + int conn_id; /* store the IDA-allocated ID */ struct usb_role_switch *role_sw; enum usb_role last_role; struct regulator *vbus; @@ -161,7 +165,17 @@ static int usb_conn_psy_register(struct usb_conn_info *info) .fwnode = dev_fwnode(dev), };
- desc->name = "usb-charger"; + info->conn_id = ida_alloc(&usb_conn_ida, GFP_KERNEL); + if (info->conn_id < 0) + return info->conn_id; + + desc->name = devm_kasprintf(dev, GFP_KERNEL, "usb-charger-%d", + info->conn_id); + if (!desc->name) { + ida_free(&usb_conn_ida, info->conn_id); + return -ENOMEM; + } + desc->properties = usb_charger_properties; desc->num_properties = ARRAY_SIZE(usb_charger_properties); desc->get_property = usb_charger_get_property; @@ -169,8 +183,10 @@ static int usb_conn_psy_register(struct usb_conn_info *info) cfg.drv_data = info;
info->charger = devm_power_supply_register(dev, desc, &cfg); - if (IS_ERR(info->charger)) - dev_err(dev, "Unable to register charger\n"); + if (IS_ERR(info->charger)) { + dev_err(dev, "Unable to register charger %d\n", info->conn_id); + ida_free(&usb_conn_ida, info->conn_id); + }
return PTR_ERR_OR_ZERO(info->charger); } @@ -278,6 +294,9 @@ static void usb_conn_remove(struct platform_device *pdev)
cancel_delayed_work_sync(&info->dw_det);
+ if (info->charger) + ida_free(&usb_conn_ida, info->conn_id); + if (info->last_role == USB_ROLE_HOST && info->vbus) regulator_disable(info->vbus);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 82fe5107fa3d21d6c3fba091c9dbc50495588630 ]
When creating a device path in the driver the snprintf() takes up to 16 characters long argument along with the additional up to 12 characters for the signed integer (as it can't see the actual limits) and tries to pack this into 16 bytes array. GCC complains about that when build with `make W=1`:
drivers/usb/core/usb.c:705:25: note: ‘snprintf’ output between 3 and 28 bytes into a destination of size 16
Since everything works until now, let's just check for the potential buffer overflow and bail out. It is most likely a never happen situation, but at least it makes GCC happy.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20250321164949.423957-1-andriy.shevchenko@linux.in... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/core/usb.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0b4685aad2d50..118fa4c93a795 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -695,15 +695,16 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, device_set_of_node_from_dev(&dev->dev, bus->sysdev); dev_set_name(&dev->dev, "usb%d", bus->busnum); } else { + int n; + /* match any labeling on the hubs; it's one-based */ if (parent->devpath[0] == '0') { - snprintf(dev->devpath, sizeof dev->devpath, - "%d", port1); + n = snprintf(dev->devpath, sizeof(dev->devpath), "%d", port1); /* Root ports are not counted in route string */ dev->route = 0; } else { - snprintf(dev->devpath, sizeof dev->devpath, - "%s.%d", parent->devpath, port1); + n = snprintf(dev->devpath, sizeof(dev->devpath), "%s.%d", + parent->devpath, port1); /* Route string assumes hubs have less than 16 ports */ if (port1 < 15) dev->route = parent->route + @@ -712,6 +713,11 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, dev->route = parent->route + (15 << ((parent->level - 1)*4)); } + if (n >= sizeof(dev->devpath)) { + usb_put_hcd(bus_to_hcd(bus)); + usb_put_dev(dev); + return NULL; + }
dev->dev.parent = &parent->dev; dev_set_name(&dev->dev, "%d-%s", bus->busnum, dev->devpath);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robert Hodaszi robert.hodaszi@digi.com
[ Upstream commit 387602d8a75574fafb451b7a8215e78dfd67ee63 ]
Don't set WDM_READ flag in wdm_in_callback() for ZLP-s, otherwise when userspace tries to poll for available data, it might - incorrectly - believe there is something available, and when it tries to non-blocking read it, it might get stuck in the read loop.
For example this is what glib does for non-blocking read (briefly):
1. poll() 2. if poll returns with non-zero, starts a read data loop: a. loop on poll() (EINTR disabled) b. if revents was set, reads data I. if read returns with EINTR or EAGAIN, goto 2.a. II. otherwise return with data
So if ZLP sets WDM_READ (#1), we expect data, and try to read it (#2). But as that was a ZLP, and we are doing non-blocking read, wdm_read() returns with EAGAIN (#2.b.I), so loop again, and try to read again (#2.a.).
With glib, we might stuck in this loop forever, as EINTR is disabled (#2.a).
Signed-off-by: Robert Hodaszi robert.hodaszi@digi.com Acked-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/20250403144004.3889125-1-robert.hodaszi@digi.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/class/cdc-wdm.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-)
diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 16e7fa4d488d3..ecd6d1f39e498 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -92,7 +92,6 @@ struct wdm_device { u16 wMaxCommand; u16 wMaxPacketSize; __le16 inum; - int reslength; int length; int read; int count; @@ -214,6 +213,11 @@ static void wdm_in_callback(struct urb *urb) if (desc->rerr == 0 && status != -EPIPE) desc->rerr = status;
+ if (length == 0) { + dev_dbg(&desc->intf->dev, "received ZLP\n"); + goto skip_zlp; + } + if (length + desc->length > desc->wMaxCommand) { /* The buffer would overflow */ set_bit(WDM_OVERFLOW, &desc->flags); @@ -222,18 +226,18 @@ static void wdm_in_callback(struct urb *urb) if (!test_bit(WDM_OVERFLOW, &desc->flags)) { memmove(desc->ubuf + desc->length, desc->inbuf, length); desc->length += length; - desc->reslength = length; } } skip_error:
if (desc->rerr) { /* - * Since there was an error, userspace may decide to not read - * any data after poll'ing. + * If there was a ZLP or an error, userspace may decide to not + * read any data after poll'ing. * We should respond to further attempts from the device to send * data, so that we can get unstuck. */ +skip_zlp: schedule_work(&desc->service_outs_intr); } else { set_bit(WDM_READ, &desc->flags); @@ -585,15 +589,6 @@ static ssize_t wdm_read goto retry; }
- if (!desc->reslength) { /* zero length read */ - dev_dbg(&desc->intf->dev, "zero length - clearing WDM_READ\n"); - clear_bit(WDM_READ, &desc->flags); - rv = service_outstanding_interrupt(desc); - spin_unlock_irq(&desc->iuspin); - if (rv < 0) - goto err; - goto retry; - } cntr = desc->length; spin_unlock_irq(&desc->iuspin); } @@ -1016,7 +1011,7 @@ static void service_interrupt_work(struct work_struct *work)
spin_lock_irq(&desc->iuspin); service_outstanding_interrupt(desc); - if (!desc->resp_count) { + if (!desc->resp_count && (desc->length || desc->rerr)) { set_bit(WDM_READ, &desc->flags); wake_up(&desc->wait); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Korsgaard peter@korsgaard.com
[ Upstream commit 937a8a3a8d46a3377b4195cd8f2aa656666ebc8b ]
Similar to how it is done in the write path.
Add a disabled flag to track the function state and use it to exit the read loops to ensure no readers get stuck when the function is disabled/unbound, protecting against corruption when the waitq and spinlocks are reinitialized in hidg_bind().
Signed-off-by: Peter Korsgaard peter@korsgaard.com Link: https://lore.kernel.org/r/20250318152207.330997-1-peter@korsgaard.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/function/f_hid.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/gadget/function/f_hid.c b/drivers/usb/gadget/function/f_hid.c index c7a05f842745b..d8bd2d82e9ec6 100644 --- a/drivers/usb/gadget/function/f_hid.c +++ b/drivers/usb/gadget/function/f_hid.c @@ -75,6 +75,7 @@ struct f_hidg { /* recv report */ spinlock_t read_spinlock; wait_queue_head_t read_queue; + bool disabled; /* recv report - interrupt out only (use_out_ep == 1) */ struct list_head completed_out_req; unsigned int qlen; @@ -329,7 +330,7 @@ static ssize_t f_hidg_intout_read(struct file *file, char __user *buffer,
spin_lock_irqsave(&hidg->read_spinlock, flags);
-#define READ_COND_INTOUT (!list_empty(&hidg->completed_out_req)) +#define READ_COND_INTOUT (!list_empty(&hidg->completed_out_req) || hidg->disabled)
/* wait for at least one buffer to complete */ while (!READ_COND_INTOUT) { @@ -343,6 +344,11 @@ static ssize_t f_hidg_intout_read(struct file *file, char __user *buffer, spin_lock_irqsave(&hidg->read_spinlock, flags); }
+ if (hidg->disabled) { + spin_unlock_irqrestore(&hidg->read_spinlock, flags); + return -ESHUTDOWN; + } + /* pick the first one */ list = list_first_entry(&hidg->completed_out_req, struct f_hidg_req_list, list); @@ -387,7 +393,7 @@ static ssize_t f_hidg_intout_read(struct file *file, char __user *buffer, return count; }
-#define READ_COND_SSREPORT (hidg->set_report_buf != NULL) +#define READ_COND_SSREPORT (hidg->set_report_buf != NULL || hidg->disabled)
static ssize_t f_hidg_ssreport_read(struct file *file, char __user *buffer, size_t count, loff_t *ptr) @@ -1012,6 +1018,11 @@ static void hidg_disable(struct usb_function *f) } spin_unlock_irqrestore(&hidg->get_report_spinlock, flags);
+ spin_lock_irqsave(&hidg->read_spinlock, flags); + hidg->disabled = true; + spin_unlock_irqrestore(&hidg->read_spinlock, flags); + wake_up(&hidg->read_queue); + spin_lock_irqsave(&hidg->write_spinlock, flags); if (!hidg->write_pending) { free_ep_req(hidg->in_ep, hidg->req); @@ -1097,6 +1108,10 @@ static int hidg_set_alt(struct usb_function *f, unsigned intf, unsigned alt) } }
+ spin_lock_irqsave(&hidg->read_spinlock, flags); + hidg->disabled = false; + spin_unlock_irqrestore(&hidg->read_spinlock, flags); + if (hidg->in_ep != NULL) { spin_lock_irqsave(&hidg->write_spinlock, flags); hidg->req = req_in;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jos Wang joswang@lenovo.com
[ Upstream commit b4b38ffb38c91afd4dc387608db26f6fc34ed40b ]
Although some Type-C DRD devices that do not support the DP Sink function (such as Huawei Mate 40Pro), the Source Port initiates Enter Mode CMD, but the device responds to Enter Mode ACK, the Source port then initiates DP Status Update CMD, and the device responds to DP Status Update NAK.
As PD2.0 spec ("6.4.4.3.4 Enter Mode Command"),A DR_Swap Message Shall Not be sent during Modal Operation between the Port Partners. At this time, the source port initiates DR_Swap message through the "echo device > /sys/class/typec/port0/data_role" command to switch the data role from host to device. The device will initiate a Hard Reset for recovery, resulting in the failure of data role swap.
Therefore, when DP Status Update NAK is received, Exit Mode CMD is initiated to exit the currently entered DP altmode.
Signed-off-by: Jos Wang joswang@lenovo.com Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20250209071926.69625-1-joswang1221@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/altmodes/displayport.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/usb/typec/altmodes/displayport.c b/drivers/usb/typec/altmodes/displayport.c index ac84a6d64c2fb..b09b58d7311de 100644 --- a/drivers/usb/typec/altmodes/displayport.c +++ b/drivers/usb/typec/altmodes/displayport.c @@ -393,6 +393,10 @@ static int dp_altmode_vdm(struct typec_altmode *alt, break; case CMDT_RSP_NAK: switch (cmd) { + case DP_CMD_STATUS_UPDATE: + if (typec_altmode_exit(alt)) + dev_err(&dp->alt->dev, "Exit Mode Failed!\n"); + break; case DP_CMD_CONFIGURE: dp->data.conf = 0; ret = dp_altmode_configured(dp);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 9fc5986fbcd7e1e63afb04be94cd4e8a536a4b04 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20250406204051.63446-1-krzysztof.kozlowski@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/tcpm/tcpci_maxim_core.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tcpm/tcpci_maxim_core.c b/drivers/usb/typec/tcpm/tcpci_maxim_core.c index 648311f5e3cf1..b5a5ed40faea9 100644 --- a/drivers/usb/typec/tcpm/tcpci_maxim_core.c +++ b/drivers/usb/typec/tcpm/tcpci_maxim_core.c @@ -537,7 +537,10 @@ static int max_tcpci_probe(struct i2c_client *client) return dev_err_probe(&client->dev, ret, "IRQ initialization failed\n");
- device_init_wakeup(chip->dev, true); + ret = devm_device_init_wakeup(chip->dev); + if (ret) + return dev_err_probe(chip->dev, ret, "Failed to init wakeup\n"); + return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit aaa8f2e959341fd4a3ccf111500eb1e6176678e0 ]
Device can be unbound, so driver must also release memory for the wakeup source.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20250406204051.63446-2-krzysztof.kozlowski@linaro.... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/tipd/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/usb/typec/tipd/core.c b/drivers/usb/typec/tipd/core.c index 7ee721a877c12..dcf141ada0781 100644 --- a/drivers/usb/typec/tipd/core.c +++ b/drivers/usb/typec/tipd/core.c @@ -1431,7 +1431,7 @@ static int tps6598x_probe(struct i2c_client *client)
tps->wakeup = device_property_read_bool(tps->dev, "wakeup-source"); if (tps->wakeup && client->irq) { - device_init_wakeup(&client->dev, true); + devm_device_init_wakeup(&client->dev); enable_irq_wake(client->irq); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Grzeschik m.grzeschik@pengutronix.de
[ Upstream commit 0f7bbef1794dc87141897f804e5871a293aa174b ]
Since the typec connectors can have many muxes or switches for different lanes (sbu, usb2, usb3) going into different modal states (usb2, usb3, audio, debug) all of them will be called on typec_switch_set and typec_mux_set. But not all of them will be handling the expected mode.
If one of the mux or switch will come back with EOPTNOSUPP this is no reason to stop running through the next ones. Therefor we skip this particular error value and continue calling the next.
Signed-off-by: Michael Grzeschik m.grzeschik@pengutronix.de Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20250404-ml-topic-typec-mux-v1-1-22c0526381ba@peng... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/mux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/typec/mux.c b/drivers/usb/typec/mux.c index 49926d6e72c71..182c902c42f61 100644 --- a/drivers/usb/typec/mux.c +++ b/drivers/usb/typec/mux.c @@ -214,7 +214,7 @@ int typec_switch_set(struct typec_switch *sw, sw_dev = sw->sw_devs[i];
ret = sw_dev->set(sw_dev, orientation); - if (ret) + if (ret && ret != -EOPNOTSUPP) return ret; }
@@ -378,7 +378,7 @@ int typec_mux_set(struct typec_mux *mux, struct typec_mux_state *state) mux_dev = mux->mux_devs[i];
ret = mux_dev->set(mux_dev, state); - if (ret) + if (ret && ret != -EOPNOTSUPP) return ret; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Chiu andybnac@gmail.com
[ Upstream commit ca358692de41b273468e625f96926fa53e13bd8c ]
RISC-V spec explicitly calls out that a local fence.i is not enough for the code modification to be visble from a remote hart. In fact, it states:
To make a store to instruction memory visible to all RISC-V harts, the writing hart also has to execute a data FENCE before requesting that all remote RISC-V harts execute a FENCE.I.
Although current riscv drivers for IPI use ordered MMIO when sending IPIs in order to synchronize the action between previous csd writes, riscv does not restrict itself to any particular flavor of IPI. Any driver or firmware implementation that does not order data writes before the IPI may pose a risk for code-modifying race.
Thus, add a fence here to order data writes before making the IPI.
Signed-off-by: Andy Chiu andybnac@gmail.com Reviewed-by: Björn Töpel bjorn@rivosinc.com Link: https://lore.kernel.org/r/20250407180838.42877-8-andybnac@gmail.com Signed-off-by: Alexandre Ghiti alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/mm/cacheflush.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/mm/cacheflush.c b/arch/riscv/mm/cacheflush.c index b816727298872..b2e4b81763f88 100644 --- a/arch/riscv/mm/cacheflush.c +++ b/arch/riscv/mm/cacheflush.c @@ -24,7 +24,20 @@ void flush_icache_all(void)
if (num_online_cpus() < 2) return; - else if (riscv_use_sbi_for_rfence()) + + /* + * Make sure all previous writes to the D$ are ordered before making + * the IPI. The RISC-V spec states that a hart must execute a data fence + * before triggering a remote fence.i in order to make the modification + * visable for remote harts. + * + * IPIs on RISC-V are triggered by MMIO writes to either CLINT or + * S-IMSIC, so the fence ensures previous data writes "happen before" + * the MMIO. + */ + RISCV_FENCE(w, o); + + if (riscv_use_sbi_for_rfence()) sbi_remote_fence_i(NULL); else on_each_cpu(ipi_remote_fence_i, NULL, 1);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens hca@linux.ibm.com
[ Upstream commit 11709abccf93b08adde95ef313c300b0d4bc28f1 ]
Kernel user spaces accesses to not exported pages in atomic context incorrectly try to resolve the page fault. With debug options enabled call traces like this can be seen:
BUG: sleeping function called from invalid context at kernel/locking/rwsem.c:1523 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 419074, name: qemu-system-s39 preempt_count: 1, expected: 0 RCU nest depth: 0, expected: 0 INFO: lockdep is turned off. Preemption disabled at: [<00000383ea47cfa2>] copy_page_from_iter_atomic+0xa2/0x8a0 CPU: 12 UID: 0 PID: 419074 Comm: qemu-system-s39 Tainted: G W 6.16.0-20250531.rc0.git0.69b3a602feac.63.fc42.s390x+debug #1 PREEMPT Tainted: [W]=WARN Hardware name: IBM 3931 A01 703 (LPAR) Call Trace: [<00000383e990d282>] dump_stack_lvl+0xa2/0xe8 [<00000383e99bf152>] __might_resched+0x292/0x2d0 [<00000383eaa7c374>] down_read+0x34/0x2d0 [<00000383e99432f8>] do_secure_storage_access+0x108/0x360 [<00000383eaa724b0>] __do_pgm_check+0x130/0x220 [<00000383eaa842e4>] pgm_check_handler+0x114/0x160 [<00000383ea47d028>] copy_page_from_iter_atomic+0x128/0x8a0 ([<00000383ea47d016>] copy_page_from_iter_atomic+0x116/0x8a0) [<00000383e9c45eae>] generic_perform_write+0x16e/0x310 [<00000383e9eb87f4>] ext4_buffered_write_iter+0x84/0x160 [<00000383e9da0de4>] vfs_write+0x1c4/0x460 [<00000383e9da123c>] ksys_write+0x7c/0x100 [<00000383eaa7284e>] __do_syscall+0x15e/0x280 [<00000383eaa8417e>] system_call+0x6e/0x90 INFO: lockdep is turned off.
It is not allowed to take the mmap_lock while in atomic context. Therefore handle such a secure storage access fault as if the accessed page is not mapped: the uaccess function will return -EFAULT, and the caller has to deal with this. Usually this means that the access is retried in process context, which allows to resolve the page fault (or in this case export the page).
Reviewed-by: Claudio Imbrenda imbrenda@linux.ibm.com Acked-by: Alexander Gordeev agordeev@linux.ibm.com Acked-by: Christian Borntraeger borntraeger@linux.ibm.com Link: https://lore.kernel.org/r/20250603134936.1314139-1-hca@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/mm/fault.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index da84ff6770dec..8b3f6dd00eab2 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -442,6 +442,8 @@ void do_secure_storage_access(struct pt_regs *regs) if (rc) BUG(); } else { + if (faulthandler_disabled()) + return handle_fault_error_nolock(regs, 0); mm = current->mm; mmap_read_lock(mm); vma = find_vma(mm, addr);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Clément Léger cleger@rivosinc.com
[ Upstream commit 1317045a7d6f397904d105f6d40dc9787876a34b ]
While misaligned_access_speed was defined in a file compile with CONFIG_RISCV_MISALIGNED, its definition was under CONFIG_RISCV_SCALAR_MISALIGNED. This resulted in compilation problems when using it in a file compiled with CONFIG_RISCV_MISALIGNED.
Move the declaration under CONFIG_RISCV_MISALIGNED so that it can be used unconditionnally when compiled with that config and remove the check for that variable in traps_misaligned.c.
Signed-off-by: Clément Léger cleger@rivosinc.com Reviewed-by: Charlie Jenkins charlie@rivosinc.com Tested-by: Charlie Jenkins charlie@rivosinc.com Reviewed-by: Andrew Jones ajones@ventanamicro.com Link: https://lore.kernel.org/r/20250523101932.1594077-9-cleger@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/include/asm/cpufeature.h | 5 ++++- arch/riscv/kernel/traps_misaligned.c | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/riscv/include/asm/cpufeature.h b/arch/riscv/include/asm/cpufeature.h index f56b409361fbe..7201da46694f7 100644 --- a/arch/riscv/include/asm/cpufeature.h +++ b/arch/riscv/include/asm/cpufeature.h @@ -71,7 +71,6 @@ bool __init check_unaligned_access_emulated_all_cpus(void); void check_unaligned_access_emulated(struct work_struct *work __always_unused); void unaligned_emulation_finish(void); bool unaligned_ctl_available(void); -DECLARE_PER_CPU(long, misaligned_access_speed); #else static inline bool unaligned_ctl_available(void) { @@ -79,6 +78,10 @@ static inline bool unaligned_ctl_available(void) } #endif
+#if defined(CONFIG_RISCV_MISALIGNED) +DECLARE_PER_CPU(long, misaligned_access_speed); +#endif + bool __init check_vector_unaligned_access_emulated_all_cpus(void); #if defined(CONFIG_RISCV_VECTOR_MISALIGNED) void check_vector_unaligned_access_emulated(struct work_struct *work __always_unused); diff --git a/arch/riscv/kernel/traps_misaligned.c b/arch/riscv/kernel/traps_misaligned.c index 56f06a27d45fb..a6b6047693105 100644 --- a/arch/riscv/kernel/traps_misaligned.c +++ b/arch/riscv/kernel/traps_misaligned.c @@ -368,9 +368,7 @@ static int handle_scalar_misaligned_load(struct pt_regs *regs)
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, addr);
-#ifdef CONFIG_RISCV_PROBE_UNALIGNED_ACCESS *this_cpu_ptr(&misaligned_access_speed) = RISCV_HWPROBE_MISALIGNED_SCALAR_EMULATED; -#endif
if (!unaligned_enabled) return -1;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski cezary.rojewski@intel.com
[ Upstream commit 3f100f524e75586537e337b34d18c8d604b398e7 ]
For the classic snd_hda_intel driver, codec->card and bus->card point to the exact same thing. When snd_card_diconnect() fires, bus->shutdown is set thanks to azx_dev_disconnect(). card->shutdown is already set when that happens but both provide basically the same functionality.
For the DSP snd_soc_avs driver where multiple codecs are located on multiple cards, bus->shutdown 'shortcut' is not sufficient. One codec card may be unregistered while other codecs are still operational. Proper check in form of card->shutdown must be used to verify whether the codec's card is being shut down.
Reviewed-by: Amadeusz Sławiński amadeuszx.slawinski@linux.intel.com Signed-off-by: Cezary Rojewski cezary.rojewski@intel.com Link: https://patch.msgid.link/20250530141309.2943404-1-cezary.rojewski@intel.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/hda_bind.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index 1fef350d821ef..df8f88beddd07 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -44,7 +44,7 @@ static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev) struct hda_codec *codec = container_of(dev, struct hda_codec, core);
/* ignore unsol events during shutdown */ - if (codec->bus->shutdown) + if (codec->card->shutdown || codec->bus->shutdown) return;
/* ignore unsol events during system suspend/resume */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda Vijendar.Mukunda@amd.com
[ Upstream commit ab72bfce7647522e01a181e3600c3d14ff5c143e ]
Add new pci id for AMD GPU display HD audio controller(device id- 0xab40).
Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Link: https://patch.msgid.link/20250529053838.2350071-1-Vijendar.Mukunda@amd.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 77a2984c3741d..eb7ffa152b97b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -2717,6 +2717,9 @@ static const struct pci_device_id azx_ids[] = { { PCI_VDEVICE(ATI, 0xab38), .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | AZX_DCAPS_PM_RUNTIME }, + { PCI_VDEVICE(ATI, 0xab40), + .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS | + AZX_DCAPS_PM_RUNTIME }, /* GLENFLY */ { PCI_DEVICE(PCI_VENDOR_ID_GLENFLY, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 4919353c7789b8047e06a9b2b943f775a8f72883 ]
The audio controller in the Lenovo Thinkpad Thunderbolt 3 dock doesn't support reading the sampling rate.
Add a quirk for it.
Suggested-by: Takashi Iwai tiwai@suse.de Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://patch.msgid.link/20250527172657.1972565-1-superm1@kernel.org Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index dbbc9eb935a4b..f302bcebaa9d0 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2284,6 +2284,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_DISABLE_AUTOSUSPEND), DEVICE_FLG(0x17aa, 0x104d, /* Lenovo ThinkStation P620 Internal Speaker + Front Headset */ QUIRK_FLAG_DISABLE_AUTOSUSPEND), + DEVICE_FLG(0x17ef, 0x3083, /* Lenovo TBT3 dock */ + QUIRK_FLAG_GET_SAMPLE_RATE), DEVICE_FLG(0x1852, 0x5062, /* Luxman D-08u */ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), DEVICE_FLG(0x1852, 0x5065, /* Luxman DA-06 */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuming Fan shumingf@realtek.com
[ Upstream commit 9adf2de86611ac108d07e769a699556d87f052e2 ]
This patch updates the settings to fix the speaker noise.
Signed-off-by: Shuming Fan shumingf@realtek.com Link: https://patch.msgid.link/20250602085851.4081886-1-shumingf@realtek.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/rt1320-sdw.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/rt1320-sdw.c b/sound/soc/codecs/rt1320-sdw.c index f51ba345a16e6..015cc710e6dc0 100644 --- a/sound/soc/codecs/rt1320-sdw.c +++ b/sound/soc/codecs/rt1320-sdw.c @@ -204,7 +204,7 @@ static const struct reg_sequence rt1320_vc_blind_write[] = { { 0x3fc2bfc0, 0x03 }, { 0x0000d486, 0x43 }, { SDW_SDCA_CTL(FUNC_NUM_AMP, RT1320_SDCA_ENT_PDE23, RT1320_SDCA_CTL_REQ_POWER_STATE, 0), 0x00 }, - { 0x1000db00, 0x04 }, + { 0x1000db00, 0x07 }, { 0x1000db01, 0x00 }, { 0x1000db02, 0x11 }, { 0x1000db03, 0x00 }, @@ -225,6 +225,21 @@ static const struct reg_sequence rt1320_vc_blind_write[] = { { 0x1000db12, 0x00 }, { 0x1000db13, 0x00 }, { 0x1000db14, 0x45 }, + { 0x1000db15, 0x0d }, + { 0x1000db16, 0x01 }, + { 0x1000db17, 0x00 }, + { 0x1000db18, 0x00 }, + { 0x1000db19, 0xbf }, + { 0x1000db1a, 0x13 }, + { 0x1000db1b, 0x09 }, + { 0x1000db1c, 0x00 }, + { 0x1000db1d, 0x00 }, + { 0x1000db1e, 0x00 }, + { 0x1000db1f, 0x12 }, + { 0x1000db20, 0x09 }, + { 0x1000db21, 0x00 }, + { 0x1000db22, 0x00 }, + { 0x1000db23, 0x00 }, { 0x0000d540, 0x01 }, { 0x0000c081, 0xfc }, { 0x0000f01e, 0x80 },
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Kandybka d.kandybka@gmail.com
[ Upstream commit 0abd87942e0c93964e93224836944712feba1d91 ]
In 'ceph_zero_objects', promote 'object_size' to 'u64' to avoid possible integer overflow.
Compile tested only.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
Signed-off-by: Dmitry Kandybka d.kandybka@gmail.com Reviewed-by: Viacheslav Dubeyko Slava.Dubeyko@ibm.com Signed-off-by: Ilya Dryomov idryomov@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ceph/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 851d70200c6b8..a7254cab44cc2 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -2616,7 +2616,7 @@ static int ceph_zero_objects(struct inode *inode, loff_t offset, loff_t length) s32 stripe_unit = ci->i_layout.stripe_unit; s32 stripe_count = ci->i_layout.stripe_count; s32 object_size = ci->i_layout.object_size; - u64 object_set_size = object_size * stripe_count; + u64 object_set_size = (u64) object_size * stripe_count; u64 nearly, t;
/* round offset up to next period boundary */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ziqi Chen quic_ziqichen@quicinc.com
[ Upstream commit e97633492f5a3eca7b3ff03b4ef6f993017f7955 ]
When preparing for UFS clock scaling, the UFS driver will quiesce all sdevs queues in the UFS SCSI host tagset list and then unquiesce them in ufshcd_clock_scaling_unprepare(). If the UFS SCSI host async scan is in progress at this time, some LUs may be added to the tagset list between UFS clkscale prepare and unprepare. This can cause two issues:
1. During clock scaling, there may be I/O requests issued through new added queues that have not been quiesced, leading to task abort issue.
2. These new added queues that have not been quiesced will be unquiesced as well when UFS clkscale is unprepared, resulting in warning prints.
Therefore, use the mutex lock scan_mutex in ufshcd_clock_scaling_prepare() and ufshcd_clock_scaling_unprepare() to protect it.
Co-developed-by: Can Guo quic_cang@quicinc.com Signed-off-by: Can Guo quic_cang@quicinc.com Signed-off-by: Ziqi Chen quic_ziqichen@quicinc.com Link: https://lore.kernel.org/r/20250522081233.2358565-1-quic_ziqichen@quicinc.com Suggested-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufshcd.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 04f769d907a44..ea24080c26e89 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -1379,6 +1379,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us) * make sure that there are no outstanding requests when * clock scaling is in progress */ + mutex_lock(&hba->host->scan_mutex); blk_mq_quiesce_tagset(&hba->host->tag_set); mutex_lock(&hba->wb_mutex); down_write(&hba->clk_scaling_lock); @@ -1389,6 +1390,7 @@ static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us) up_write(&hba->clk_scaling_lock); mutex_unlock(&hba->wb_mutex); blk_mq_unquiesce_tagset(&hba->host->tag_set); + mutex_unlock(&hba->host->scan_mutex); goto out; }
@@ -1410,6 +1412,7 @@ static void ufshcd_clock_scaling_unprepare(struct ufs_hba *hba, int err) mutex_unlock(&hba->wb_mutex);
blk_mq_unquiesce_tagset(&hba->host->tag_set); + mutex_unlock(&hba->host->scan_mutex); ufshcd_release(hba); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ben Dooks ben.dooks@codethink.co.uk
[ Upstream commit 788aa64c01f1262310b4c1fb827a36df170d86ea ]
When threads/tasks are switched we need to ensure the old execution's SR_SUM state is saved and the new thread has the old SR_SUM state restored.
The issue was seen under heavy load especially with the syz-stress tool running, with crashes as follows in schedule_tail:
Unable to handle kernel access to user memory without uaccess routines at virtual address 000000002749f0d0 Oops [#1] Modules linked in: CPU: 1 PID: 4875 Comm: syz-executor.0 Not tainted 5.12.0-rc2-syzkaller-00467-g0d7588ab9ef9 #0 Hardware name: riscv-virtio,qemu (DT) epc : schedule_tail+0x72/0xb2 kernel/sched/core.c:4264 ra : task_pid_vnr include/linux/sched.h:1421 [inline] ra : schedule_tail+0x70/0xb2 kernel/sched/core.c:4264 epc : ffffffe00008c8b0 ra : ffffffe00008c8ae sp : ffffffe025d17ec0 gp : ffffffe005d25378 tp : ffffffe00f0d0000 t0 : 0000000000000000 t1 : 0000000000000001 t2 : 00000000000f4240 s0 : ffffffe025d17ee0 s1 : 000000002749f0d0 a0 : 000000000000002a a1 : 0000000000000003 a2 : 1ffffffc0cfac500 a3 : ffffffe0000c80cc a4 : 5ae9db91c19bbe00 a5 : 0000000000000000 a6 : 0000000000f00000 a7 : ffffffe000082eba s2 : 0000000000040000 s3 : ffffffe00eef96c0 s4 : ffffffe022c77fe0 s5 : 0000000000004000 s6 : ffffffe067d74e00 s7 : ffffffe067d74850 s8 : ffffffe067d73e18 s9 : ffffffe067d74e00 s10: ffffffe00eef96e8 s11: 000000ae6cdf8368 t3 : 5ae9db91c19bbe00 t4 : ffffffc4043cafb2 t5 : ffffffc4043cafba t6 : 0000000000040000 status: 0000000000000120 badaddr: 000000002749f0d0 cause: 000000000000000f Call Trace: [<ffffffe00008c8b0>] schedule_tail+0x72/0xb2 kernel/sched/core.c:4264 [<ffffffe000005570>] ret_from_exception+0x0/0x14 Dumping ftrace buffer: (ftrace buffer empty) ---[ end trace b5f8f9231dc87dda ]---
The issue comes from the put_user() in schedule_tail (kernel/sched/core.c) doing the following:
asmlinkage __visible void schedule_tail(struct task_struct *prev) { ... if (current->set_child_tid) put_user(task_pid_vnr(current), current->set_child_tid); ... }
the put_user() macro causes the code sequence to come out as follows:
1: __enable_user_access() 2: reg = task_pid_vnr(current); 3: *current->set_child_tid = reg; 4: __disable_user_access()
The problem is that we may have a sleeping function as argument which could clear SR_SUM causing the panic above. This was fixed by evaluating the argument of the put_user() macro outside the user-enabled section in commit 285a76bb2cf5 ("riscv: evaluate put_user() arg before enabling user access")"
In order for riscv to take advantage of unsafe_get/put_XXX() macros and to avoid the same issue we had with put_user() and sleeping functions we must ensure code flow can go through switch_to() from within a region of code with SR_SUM enabled and come back with SR_SUM still enabled. This patch addresses the problem allowing future work to enable full use of unsafe_get/put_XXX() macros without needing to take a CSR bit flip cost on every access. Make switch_to() save and restore SR_SUM.
Reported-by: syzbot+e74b94fe601ab9552d69@syzkaller.appspotmail.com Signed-off-by: Ben Dooks ben.dooks@codethink.co.uk Signed-off-by: Cyril Bur cyrilbur@tenstorrent.com Reviewed-by: Alexandre Ghiti alexghiti@rivosinc.com Reviewed-by: Deepak Gupta debug@rivosinc.com Link: https://lore.kernel.org/r/20250410070526.3160847-2-cyrilbur@tenstorrent.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/include/asm/processor.h | 1 + arch/riscv/kernel/asm-offsets.c | 5 +++++ arch/riscv/kernel/entry.S | 8 ++++++++ 3 files changed, 14 insertions(+)
diff --git a/arch/riscv/include/asm/processor.h b/arch/riscv/include/asm/processor.h index 5f56eb9d114a9..58fd11c89fe9f 100644 --- a/arch/riscv/include/asm/processor.h +++ b/arch/riscv/include/asm/processor.h @@ -103,6 +103,7 @@ struct thread_struct { struct __riscv_d_ext_state fstate; unsigned long bad_cause; unsigned long envcfg; + unsigned long status; u32 riscv_v_flags; u32 vstate_ctrl; struct __riscv_v_ext_state vstate; diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c index 16490755304e0..969c65b1fe41d 100644 --- a/arch/riscv/kernel/asm-offsets.c +++ b/arch/riscv/kernel/asm-offsets.c @@ -34,6 +34,7 @@ void asm_offsets(void) OFFSET(TASK_THREAD_S9, task_struct, thread.s[9]); OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]); OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); + OFFSET(TASK_THREAD_STATUS, task_struct, thread.status);
OFFSET(TASK_TI_CPU, task_struct, thread_info.cpu); OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count); @@ -346,6 +347,10 @@ void asm_offsets(void) offsetof(struct task_struct, thread.s[11]) - offsetof(struct task_struct, thread.ra) ); + DEFINE(TASK_THREAD_STATUS_RA, + offsetof(struct task_struct, thread.status) + - offsetof(struct task_struct, thread.ra) + );
DEFINE(TASK_THREAD_F0_F0, offsetof(struct task_struct, thread.fstate.f[0]) diff --git a/arch/riscv/kernel/entry.S b/arch/riscv/kernel/entry.S index 33a5a9f2a0d4e..00bd0de9faa28 100644 --- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -397,9 +397,17 @@ SYM_FUNC_START(__switch_to) REG_S s9, TASK_THREAD_S9_RA(a3) REG_S s10, TASK_THREAD_S10_RA(a3) REG_S s11, TASK_THREAD_S11_RA(a3) + + /* save the user space access flag */ + li s0, SR_SUM + csrr s1, CSR_STATUS + REG_S s1, TASK_THREAD_STATUS_RA(a3) + /* Save the kernel shadow call stack pointer */ scs_save_current /* Restore context from next->thread */ + REG_L s0, TASK_THREAD_STATUS_RA(a4) + csrs CSR_STATUS, s0 REG_L ra, TASK_THREAD_RA_RA(a4) REG_L sp, TASK_THREAD_SP_RA(a4) REG_L s0, TASK_THREAD_S0_RA(a4)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook kees@kernel.org
[ Upstream commit 8a39f1c870e9d6fbac5638f3a42a6a6363829c49 ]
In ovl_path_type() and ovl_is_metacopy_dentry() GCC notices that it is possible for OVL_E() to return NULL (which implies that d_inode(dentry) may be NULL). This would result in out of bounds reads via container_of(), seen with GCC 15's -Warray-bounds -fdiagnostics-details. For example:
In file included from arch/x86/include/generated/asm/rwonce.h:1, from include/linux/compiler.h:339, from include/linux/export.h:5, from include/linux/linkage.h:7, from include/linux/fs.h:5, from fs/overlayfs/util.c:7: In function 'ovl_upperdentry_dereference', inlined from 'ovl_dentry_upper' at ../fs/overlayfs/util.c:305:9, inlined from 'ovl_path_type' at ../fs/overlayfs/util.c:216:6: include/asm-generic/rwonce.h:44:26: error: array subscript 0 is outside array bounds of 'struct inode[7486503276667837]' [-Werror=array-bounds=] 44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x)) | ~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/asm-generic/rwonce.h:50:9: note: in expansion of macro '__READ_ONCE' 50 | __READ_ONCE(x); \ | ^~~~~~~~~~~ fs/overlayfs/ovl_entry.h:195:16: note: in expansion of macro 'READ_ONCE' 195 | return READ_ONCE(oi->__upperdentry); | ^~~~~~~~~ 'ovl_path_type': event 1 185 | return inode ? OVL_I(inode)->oe : NULL; 'ovl_path_type': event 2
Avoid this by allowing ovl_dentry_upper() to return NULL if d_inode() is NULL, as that means the problematic dereferencing can never be reached. Note that this fixes the over-eager compiler warning in an effort to being able to enable -Warray-bounds globally. There is no known behavioral bug here.
Suggested-by: Amir Goldstein amir73il@gmail.com Signed-off-by: Kees Cook kees@kernel.org Signed-off-by: Miklos Szeredi mszeredi@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/overlayfs/util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c index 0819c739cc2ff..5d6b60d56c275 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -305,7 +305,9 @@ enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path)
struct dentry *ovl_dentry_upper(struct dentry *dentry) { - return ovl_upperdentry_dereference(OVL_I(d_inode(dentry))); + struct inode *inode = d_inode(dentry); + + return inode ? ovl_upperdentry_dereference(OVL_I(inode)) : NULL; }
struct dentry *ovl_dentry_lower(struct dentry *dentry)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana fdmanana@suse.com
[ Upstream commit a26bf338cdad3643a6e7c3d78a172baadba15c1a ]
Syzbot reported an assertion failure due to an attempt to add a delayed iput after we have set BTRFS_FS_STATE_NO_DELAYED_IPUT in the fs_info state:
WARNING: CPU: 0 PID: 65 at fs/btrfs/inode.c:3420 btrfs_add_delayed_iput+0x2f8/0x370 fs/btrfs/inode.c:3420 Modules linked in: CPU: 0 UID: 0 PID: 65 Comm: kworker/u8:4 Not tainted 6.15.0-next-20250530-syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Workqueue: btrfs-endio-write btrfs_work_helper RIP: 0010:btrfs_add_delayed_iput+0x2f8/0x370 fs/btrfs/inode.c:3420 Code: 4e ad 5d (...) RSP: 0018:ffffc9000213f780 EFLAGS: 00010293 RAX: ffffffff83c635b7 RBX: ffff888058920000 RCX: ffff88801c769e00 RDX: 0000000000000000 RSI: 0000000000000100 RDI: 0000000000000000 RBP: 0000000000000001 R08: ffff888058921b67 R09: 1ffff1100b12436c R10: dffffc0000000000 R11: ffffed100b12436d R12: 0000000000000001 R13: dffffc0000000000 R14: ffff88807d748000 R15: 0000000000000100 FS: 0000000000000000(0000) GS:ffff888125c53000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00002000000bd038 CR3: 000000006a142000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> btrfs_put_ordered_extent+0x19f/0x470 fs/btrfs/ordered-data.c:635 btrfs_finish_one_ordered+0x11d8/0x1b10 fs/btrfs/inode.c:3312 btrfs_work_helper+0x399/0xc20 fs/btrfs/async-thread.c:312 process_one_work kernel/workqueue.c:3238 [inline] process_scheduled_works+0xae1/0x17b0 kernel/workqueue.c:3321 worker_thread+0x8a0/0xda0 kernel/workqueue.c:3402 kthread+0x70e/0x8a0 kernel/kthread.c:464 ret_from_fork+0x3fc/0x770 arch/x86/kernel/process.c:148 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK>
This can happen due to a race with the async reclaim worker like this:
1) The async metadata reclaim worker enters shrink_delalloc(), which calls btrfs_start_delalloc_roots() with an nr_pages argument that has a value less than LONG_MAX, and that in turn enters start_delalloc_inodes(), which sets the local variable 'full_flush' to false because wbc->nr_to_write is less than LONG_MAX;
2) There it finds inode X in a root's delalloc list, grabs a reference for inode X (with igrab()), and triggers writeback for it with filemap_fdatawrite_wbc(), which creates an ordered extent for inode X;
3) The unmount sequence starts from another task, we enter close_ctree() and we flush the workqueue fs_info->endio_write_workers, which waits for the ordered extent for inode X to complete and when dropping the last reference of the ordered extent, with btrfs_put_ordered_extent(), when we call btrfs_add_delayed_iput() we don't add the inode to the list of delayed iputs because it has a refcount of 2, so we decrement it to 1 and return;
4) Shortly after at close_ctree() we call btrfs_run_delayed_iputs() which runs all delayed iputs, and then we set BTRFS_FS_STATE_NO_DELAYED_IPUT in the fs_info state;
5) The async reclaim worker, after calling filemap_fdatawrite_wbc(), now calls btrfs_add_delayed_iput() for inode X and there we trigger an assertion failure since the fs_info state has the flag BTRFS_FS_STATE_NO_DELAYED_IPUT set.
Fix this by setting BTRFS_FS_STATE_NO_DELAYED_IPUT only after we wait for the async reclaim workers to finish, after we call cancel_work_sync() for them at close_ctree(), and by running delayed iputs after wait for the reclaim workers to finish and before setting the bit.
This race was recently introduced by commit 19e60b2a95f5 ("btrfs: add extra warning if delayed iput is added when it's not allowed"). Without the new validation at btrfs_add_delayed_iput(), this described scenario was safe because close_ctree() later calls btrfs_commit_super(). That will run any final delayed iputs added by reclaim workers in the window between the btrfs_run_delayed_iputs() and the the reclaim workers being shut down.
Reported-by: syzbot+0ed30ad435bf6f5b7a42@syzkaller.appspotmail.com Link: https://lore.kernel.org/linux-btrfs/6840481c.a00a0220.d4325.000c.GAE@google.... Fixes: 19e60b2a95f5 ("btrfs: add extra warning if delayed iput is added when it's not allowed") Reviewed-by: Boris Burkov boris@bur.io Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/disk-io.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index aa58e0663a5d7..87501762d81fb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -4385,8 +4385,8 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) * * So wait for all ongoing ordered extents to complete and then run * delayed iputs. This works because once we reach this point no one - * can either create new ordered extents nor create delayed iputs - * through some other means. + * can create new ordered extents, but delayed iputs can still be added + * by a reclaim worker (see comments further below). * * Also note that btrfs_wait_ordered_roots() is not safe here, because * it waits for BTRFS_ORDERED_COMPLETE to be set on an ordered extent, @@ -4397,15 +4397,29 @@ void __cold close_ctree(struct btrfs_fs_info *fs_info) btrfs_flush_workqueue(fs_info->endio_write_workers); /* Ordered extents for free space inodes. */ btrfs_flush_workqueue(fs_info->endio_freespace_worker); + /* + * Run delayed iputs in case an async reclaim worker is waiting for them + * to be run as mentioned above. + */ btrfs_run_delayed_iputs(fs_info); - /* There should be no more workload to generate new delayed iputs. */ - set_bit(BTRFS_FS_STATE_NO_DELAYED_IPUT, &fs_info->fs_state);
cancel_work_sync(&fs_info->async_reclaim_work); cancel_work_sync(&fs_info->async_data_reclaim_work); cancel_work_sync(&fs_info->preempt_reclaim_work); cancel_work_sync(&fs_info->em_shrinker_work);
+ /* + * Run delayed iputs again because an async reclaim worker may have + * added new ones if it was flushing delalloc: + * + * shrink_delalloc() -> btrfs_start_delalloc_roots() -> + * start_delalloc_inodes() -> btrfs_add_delayed_iput() + */ + btrfs_run_delayed_iputs(fs_info); + + /* There should be no more workload to generate new delayed iputs. */ + set_bit(BTRFS_FS_STATE_NO_DELAYED_IPUT, &fs_info->fs_state); + /* Cancel or finish ongoing discard work */ btrfs_discard_cleanup(fs_info);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo wqu@suse.com
[ Upstream commit 547e836661554dcfa15c212a3821664e85b4191a ]
[BUG] There is syzbot based reproducer that can crash the kernel, with the following call trace: (With some debug output added)
DEBUG: rescue=ibadroots parsed BTRFS: device fsid 14d642db-7b15-43e4-81e6-4b8fac6a25f8 devid 1 transid 8 /dev/loop0 (7:0) scanned by repro (1010) BTRFS info (device loop0): first mount of filesystem 14d642db-7b15-43e4-81e6-4b8fac6a25f8 BTRFS info (device loop0): using blake2b (blake2b-256-generic) checksum algorithm BTRFS info (device loop0): using free-space-tree BTRFS warning (device loop0): checksum verify failed on logical 5312512 mirror 1 wanted 0xb043382657aede36608fd3386d6b001692ff406164733d94e2d9a180412c6003 found 0x810ceb2bacb7f0f9eb2bf3b2b15c02af867cb35ad450898169f3b1f0bd818651 level 0 DEBUG: read tree root path failed for tree csum, ret=-5 BTRFS warning (device loop0): checksum verify failed on logical 5328896 mirror 1 wanted 0x51be4e8b303da58e6340226815b70e3a93592dac3f30dd510c7517454de8567a found 0x51be4e8b303da58e634022a315b70e3a93592dac3f30dd510c7517454de8567a level 0 BTRFS warning (device loop0): checksum verify failed on logical 5292032 mirror 1 wanted 0x1924ccd683be9efc2fa98582ef58760e3848e9043db8649ee382681e220cdee4 found 0x0cb6184f6e8799d9f8cb335dccd1d1832da1071d12290dab3b85b587ecacca6e level 0 process 'repro' launched './file2' with NULL argv: empty string added DEBUG: no csum root, idatacsums=0 ibadroots=134217728 Oops: general protection fault, probably for non-canonical address 0xdffffc0000000041: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000208-0x000000000000020f] CPU: 5 UID: 0 PID: 1010 Comm: repro Tainted: G OE 6.15.0-custom+ #249 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022 RIP: 0010:btrfs_lookup_csum+0x93/0x3d0 [btrfs] Call Trace: <TASK> btrfs_lookup_bio_sums+0x47a/0xdf0 [btrfs] btrfs_submit_bbio+0x43e/0x1a80 [btrfs] submit_one_bio+0xde/0x160 [btrfs] btrfs_readahead+0x498/0x6a0 [btrfs] read_pages+0x1c3/0xb20 page_cache_ra_order+0x4b5/0xc20 filemap_get_pages+0x2d3/0x19e0 filemap_read+0x314/0xde0 __kernel_read+0x35b/0x900 bprm_execve+0x62e/0x1140 do_execveat_common.isra.0+0x3fc/0x520 __x64_sys_execveat+0xdc/0x130 do_syscall_64+0x54/0x1d0 entry_SYSCALL_64_after_hwframe+0x76/0x7e ---[ end trace 0000000000000000 ]---
[CAUSE] Firstly the fs has a corrupted csum tree root, thus to mount the fs we have to go "ro,rescue=ibadroots" mount option.
Normally with that mount option, a bad csum tree root should set BTRFS_FS_STATE_NO_DATA_CSUMS flag, so that any future data read will ignore csum search.
But in this particular case, we have the following call trace that caused NULL csum root, but not setting BTRFS_FS_STATE_NO_DATA_CSUMS:
load_global_roots_objectid():
ret = btrfs_search_slot(); /* Succeeded */ btrfs_item_key_to_cpu() found = true; /* We found the root item for csum tree. */ root = read_tree_root_path(); if (IS_ERR(root)) { if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) /* * Since we have rescue=ibadroots mount option, * @ret is still 0. */ break; if (!found || ret) { /* @found is true, @ret is 0, error handling for csum * tree is skipped. */ }
This means we completely skipped to set BTRFS_FS_STATE_NO_DATA_CSUMS if the csum tree is corrupted, which results unexpected later csum lookup.
[FIX] If read_tree_root_path() failed, always populate @ret to the error number.
As at the end of the function, we need @ret to determine if we need to do the extra error handling for csum tree.
Fixes: abed4aaae4f7 ("btrfs: track the csum, extent, and free space trees in a rb tree") Reported-by: Zhiyu Zhang zhiyuzhang999@gmail.com Reported-by: Longxing Li coregee2000@gmail.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: Qu Wenruo wqu@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/disk-io.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 87501762d81fb..321feb99c1797 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2164,8 +2164,7 @@ static int load_global_roots_objectid(struct btrfs_root *tree_root, found = true; root = read_tree_root_path(tree_root, path, &key); if (IS_ERR(root)) { - if (!btrfs_test_opt(fs_info, IGNOREBADROOTS)) - ret = PTR_ERR(root); + ret = PTR_ERR(root); break; } set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä ville.syrjala@linux.intel.com
[ Upstream commit 25eeba495b2fc16037647c1a51bcdf6fc157af5c ]
The intel-media-driver is currently broken on DG1 because it uses EXEC_CAPTURE with recovarable contexts. Relax the check to allow that.
I've also submitted a fix for the intel-media-driver: https://github.com/intel/media-driver/pull/1920
Cc: stable@vger.kernel.org # v6.0+ Cc: Matthew Auld matthew.auld@intel.com Cc: Thomas Hellström thomas.hellstrom@linux.intel.com Testcase: igt/gem_exec_capture/capture-invisible Fixes: 71b1669ea9bd ("drm/i915/uapi: tweak error capture on recoverable contexts") Reviewed-by: Andi Shyti andi.shyti@linux.intel.com Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Signed-off-by: Andi Shyti andi.shyti@kernel.org Link: https://lore.kernel.org/r/20250411144313.11660-2-ville.syrjala@linux.intel.c... (cherry picked from commit d6e020819612a4a06207af858e0978be4d3e3140) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Stable-dep-of: ed5915cfce2a ("Revert "drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1"") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 7796c4119ef5e..1974a300b24a1 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2014,7 +2014,7 @@ static int eb_capture_stage(struct i915_execbuffer *eb) continue;
if (i915_gem_context_is_recoverable(eb->gem_context) && - (IS_DGFX(eb->i915) || GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 0))) + GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 10)) return -EINVAL;
for_each_batch_create_order(eb, j) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joonas Lahtinen joonas.lahtinen@linux.intel.com
[ Upstream commit ed5915cfce2abb9a553c3737badebd4a11d6c9c7 ]
This reverts commit d6e020819612a4a06207af858e0978be4d3e3140.
The IS_DGFX check was put in place because error capture of buffer objects is expected to be broken on devices with VRAM.
Userspace fix[1] to the impacted media driver has been submitted, merged and a new driver release is out as 25.2.3 where the capture flag is dropped on DG1 thus unblocking the usage of media driver on DG1.
[1] https://github.com/intel/media-driver/commit/93c07d9b4b96a78bab21f6acd4eb863...
Cc: stable@vger.kernel.org # v6.0+ Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Andi Shyti andi.shyti@linux.intel.com Cc: Matthew Auld matthew.auld@intel.com Cc: Thomas Hellström thomas.hellstrom@linux.intel.com Cc: Tvrtko Ursulin tursulin@ursulin.net Acked-by: Tvrtko Ursulin tvrtko.ursulin@igalia.com Reviewed-by: Andi Shyti andi.shyti@linux.intel.com Link: https://lore.kernel.org/r/20250522064127.24293-1-joonas.lahtinen@linux.intel... [Joonas: Update message to point out the merged userspace fix] Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com (cherry picked from commit d2dc30e0aa252830f908c8e793d3139d51321370) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c index 1974a300b24a1..7796c4119ef5e 100644 --- a/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/gem/i915_gem_execbuffer.c @@ -2014,7 +2014,7 @@ static int eb_capture_stage(struct i915_execbuffer *eb) continue;
if (i915_gem_context_is_recoverable(eb->gem_context) && - GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 10)) + (IS_DGFX(eb->i915) || GRAPHICS_VER_FULL(eb->i915) > IP_VER(12, 0))) return -EINVAL;
for_each_batch_create_order(eb, j) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Sterba dsterba@suse.com
[ Upstream commit 05a6ec865d091fe8244657df8063f74e704d1711 ]
The unsigned type is a recommended practice (CWE-190, CWE-194) for bit shifts to avoid problems with potential unwanted sign extensions. Although there are no such cases in btrfs codebase, follow the recommendation.
Reviewed-by: Boris Burkov boris@bur.io Signed-off-by: David Sterba dsterba@suse.com Stable-dep-of: 1f2889f5594a ("btrfs: fix qgroup reservation leak on failure to allocate ordered extent") Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/backref.h | 4 ++-- fs/btrfs/direct-io.c | 4 ++-- fs/btrfs/extent_io.h | 2 +- fs/btrfs/inode.c | 12 ++++++------ fs/btrfs/ordered-data.c | 4 ++-- fs/btrfs/raid56.c | 5 ++--- fs/btrfs/tests/extent-io-tests.c | 6 +++--- fs/btrfs/zstd.c | 2 +- 8 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h index 74e6140312747..953637115956b 100644 --- a/fs/btrfs/backref.h +++ b/fs/btrfs/backref.h @@ -423,8 +423,8 @@ struct btrfs_backref_node *btrfs_backref_alloc_node( struct btrfs_backref_edge *btrfs_backref_alloc_edge( struct btrfs_backref_cache *cache);
-#define LINK_LOWER (1 << 0) -#define LINK_UPPER (1 << 1) +#define LINK_LOWER (1U << 0) +#define LINK_UPPER (1U << 1)
void btrfs_backref_link_edge(struct btrfs_backref_edge *edge, struct btrfs_backref_node *lower, diff --git a/fs/btrfs/direct-io.c b/fs/btrfs/direct-io.c index a374ce7a1813b..7900cba56225d 100644 --- a/fs/btrfs/direct-io.c +++ b/fs/btrfs/direct-io.c @@ -151,8 +151,8 @@ static struct extent_map *btrfs_create_dio_extent(struct btrfs_inode *inode, }
ordered = btrfs_alloc_ordered_extent(inode, start, file_extent, - (1 << type) | - (1 << BTRFS_ORDERED_DIRECT)); + (1U << type) | + (1U << BTRFS_ORDERED_DIRECT)); if (IS_ERR(ordered)) { if (em) { free_extent_map(em); diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index f5b28b5c4908b..91d9cb5ff401b 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -79,7 +79,7 @@ enum { * single word in a bitmap may straddle two pages in the extent buffer. */ #define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) -#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1) +#define BYTE_MASK ((1U << BITS_PER_BYTE) - 1) #define BITMAP_FIRST_BYTE_MASK(start) \ ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK) #define BITMAP_LAST_BYTE_MASK(nbits) \ diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8a3f44302788c..867b438652ef7 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -1171,7 +1171,7 @@ static void submit_one_async_extent(struct async_chunk *async_chunk, free_extent_map(em);
ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent, - 1 << BTRFS_ORDERED_COMPRESSED); + 1U << BTRFS_ORDERED_COMPRESSED); if (IS_ERR(ordered)) { btrfs_drop_extent_map_range(inode, start, end, false); ret = PTR_ERR(ordered); @@ -1418,7 +1418,7 @@ static noinline int cow_file_range(struct btrfs_inode *inode, free_extent_map(em);
ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent, - 1 << BTRFS_ORDERED_REGULAR); + 1U << BTRFS_ORDERED_REGULAR); if (IS_ERR(ordered)) { unlock_extent(&inode->io_tree, start, start + cur_alloc_size - 1, &cached); @@ -1999,8 +1999,8 @@ static int nocow_one_range(struct btrfs_inode *inode, struct folio *locked_folio
ordered = btrfs_alloc_ordered_extent(inode, file_pos, &nocow_args->file_extent, is_prealloc - ? (1 << BTRFS_ORDERED_PREALLOC) - : (1 << BTRFS_ORDERED_NOCOW)); + ? (1U << BTRFS_ORDERED_PREALLOC) + : (1U << BTRFS_ORDERED_NOCOW)); if (IS_ERR(ordered)) { if (is_prealloc) btrfs_drop_extent_map_range(inode, file_pos, end, false); @@ -9733,8 +9733,8 @@ ssize_t btrfs_do_encoded_write(struct kiocb *iocb, struct iov_iter *from, free_extent_map(em);
ordered = btrfs_alloc_ordered_extent(inode, start, &file_extent, - (1 << BTRFS_ORDERED_ENCODED) | - (1 << BTRFS_ORDERED_COMPRESSED)); + (1U << BTRFS_ORDERED_ENCODED) | + (1U << BTRFS_ORDERED_COMPRESSED)); if (IS_ERR(ordered)) { btrfs_drop_extent_map_range(inode, start, end, false); ret = PTR_ERR(ordered); diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 03c945711003c..f61b0bb1faccf 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -155,7 +155,7 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( u64 qgroup_rsv = 0;
if (flags & - ((1 << BTRFS_ORDERED_NOCOW) | (1 << BTRFS_ORDERED_PREALLOC))) { + ((1U << BTRFS_ORDERED_NOCOW) | (1U << BTRFS_ORDERED_PREALLOC))) { /* For nocow write, we can release the qgroup rsv right now */ ret = btrfs_qgroup_free_data(inode, NULL, file_offset, num_bytes, &qgroup_rsv); if (ret < 0) @@ -253,7 +253,7 @@ static void insert_ordered_extent(struct btrfs_ordered_extent *entry) * @disk_bytenr: Offset of extent on disk. * @disk_num_bytes: Size of extent on disk. * @offset: Offset into unencoded data where file data starts. - * @flags: Flags specifying type of extent (1 << BTRFS_ORDERED_*). + * @flags: Flags specifying type of extent (1U << BTRFS_ORDERED_*). * @compress_type: Compression algorithm used for data. * * Most of these parameters correspond to &struct btrfs_file_extent_item. The diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index cdd373c277848..7285bf7926e3a 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c @@ -200,8 +200,7 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info) struct btrfs_stripe_hash_table *x; struct btrfs_stripe_hash *cur; struct btrfs_stripe_hash *h; - int num_entries = 1 << BTRFS_STRIPE_HASH_TABLE_BITS; - int i; + unsigned int num_entries = 1U << BTRFS_STRIPE_HASH_TABLE_BITS;
if (info->stripe_hash_table) return 0; @@ -222,7 +221,7 @@ int btrfs_alloc_stripe_hash_table(struct btrfs_fs_info *info)
h = table->table;
- for (i = 0; i < num_entries; i++) { + for (unsigned int i = 0; i < num_entries; i++) { cur = h + i; INIT_LIST_HEAD(&cur->hash_list); spin_lock_init(&cur->lock); diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index 74aca7180a5a9..400574c6e82ec 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c @@ -14,9 +14,9 @@ #include "../disk-io.h" #include "../btrfs_inode.h"
-#define PROCESS_UNLOCK (1 << 0) -#define PROCESS_RELEASE (1 << 1) -#define PROCESS_TEST_LOCKED (1 << 2) +#define PROCESS_UNLOCK (1U << 0) +#define PROCESS_RELEASE (1U << 1) +#define PROCESS_TEST_LOCKED (1U << 2)
static noinline int process_page_range(struct inode *inode, u64 start, u64 end, unsigned long flags) diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c index 3541efa765c73..94c19331823a9 100644 --- a/fs/btrfs/zstd.c +++ b/fs/btrfs/zstd.c @@ -24,7 +24,7 @@ #include "super.h"
#define ZSTD_BTRFS_MAX_WINDOWLOG 17 -#define ZSTD_BTRFS_MAX_INPUT (1 << ZSTD_BTRFS_MAX_WINDOWLOG) +#define ZSTD_BTRFS_MAX_INPUT (1U << ZSTD_BTRFS_MAX_WINDOWLOG) #define ZSTD_BTRFS_DEFAULT_LEVEL 3 #define ZSTD_BTRFS_MIN_LEVEL -15 #define ZSTD_BTRFS_MAX_LEVEL 15
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana fdmanana@suse.com
[ Upstream commit 1f2889f5594a2bc4c6a52634c4a51b93e785def5 ]
If we fail to allocate an ordered extent for a COW write we end up leaking a qgroup data reservation since we called btrfs_qgroup_release_data() but we didn't call btrfs_qgroup_free_refroot() (which would happen when running the respective data delayed ref created by ordered extent completion or when finishing the ordered extent in case an error happened).
So make sure we call btrfs_qgroup_free_refroot() if we fail to allocate an ordered extent for a COW write.
Fixes: 7dbeaad0af7d ("btrfs: change timing for qgroup reserved space for ordered extents to fix reserved space leak") CC: stable@vger.kernel.org # 6.1+ Reviewed-by: Boris Burkov boris@bur.io Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/ordered-data.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index f61b0bb1faccf..1d7ddd664c0d3 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -153,9 +153,10 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( struct btrfs_ordered_extent *entry; int ret; u64 qgroup_rsv = 0; + const bool is_nocow = (flags & + ((1U << BTRFS_ORDERED_NOCOW) | (1U << BTRFS_ORDERED_PREALLOC)));
- if (flags & - ((1U << BTRFS_ORDERED_NOCOW) | (1U << BTRFS_ORDERED_PREALLOC))) { + if (is_nocow) { /* For nocow write, we can release the qgroup rsv right now */ ret = btrfs_qgroup_free_data(inode, NULL, file_offset, num_bytes, &qgroup_rsv); if (ret < 0) @@ -170,8 +171,13 @@ static struct btrfs_ordered_extent *alloc_ordered_extent( return ERR_PTR(ret); } entry = kmem_cache_zalloc(btrfs_ordered_extent_cache, GFP_NOFS); - if (!entry) + if (!entry) { + if (!is_nocow) + btrfs_qgroup_free_refroot(inode->root->fs_info, + btrfs_root_id(inode->root), + qgroup_rsv, BTRFS_QGROUP_RSV_DATA); return ERR_PTR(-ENOMEM); + }
entry->file_offset = file_offset; entry->num_bytes = num_bytes;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit 14f6e205e5599c2217b68c05b903ce162e7c1e27 ]
Add a variable in the file handle state to figure out if a camera is in the streaming state or not. This variable will be used in the future for power management policies.
Now that we are at it, make use of guards to simplify the code.
Reviewed-by: Laurent Pinchart laurent.pinchart@ideasonboard.com Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Ricardo Ribalda ribalda@chromium.org Message-ID: 20250327-uvc-granpower-ng-v6-1-35a2357ff348@chromium.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: a70705d3c020 ("media: uvcvideo: Rollback non processed entities on error") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_v4l2.c | 18 +++++++++++++----- drivers/media/usb/uvc/uvcvideo.h | 1 + 2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 39065db44e864..22886b47d81c2 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -841,11 +841,18 @@ static int uvc_ioctl_streamon(struct file *file, void *fh, if (!uvc_has_privileges(handle)) return -EBUSY;
- mutex_lock(&stream->mutex); + guard(mutex)(&stream->mutex); + + if (handle->is_streaming) + return 0; + ret = uvc_queue_streamon(&stream->queue, type); - mutex_unlock(&stream->mutex); + if (ret) + return ret;
- return ret; + handle->is_streaming = true; + + return 0; }
static int uvc_ioctl_streamoff(struct file *file, void *fh, @@ -857,9 +864,10 @@ static int uvc_ioctl_streamoff(struct file *file, void *fh, if (!uvc_has_privileges(handle)) return -EBUSY;
- mutex_lock(&stream->mutex); + guard(mutex)(&stream->mutex); + uvc_queue_streamoff(&stream->queue, type); - mutex_unlock(&stream->mutex); + handle->is_streaming = false;
return 0; } diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index b4ee701835fc0..5ceb01e7831a8 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -630,6 +630,7 @@ struct uvc_fh { struct uvc_streaming *stream; enum uvc_handle_state state; unsigned int pending_async_ctrls; + bool is_streaming; };
/* ------------------------------------------------------------------------
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit 2f101572c0a3ae4630f2a57c8033b78ee84ac5a6 ]
Most of the times that we have to call uvc_status_(get|put) we need to call the usb_autopm_ functions.
Create a new pair of functions that automate this for us. This simplifies the current code and future PM changes in the driver.
Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Ricardo Ribalda ribalda@chromium.org Message-ID: 20250327-uvc-granpower-ng-v6-2-35a2357ff348@chromium.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: a70705d3c020 ("media: uvcvideo: Rollback non processed entities on error") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_v4l2.c | 36 +++++++++++++++++++++----------- drivers/media/usb/uvc/uvcvideo.h | 4 ++++ 2 files changed, 28 insertions(+), 12 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 22886b47d81c2..1d5be045d04ec 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -26,6 +26,27 @@
#include "uvcvideo.h"
+int uvc_pm_get(struct uvc_device *dev) +{ + int ret; + + ret = usb_autopm_get_interface(dev->intf); + if (ret) + return ret; + + ret = uvc_status_get(dev); + if (ret) + usb_autopm_put_interface(dev->intf); + + return ret; +} + +void uvc_pm_put(struct uvc_device *dev) +{ + uvc_status_put(dev); + usb_autopm_put_interface(dev->intf); +} + static int uvc_acquire_privileges(struct uvc_fh *handle);
static int uvc_control_add_xu_mapping(struct uvc_video_chain *chain, @@ -642,20 +663,13 @@ static int uvc_v4l2_open(struct file *file) stream = video_drvdata(file); uvc_dbg(stream->dev, CALLS, "%s\n", __func__);
- ret = usb_autopm_get_interface(stream->dev->intf); - if (ret < 0) - return ret; - /* Create the device handle. */ handle = kzalloc(sizeof(*handle), GFP_KERNEL); - if (handle == NULL) { - usb_autopm_put_interface(stream->dev->intf); + if (!handle) return -ENOMEM; - }
- ret = uvc_status_get(stream->dev); + ret = uvc_pm_get(stream->dev); if (ret) { - usb_autopm_put_interface(stream->dev->intf); kfree(handle); return ret; } @@ -690,9 +704,7 @@ static int uvc_v4l2_release(struct file *file) kfree(handle); file->private_data = NULL;
- uvc_status_put(stream->dev); - - usb_autopm_put_interface(stream->dev->intf); + uvc_pm_put(stream->dev); return 0; }
diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 5ceb01e7831a8..b9f8eb62ba1d8 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -768,6 +768,10 @@ void uvc_status_suspend(struct uvc_device *dev); int uvc_status_get(struct uvc_device *dev); void uvc_status_put(struct uvc_device *dev);
+/* PM */ +int uvc_pm_get(struct uvc_device *dev); +void uvc_pm_put(struct uvc_device *dev); + /* Controls */ extern const struct v4l2_subscribed_event_ops uvc_ctrl_sub_ev_ops;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit 10acb9101355484c3e4f2625003cd1b6c203cfe4 ]
Now we call uvc_pm_get/put from the device open/close. This low level of granularity might leave the camera powered on in situations where it is not needed.
Increase the granularity by increasing and decreasing the Power Management counter per ioctl. There are two special cases where the power management outlives the ioctl: async controls and streamon. Handle those cases as well.
In a future patch, we will remove the uvc_pm_get/put from open/close.
Reviewed-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Ricardo Ribalda ribalda@chromium.org Message-ID: 20250327-uvc-granpower-ng-v6-3-35a2357ff348@chromium.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: a70705d3c020 ("media: uvcvideo: Rollback non processed entities on error") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_ctrl.c | 38 ++++++++++++++++++++++--------- drivers/media/usb/uvc/uvc_v4l2.c | 39 ++++++++++++++++++++++++++++++-- 2 files changed, 64 insertions(+), 13 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index bc7e2005fc6c7..636ce1eb2a6bf 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -1812,38 +1812,49 @@ static void uvc_ctrl_send_slave_event(struct uvc_video_chain *chain, uvc_ctrl_send_event(chain, handle, ctrl, mapping, val, changes); }
-static void uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, - struct uvc_fh *new_handle) +static int uvc_ctrl_set_handle(struct uvc_fh *handle, struct uvc_control *ctrl, + struct uvc_fh *new_handle) { lockdep_assert_held(&handle->chain->ctrl_mutex);
if (new_handle) { + int ret; + if (ctrl->handle) dev_warn_ratelimited(&handle->stream->dev->udev->dev, "UVC non compliance: Setting an async control with a pending operation.");
if (new_handle == ctrl->handle) - return; + return 0;
if (ctrl->handle) { WARN_ON(!ctrl->handle->pending_async_ctrls); if (ctrl->handle->pending_async_ctrls) ctrl->handle->pending_async_ctrls--; + ctrl->handle = new_handle; + handle->pending_async_ctrls++; + return 0; }
+ ret = uvc_pm_get(handle->chain->dev); + if (ret) + return ret; + ctrl->handle = new_handle; handle->pending_async_ctrls++; - return; + return 0; }
/* Cannot clear the handle for a control not owned by us.*/ if (WARN_ON(ctrl->handle != handle)) - return; + return -EINVAL;
ctrl->handle = NULL; if (WARN_ON(!handle->pending_async_ctrls)) - return; + return -EINVAL; handle->pending_async_ctrls--; + uvc_pm_put(handle->chain->dev); + return 0; }
void uvc_ctrl_status_event(struct uvc_video_chain *chain, @@ -2150,15 +2161,15 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
ctrl->dirty = 0;
+ if (!rollback && handle && !ret && + ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) + ret = uvc_ctrl_set_handle(handle, ctrl, handle); + if (ret < 0) { if (err_ctrl) *err_ctrl = ctrl; return ret; } - - if (!rollback && handle && - ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) - uvc_ctrl_set_handle(handle, ctrl, handle); }
return processed_ctrls; @@ -3237,6 +3248,7 @@ int uvc_ctrl_init_device(struct uvc_device *dev) void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) { struct uvc_entity *entity; + int i;
guard(mutex)(&handle->chain->ctrl_mutex);
@@ -3251,7 +3263,11 @@ void uvc_ctrl_cleanup_fh(struct uvc_fh *handle) } }
- WARN_ON(handle->pending_async_ctrls); + if (!WARN_ON(handle->pending_async_ctrls)) + return; + + for (i = 0; i < handle->pending_async_ctrls; i++) + uvc_pm_put(handle->stream->dev); }
/* diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c index 1d5be045d04ec..8bccf7e17528b 100644 --- a/drivers/media/usb/uvc/uvc_v4l2.c +++ b/drivers/media/usb/uvc/uvc_v4l2.c @@ -697,6 +697,9 @@ static int uvc_v4l2_release(struct file *file) if (uvc_has_privileges(handle)) uvc_queue_release(&stream->queue);
+ if (handle->is_streaming) + uvc_pm_put(stream->dev); + /* Release the file handle. */ uvc_dismiss_privileges(handle); v4l2_fh_del(&handle->vfh); @@ -862,6 +865,11 @@ static int uvc_ioctl_streamon(struct file *file, void *fh, if (ret) return ret;
+ ret = uvc_pm_get(stream->dev); + if (ret) { + uvc_queue_streamoff(&stream->queue, type); + return ret; + } handle->is_streaming = true;
return 0; @@ -879,7 +887,10 @@ static int uvc_ioctl_streamoff(struct file *file, void *fh, guard(mutex)(&stream->mutex);
uvc_queue_streamoff(&stream->queue, type); - handle->is_streaming = false; + if (handle->is_streaming) { + handle->is_streaming = false; + uvc_pm_put(stream->dev); + }
return 0; } @@ -1378,9 +1389,11 @@ static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp, #define UVCIOC_CTRL_MAP32 _IOWR('u', 0x20, struct uvc_xu_control_mapping32) #define UVCIOC_CTRL_QUERY32 _IOWR('u', 0x21, struct uvc_xu_control_query32)
+DEFINE_FREE(uvc_pm_put, struct uvc_device *, if (_T) uvc_pm_put(_T)) static long uvc_v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) { + struct uvc_device *uvc_device __free(uvc_pm_put) = NULL; struct uvc_fh *handle = file->private_data; union { struct uvc_xu_control_mapping xmap; @@ -1389,6 +1402,12 @@ static long uvc_v4l2_compat_ioctl32(struct file *file, void __user *up = compat_ptr(arg); long ret;
+ ret = uvc_pm_get(handle->stream->dev); + if (ret) + return ret; + + uvc_device = handle->stream->dev; + switch (cmd) { case UVCIOC_CTRL_MAP32: ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up); @@ -1423,6 +1442,22 @@ static long uvc_v4l2_compat_ioctl32(struct file *file, } #endif
+static long uvc_v4l2_unlocked_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + struct uvc_fh *handle = file->private_data; + int ret; + + ret = uvc_pm_get(handle->stream->dev); + if (ret) + return ret; + + ret = video_ioctl2(file, cmd, arg); + + uvc_pm_put(handle->stream->dev); + return ret; +} + static ssize_t uvc_v4l2_read(struct file *file, char __user *data, size_t count, loff_t *ppos) { @@ -1507,7 +1542,7 @@ const struct v4l2_file_operations uvc_fops = { .owner = THIS_MODULE, .open = uvc_v4l2_open, .release = uvc_v4l2_release, - .unlocked_ioctl = video_ioctl2, + .unlocked_ioctl = uvc_v4l2_unlocked_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl32 = uvc_v4l2_compat_ioctl32, #endif
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ricardo Ribalda ribalda@chromium.org
[ Upstream commit a70705d3c020d0d5c3ab6a5cc93e011ac35e7d48 ]
If we fail to commit an entity, we need to restore the UVC_CTRL_DATA_BACKUP for the other uncommitted entities. Otherwise the control cache and the device would be out of sync.
Cc: stable@kernel.org Fixes: b4012002f3a3 ("[media] uvcvideo: Add support for control events") Reported-by: Hans de Goede hdegoede@redhat.com Closes: https://lore.kernel.org/linux-media/fe845e04-9fde-46ee-9763-a6f00867929a@red... Signed-off-by: Ricardo Ribalda ribalda@chromium.org Message-ID: 20250224-uvc-data-backup-v2-3-de993ed9823b@chromium.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/usb/uvc/uvc_ctrl.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-)
diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c index 636ce1eb2a6bf..44b6513c52642 100644 --- a/drivers/media/usb/uvc/uvc_ctrl.c +++ b/drivers/media/usb/uvc/uvc_ctrl.c @@ -2119,7 +2119,7 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, unsigned int processed_ctrls = 0; struct uvc_control *ctrl; unsigned int i; - int ret; + int ret = 0;
if (entity == NULL) return 0; @@ -2148,8 +2148,6 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, dev->intfnum, ctrl->info.selector, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), ctrl->info.size); - else - ret = 0;
if (!ret) processed_ctrls++; @@ -2165,13 +2163,20 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, ctrl->info.flags & UVC_CTRL_FLAG_ASYNCHRONOUS) ret = uvc_ctrl_set_handle(handle, ctrl, handle);
- if (ret < 0) { + if (ret < 0 && !rollback) { if (err_ctrl) *err_ctrl = ctrl; - return ret; + /* + * If we fail to set a control, we need to rollback + * the next ones. + */ + rollback = 1; } }
+ if (ret) + return ret; + return processed_ctrls; }
@@ -2202,7 +2207,8 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, struct uvc_video_chain *chain = handle->chain; struct uvc_control *err_ctrl; struct uvc_entity *entity; - int ret = 0; + int ret_out = 0; + int ret;
/* Find the control. */ list_for_each_entry(entity, &chain->entities, chain) { @@ -2213,17 +2219,23 @@ int __uvc_ctrl_commit(struct uvc_fh *handle, int rollback, ctrls->error_idx = uvc_ctrl_find_ctrl_idx(entity, ctrls, err_ctrl); - goto done; + /* + * When we fail to commit an entity, we need to + * restore the UVC_CTRL_DATA_BACKUP for all the + * controls in the other entities, otherwise our cache + * and the hardware will be out of sync. + */ + rollback = 1; + + ret_out = ret; } else if (ret > 0 && !rollback) { uvc_ctrl_send_events(handle, entity, ctrls->controls, ctrls->count); } }
- ret = 0; -done: mutex_unlock(&chain->ctrl_mutex); - return ret; + return ret_out; }
static int uvc_mapping_get_xctrl_compound(struct uvc_video_chain *chain,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan peng.fan@nxp.com
[ Upstream commit d5099bc1b56417733f4cccf10c61ee74dadd5562 ]
of_gpio.h is deprecated, update the driver to use GPIO descriptors. - Use dev_gpiod_get to get GPIO descriptor. - Use gpiod_set_value to configure output value.
With legacy of_gpio API, the driver set gpio value 0 to assert reset, and 1 to deassert reset. And the reset-gpios use GPIO_ACTIVE_LOW flag in DTS, so set GPIOD_OUT_LOW when get GPIO descriptors, and set value 1 means output low, set value 0 means output high with gpiod API.
The in-tree DTS files have the right polarity set up already so we can expect this to "just work"
Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Peng Fan peng.fan@nxp.com Link: https://patch.msgid.link/20250324-wcd-gpiod-v2-3-773f67ce3b56@nxp.com Reviewed-by: Bartosz Golaszewski bartosz.golaszewski@linaro.org Signed-off-by: Mark Brown broonie@kernel.org Stable-dep-of: 9079db287fc3 ("ASoC: codecs: wcd9335: Fix missing free of regulator supplies") Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/wcd9335.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 7cef43bb2a880..8ee4360aff929 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -17,7 +17,7 @@ #include <sound/soc.h> #include <sound/pcm_params.h> #include <sound/soc-dapm.h> -#include <linux/of_gpio.h> +#include <linux/gpio/consumer.h> #include <linux/of.h> #include <linux/of_irq.h> #include <sound/tlv.h> @@ -331,7 +331,7 @@ struct wcd9335_codec { int comp_enabled[COMPANDER_MAX];
int intr1; - int reset_gpio; + struct gpio_desc *reset_gpio; struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
unsigned int rx_port_value[WCD9335_RX_MAX]; @@ -4975,12 +4975,11 @@ static const struct regmap_irq_chip wcd9335_regmap_irq1_chip = { static int wcd9335_parse_dt(struct wcd9335_codec *wcd) { struct device *dev = wcd->dev; - struct device_node *np = dev->of_node; int ret;
- wcd->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0); - if (wcd->reset_gpio < 0) - return dev_err_probe(dev, wcd->reset_gpio, "Reset GPIO missing from DT\n"); + wcd->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(wcd->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(wcd->reset_gpio), "Reset GPIO missing from DT\n");
wcd->mclk = devm_clk_get(dev, "mclk"); if (IS_ERR(wcd->mclk)) @@ -5023,9 +5022,9 @@ static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) */ usleep_range(600, 650);
- gpio_direction_output(wcd->reset_gpio, 0); + gpiod_set_value(wcd->reset_gpio, 1); msleep(20); - gpio_set_value(wcd->reset_gpio, 1); + gpiod_set_value(wcd->reset_gpio, 0); msleep(20);
return 0;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit 9079db287fc3e38e040b0edeb0a25770bb679c8e ]
Driver gets and enables all regulator supplies in probe path (wcd9335_parse_dt() and wcd9335_power_on_reset()), but does not cleanup in final error paths and in unbind (missing remove() callback). This leads to leaked memory and unbalanced regulator enable count during probe errors or unbind.
Fix this by converting entire code into devm_regulator_bulk_get_enable() which also greatly simplifies the code.
Fixes: 20aedafdf492 ("ASoC: wcd9335: add support to wcd9335 codec") Cc: stable@vger.kernel.org Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Link: https://patch.msgid.link/20250526-b4-b4-asoc-wcd9395-vdd-px-fixes-v1-1-0b8a2... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/wcd9335.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-)
diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 8ee4360aff929..5e19e813748df 100644 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -332,7 +332,6 @@ struct wcd9335_codec {
int intr1; struct gpio_desc *reset_gpio; - struct regulator_bulk_data supplies[WCD9335_MAX_SUPPLY];
unsigned int rx_port_value[WCD9335_RX_MAX]; unsigned int tx_port_value[WCD9335_TX_MAX]; @@ -355,6 +354,10 @@ struct wcd9335_irq { char *name; };
+static const char * const wcd9335_supplies[] = { + "vdd-buck", "vdd-buck-sido", "vdd-tx", "vdd-rx", "vdd-io", +}; + static const struct wcd9335_slim_ch wcd9335_tx_chs[WCD9335_TX_MAX] = { WCD9335_SLIM_TX_CH(0), WCD9335_SLIM_TX_CH(1), @@ -4989,30 +4992,16 @@ static int wcd9335_parse_dt(struct wcd9335_codec *wcd) if (IS_ERR(wcd->native_clk)) return dev_err_probe(dev, PTR_ERR(wcd->native_clk), "slimbus clock not found\n");
- wcd->supplies[0].supply = "vdd-buck"; - wcd->supplies[1].supply = "vdd-buck-sido"; - wcd->supplies[2].supply = "vdd-tx"; - wcd->supplies[3].supply = "vdd-rx"; - wcd->supplies[4].supply = "vdd-io"; - - ret = regulator_bulk_get(dev, WCD9335_MAX_SUPPLY, wcd->supplies); + ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(wcd9335_supplies), + wcd9335_supplies); if (ret) - return dev_err_probe(dev, ret, "Failed to get supplies\n"); + return dev_err_probe(dev, ret, "Failed to get and enable supplies\n");
return 0; }
static int wcd9335_power_on_reset(struct wcd9335_codec *wcd) { - struct device *dev = wcd->dev; - int ret; - - ret = regulator_bulk_enable(WCD9335_MAX_SUPPLY, wcd->supplies); - if (ret) { - dev_err(dev, "Failed to get supplies: err = %d\n", ret); - return ret; - } - /* * For WCD9335, it takes about 600us for the Vout_A and * Vout_D to be ready after BUCK_SIDO is powered up.
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu chao@kernel.org
[ Upstream commit a9201960623287927bf5776de3f70fb2fbde7e02 ]
This fixes an analogus bug that was fixed in modern filesystems: a) xfs in commit 4b8d867ca6e2 ("xfs: don't over-report free space or inodes in statvfs") b) ext4 in commit f87d3af74193 ("ext4: don't over-report free space or inodes in statvfs") where statfs can report misleading / incorrect information where project quota is enabled, and the free space is less than the remaining quota.
This commit will resolve a test failure in generic/762 which tests for this bug.
generic/762 - output mismatch (see /share/git/fstests/results//generic/762.out.bad) # --- tests/generic/762.out 2025-04-15 10:21:53.371067071 +0800 # +++ /share/git/fstests/results//generic/762.out.bad 2025-05-13 16:13:37.000000000 +0800 # @@ -6,8 +6,10 @@ # root blocks2 is in range # dir blocks2 is in range # root bavail2 is in range # -dir bavail2 is in range # +dir bavail2 has value of 1539066 # +dir bavail2 is NOT in range 304734.87 .. 310891.13 # root blocks3 is in range # ... # (Run 'diff -u /share/git/fstests/tests/generic/762.out /share/git/fstests/results//generic/762.out.bad' to see the entire diff)
HINT: You _MAY_ be missing kernel fix: XXXXXXXXXXXXXX xfs: don't over-report free space or inodes in statvfs
Cc: stable@kernel.org Fixes: ddc34e328d06 ("f2fs: introduce f2fs_statfs_project") Signed-off-by: Chao Yu chao@kernel.org Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/f2fs/super.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index bc510c91f3eba..86dd30eb50b1d 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -1806,26 +1806,32 @@ static int f2fs_statfs_project(struct super_block *sb,
limit = min_not_zero(dquot->dq_dqb.dqb_bsoftlimit, dquot->dq_dqb.dqb_bhardlimit); - if (limit) - limit >>= sb->s_blocksize_bits; + limit >>= sb->s_blocksize_bits; + + if (limit) { + uint64_t remaining = 0;
- if (limit && buf->f_blocks > limit) { curblock = (dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace) >> sb->s_blocksize_bits; - buf->f_blocks = limit; - buf->f_bfree = buf->f_bavail = - (buf->f_blocks > curblock) ? - (buf->f_blocks - curblock) : 0; + if (limit > curblock) + remaining = limit - curblock; + + buf->f_blocks = min(buf->f_blocks, limit); + buf->f_bfree = min(buf->f_bfree, remaining); + buf->f_bavail = min(buf->f_bavail, remaining); }
limit = min_not_zero(dquot->dq_dqb.dqb_isoftlimit, dquot->dq_dqb.dqb_ihardlimit);
- if (limit && buf->f_files > limit) { - buf->f_files = limit; - buf->f_ffree = - (buf->f_files > dquot->dq_dqb.dqb_curinodes) ? - (buf->f_files - dquot->dq_dqb.dqb_curinodes) : 0; + if (limit) { + uint64_t remaining = 0; + + if (limit > dquot->dq_dqb.dqb_curinodes) + remaining = limit - dquot->dq_dqb.dqb_curinodes; + + buf->f_files = min(buf->f_files, limit); + buf->f_ffree = min(buf->f_ffree, remaining); }
spin_unlock(&dquot->dq_dqb_lock);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
[ Upstream commit a79154ae5df9e21dbacb1eb77fad984fd4c45cca ]
We'll need io_zcrx_iov_page at the top to keep offset calculations closer together, move it there.
Reviewed-by: David Wei dw@davidwei.uk Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/575617033a8b84a5985c7eb760b7121efdbe7e56.174514126... Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: 0ec33c81d9c7 ("io_uring/zcrx: fix area release on registration failure") Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/zcrx.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index fe86606b9f304..ecb59182d9b2c 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -31,6 +31,20 @@ static inline struct io_zcrx_ifq *io_pp_to_ifq(struct page_pool *pp) return pp->mp_priv; }
+static inline struct io_zcrx_area *io_zcrx_iov_to_area(const struct net_iov *niov) +{ + struct net_iov_area *owner = net_iov_owner(niov); + + return container_of(owner, struct io_zcrx_area, nia); +} + +static inline struct page *io_zcrx_iov_page(const struct net_iov *niov) +{ + struct io_zcrx_area *area = io_zcrx_iov_to_area(niov); + + return area->pages[net_iov_idx(niov)]; +} + #define IO_DMA_ATTR (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING)
static void __io_zcrx_unmap_area(struct io_zcrx_ifq *ifq, @@ -118,13 +132,6 @@ struct io_zcrx_args {
static const struct memory_provider_ops io_uring_pp_zc_ops;
-static inline struct io_zcrx_area *io_zcrx_iov_to_area(const struct net_iov *niov) -{ - struct net_iov_area *owner = net_iov_owner(niov); - - return container_of(owner, struct io_zcrx_area, nia); -} - static inline atomic_t *io_get_user_counter(struct net_iov *niov) { struct io_zcrx_area *area = io_zcrx_iov_to_area(niov); @@ -147,13 +154,6 @@ static void io_zcrx_get_niov_uref(struct net_iov *niov) atomic_inc(io_get_user_counter(niov)); }
-static inline struct page *io_zcrx_iov_page(const struct net_iov *niov) -{ - struct io_zcrx_area *area = io_zcrx_iov_to_area(niov); - - return area->pages[net_iov_idx(niov)]; -} - static int io_allocate_rbuf_ring(struct io_zcrx_ifq *ifq, struct io_uring_zcrx_ifq_reg *reg, struct io_uring_region_desc *rd)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
[ Upstream commit d760d3f59f0d8d0df2895db30d36cf23106d6b05 ]
dmabuf backed area will be taking an offset instead of addresses, and io_buffer_validate() is not flexible enough to facilitate it. It also takes an iovec, which may truncate the u64 length zcrx takes. Add a new helper function for validation.
Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/0b3b735391a0a8f8971bf0121c19765131fddd3b.174609743... Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: 0ec33c81d9c7 ("io_uring/zcrx: fix area release on registration failure") Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/rsrc.c | 27 +++++++++++++++------------ io_uring/rsrc.h | 2 +- io_uring/zcrx.c | 7 +++---- 3 files changed, 19 insertions(+), 17 deletions(-)
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index 794d4ae6f0bc8..6d61683223870 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -80,10 +80,21 @@ static int io_account_mem(struct io_ring_ctx *ctx, unsigned long nr_pages) return 0; }
-int io_buffer_validate(struct iovec *iov) +int io_validate_user_buf_range(u64 uaddr, u64 ulen) { - unsigned long tmp, acct_len = iov->iov_len + (PAGE_SIZE - 1); + unsigned long tmp, base = (unsigned long)uaddr; + unsigned long acct_len = (unsigned long)PAGE_ALIGN(ulen);
+ /* arbitrary limit, but we need something */ + if (ulen > SZ_1G || !ulen) + return -EFAULT; + if (check_add_overflow(base, acct_len, &tmp)) + return -EOVERFLOW; + return 0; +} + +static int io_buffer_validate(struct iovec *iov) +{ /* * Don't impose further limits on the size and buffer * constraints here, we'll -EINVAL later when IO is @@ -91,17 +102,9 @@ int io_buffer_validate(struct iovec *iov) */ if (!iov->iov_base) return iov->iov_len ? -EFAULT : 0; - if (!iov->iov_len) - return -EFAULT; - - /* arbitrary limit, but we need something */ - if (iov->iov_len > SZ_1G) - return -EFAULT;
- if (check_add_overflow((unsigned long)iov->iov_base, acct_len, &tmp)) - return -EOVERFLOW; - - return 0; + return io_validate_user_buf_range((unsigned long)iov->iov_base, + iov->iov_len); }
static void io_release_ubuf(void *priv) diff --git a/io_uring/rsrc.h b/io_uring/rsrc.h index b52242852ff34..4373524f993c7 100644 --- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -83,7 +83,7 @@ int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg, unsigned size, unsigned type); int io_register_rsrc(struct io_ring_ctx *ctx, void __user *arg, unsigned int size, unsigned int type); -int io_buffer_validate(struct iovec *iov); +int io_validate_user_buf_range(u64 uaddr, u64 ulen);
bool io_check_coalesce_buffer(struct page **page_array, int nr_pages, struct io_imu_folio_data *data); diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index ecb59182d9b2c..0771a57d81a5b 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -205,7 +205,6 @@ static int io_zcrx_create_area(struct io_zcrx_ifq *ifq, { struct io_zcrx_area *area; int i, ret, nr_pages, nr_iovs; - struct iovec iov;
if (area_reg->flags || area_reg->rq_area_token) return -EINVAL; @@ -214,11 +213,11 @@ static int io_zcrx_create_area(struct io_zcrx_ifq *ifq, if (area_reg->addr & ~PAGE_MASK || area_reg->len & ~PAGE_MASK) return -EINVAL;
- iov.iov_base = u64_to_user_ptr(area_reg->addr); - iov.iov_len = area_reg->len; - ret = io_buffer_validate(&iov); + ret = io_validate_user_buf_range(area_reg->addr, area_reg->len); if (ret) return ret; + if (!area_reg->addr) + return -EFAULT;
ret = -ENOMEM; area = kzalloc(sizeof(*area), GFP_KERNEL);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
[ Upstream commit 782dfa329ac9d1b5ca7b6df56a7696bac58cb829 ]
In the data path users of struct io_zcrx_area don't need to know what kind of memory it's backed by. Only keep there generic bits in there and and split out memory type dependent fields into a new structure. It also logically separates the step that actually imports the memory, e.g. pinning user pages, from the generic area initialisation.
Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/b60fc09c76921bf69e77eb17e07eb4decedb3bf4.174609743... Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: 0ec33c81d9c7 ("io_uring/zcrx: fix area release on registration failure") Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/zcrx.c | 71 ++++++++++++++++++++++++++++++++----------------- io_uring/zcrx.h | 11 ++++++-- 2 files changed, 56 insertions(+), 26 deletions(-)
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index 0771a57d81a5b..7214236c14882 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -26,6 +26,8 @@ #include "zcrx.h" #include "rsrc.h"
+#define IO_DMA_ATTR (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING) + static inline struct io_zcrx_ifq *io_pp_to_ifq(struct page_pool *pp) { return pp->mp_priv; @@ -42,10 +44,43 @@ static inline struct page *io_zcrx_iov_page(const struct net_iov *niov) { struct io_zcrx_area *area = io_zcrx_iov_to_area(niov);
- return area->pages[net_iov_idx(niov)]; + return area->mem.pages[net_iov_idx(niov)]; }
-#define IO_DMA_ATTR (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_WEAK_ORDERING) +static void io_release_area_mem(struct io_zcrx_mem *mem) +{ + if (mem->pages) { + unpin_user_pages(mem->pages, mem->nr_folios); + kvfree(mem->pages); + } +} + +static int io_import_area(struct io_zcrx_ifq *ifq, + struct io_zcrx_mem *mem, + struct io_uring_zcrx_area_reg *area_reg) +{ + struct page **pages; + int nr_pages; + int ret; + + ret = io_validate_user_buf_range(area_reg->addr, area_reg->len); + if (ret) + return ret; + if (!area_reg->addr) + return -EFAULT; + if (area_reg->addr & ~PAGE_MASK || area_reg->len & ~PAGE_MASK) + return -EINVAL; + + pages = io_pin_pages((unsigned long)area_reg->addr, area_reg->len, + &nr_pages); + if (IS_ERR(pages)) + return PTR_ERR(pages); + + mem->pages = pages; + mem->nr_folios = nr_pages; + mem->size = area_reg->len; + return 0; +}
static void __io_zcrx_unmap_area(struct io_zcrx_ifq *ifq, struct io_zcrx_area *area, int nr_mapped) @@ -84,8 +119,8 @@ static int io_zcrx_map_area(struct io_zcrx_ifq *ifq, struct io_zcrx_area *area) struct net_iov *niov = &area->nia.niovs[i]; dma_addr_t dma;
- dma = dma_map_page_attrs(ifq->dev, area->pages[i], 0, PAGE_SIZE, - DMA_FROM_DEVICE, IO_DMA_ATTR); + dma = dma_map_page_attrs(ifq->dev, area->mem.pages[i], 0, + PAGE_SIZE, DMA_FROM_DEVICE, IO_DMA_ATTR); if (dma_mapping_error(ifq->dev, dma)) break; if (net_mp_niov_set_dma_addr(niov, dma)) { @@ -188,14 +223,11 @@ static void io_free_rbuf_ring(struct io_zcrx_ifq *ifq) static void io_zcrx_free_area(struct io_zcrx_area *area) { io_zcrx_unmap_area(area->ifq, area); + io_release_area_mem(&area->mem);
kvfree(area->freelist); kvfree(area->nia.niovs); kvfree(area->user_refs); - if (area->pages) { - unpin_user_pages(area->pages, area->nr_folios); - kvfree(area->pages); - } kfree(area); }
@@ -204,36 +236,27 @@ static int io_zcrx_create_area(struct io_zcrx_ifq *ifq, struct io_uring_zcrx_area_reg *area_reg) { struct io_zcrx_area *area; - int i, ret, nr_pages, nr_iovs; + unsigned nr_iovs; + int i, ret;
if (area_reg->flags || area_reg->rq_area_token) return -EINVAL; if (area_reg->__resv1 || area_reg->__resv2[0] || area_reg->__resv2[1]) return -EINVAL; - if (area_reg->addr & ~PAGE_MASK || area_reg->len & ~PAGE_MASK) - return -EINVAL; - - ret = io_validate_user_buf_range(area_reg->addr, area_reg->len); - if (ret) - return ret; - if (!area_reg->addr) - return -EFAULT;
ret = -ENOMEM; area = kzalloc(sizeof(*area), GFP_KERNEL); if (!area) goto err;
- area->pages = io_pin_pages((unsigned long)area_reg->addr, area_reg->len, - &nr_pages); - if (IS_ERR(area->pages)) { - ret = PTR_ERR(area->pages); - area->pages = NULL; + ret = io_import_area(ifq, &area->mem, area_reg); + if (ret) goto err; - } - area->nr_folios = nr_iovs = nr_pages; + + nr_iovs = area->mem.size >> PAGE_SHIFT; area->nia.num_niovs = nr_iovs;
+ ret = -ENOMEM; area->nia.niovs = kvmalloc_array(nr_iovs, sizeof(area->nia.niovs[0]), GFP_KERNEL | __GFP_ZERO); if (!area->nia.niovs) diff --git a/io_uring/zcrx.h b/io_uring/zcrx.h index f2bc811f022c6..64796c90851e1 100644 --- a/io_uring/zcrx.h +++ b/io_uring/zcrx.h @@ -7,6 +7,13 @@ #include <net/page_pool/types.h> #include <net/net_trackers.h>
+struct io_zcrx_mem { + unsigned long size; + + struct page **pages; + unsigned long nr_folios; +}; + struct io_zcrx_area { struct net_iov_area nia; struct io_zcrx_ifq *ifq; @@ -14,13 +21,13 @@ struct io_zcrx_area {
bool is_mapped; u16 area_id; - struct page **pages; - unsigned long nr_folios;
/* freelist */ spinlock_t freelist_lock ____cacheline_aligned_in_smp; u32 free_count; u32 *freelist; + + struct io_zcrx_mem mem; };
struct io_zcrx_ifq {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
[ Upstream commit 0ec33c81d9c7342f03864101ddb2e717a0cce03e ]
On area registration failure there might be no ifq set and it's not safe to access area->ifq in the release path without checking it first.
Cc: stable@vger.kernel.org Fixes: f12ecf5e1c5ec ("io_uring/zcrx: fix late dma unmap for a dead dev") Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/bc02878678a5fec28bc77d33355cdba735418484.174836564... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/zcrx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/io_uring/zcrx.c b/io_uring/zcrx.c index 7214236c14882..a53058dd6b7a1 100644 --- a/io_uring/zcrx.c +++ b/io_uring/zcrx.c @@ -222,7 +222,8 @@ static void io_free_rbuf_ring(struct io_zcrx_ifq *ifq)
static void io_zcrx_free_area(struct io_zcrx_area *area) { - io_zcrx_unmap_area(area->ifq, area); + if (area->ifq) + io_zcrx_unmap_area(area->ifq, area); io_release_area_mem(&area->mem);
kvfree(area->freelist);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li haoxiang_li2024@163.com
[ Upstream commit f4c7baa0699b69edb6887a992283b389761e0e81 ]
Add check for the return value of alloc_ordered_workqueue() and alloc_workqueue(). Furthermore, if some allocations fail, cleanup works are added to avoid potential memory leak problem.
Fixes: 40053823baad ("drm/i915/display: move modeset probe/remove functions to intel_display_driver.c") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li haoxiang_li2024@163.com Reviewed-by: Matthew Auld matthew.auld@intel.com Link: https://lore.kernel.org/r/20d3d096c6a4907636f8a1389b3b4dd753ca356e.174739763... Signed-off-by: Jani Nikula jani.nikula@intel.com (cherry picked from commit dcab7a228f4ea9cda3f5b0a1f0679e046d23d7f7) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../drm/i915/display/intel_display_driver.c | 30 +++++++++++++++---- 1 file changed, 25 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 31740a677dd80..14c8b3259bbf5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -241,31 +241,45 @@ int intel_display_driver_probe_noirq(struct intel_display *display) intel_dmc_init(display);
display->wq.modeset = alloc_ordered_workqueue("i915_modeset", 0); + if (!display->wq.modeset) { + ret = -ENOMEM; + goto cleanup_vga_client_pw_domain_dmc; + } + display->wq.flip = alloc_workqueue("i915_flip", WQ_HIGHPRI | WQ_UNBOUND, WQ_UNBOUND_MAX_ACTIVE); + if (!display->wq.flip) { + ret = -ENOMEM; + goto cleanup_wq_modeset; + } + display->wq.cleanup = alloc_workqueue("i915_cleanup", WQ_HIGHPRI, 0); + if (!display->wq.cleanup) { + ret = -ENOMEM; + goto cleanup_wq_flip; + }
intel_mode_config_init(display);
ret = intel_cdclk_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup;
ret = intel_color_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup;
ret = intel_dbuf_init(i915); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup;
ret = intel_bw_init(i915); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup;
ret = intel_pmdemand_init(display); if (ret) - goto cleanup_vga_client_pw_domain_dmc; + goto cleanup_wq_cleanup;
intel_init_quirks(display);
@@ -273,6 +287,12 @@ int intel_display_driver_probe_noirq(struct intel_display *display)
return 0;
+cleanup_wq_cleanup: + destroy_workqueue(display->wq.cleanup); +cleanup_wq_flip: + destroy_workqueue(display->wq.flip); +cleanup_wq_modeset: + destroy_workqueue(display->wq.modeset); cleanup_vga_client_pw_domain_dmc: intel_dmc_fini(display); intel_power_domains_driver_remove(display);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima kuniyu@google.com
[ Upstream commit 32ca245464e1479bfea8592b9db227fdc1641705 ]
Jann Horn reported a use-after-free in unix_stream_read_generic().
The following sequences reproduce the issue:
$ python3 from socket import * s1, s2 = socketpair(AF_UNIX, SOCK_STREAM) s1.send(b'x', MSG_OOB) s2.recv(1, MSG_OOB) # leave a consumed OOB skb s1.send(b'y', MSG_OOB) s2.recv(1, MSG_OOB) # leave a consumed OOB skb s1.send(b'z', MSG_OOB) s2.recv(1) # recv 'z' illegally s2.recv(1, MSG_OOB) # access 'z' skb (use-after-free)
Even though a user reads OOB data, the skb holding the data stays on the recv queue to mark the OOB boundary and break the next recv().
After the last send() in the scenario above, the sk2's recv queue has 2 leading consumed OOB skbs and 1 real OOB skb.
Then, the following happens during the next recv() without MSG_OOB
1. unix_stream_read_generic() peeks the first consumed OOB skb 2. manage_oob() returns the next consumed OOB skb 3. unix_stream_read_generic() fetches the next not-yet-consumed OOB skb 4. unix_stream_read_generic() reads and frees the OOB skb
, and the last recv(MSG_OOB) triggers KASAN splat.
The 3. above occurs because of the SO_PEEK_OFF code, which does not expect unix_skb_len(skb) to be 0, but this is true for such consumed OOB skbs.
while (skip >= unix_skb_len(skb)) { skip -= unix_skb_len(skb); skb = skb_peek_next(skb, &sk->sk_receive_queue); ... }
In addition to this use-after-free, there is another issue that ioctl(SIOCATMARK) does not function properly with consecutive consumed OOB skbs.
So, nothing good comes out of such a situation.
Instead of complicating manage_oob(), ioctl() handling, and the next ECONNRESET fix by introducing a loop for consecutive consumed OOB skbs, let's not leave such consecutive OOB unnecessarily.
Now, while receiving an OOB skb in unix_stream_recv_urg(), if its previous skb is a consumed OOB skb, it is freed.
[0]: BUG: KASAN: slab-use-after-free in unix_stream_read_actor (net/unix/af_unix.c:3027) Read of size 4 at addr ffff888106ef2904 by task python3/315
CPU: 2 UID: 0 PID: 315 Comm: python3 Not tainted 6.16.0-rc1-00407-gec315832f6f9 #8 PREEMPT(voluntary) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-4.fc42 04/01/2014 Call Trace: <TASK> dump_stack_lvl (lib/dump_stack.c:122) print_report (mm/kasan/report.c:409 mm/kasan/report.c:521) kasan_report (mm/kasan/report.c:636) unix_stream_read_actor (net/unix/af_unix.c:3027) unix_stream_read_generic (net/unix/af_unix.c:2708 net/unix/af_unix.c:2847) unix_stream_recvmsg (net/unix/af_unix.c:3048) sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20)) __sys_recvfrom (net/socket.c:2278) __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1)) do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130) RIP: 0033:0x7f8911fcea06 Code: 5d e8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 75 19 83 e2 39 83 fa 08 75 11 e8 26 ff ff ff 66 0f 1f 44 00 00 48 8b 45 10 0f 05 <48> 8b 5d f8 c9 c3 0f 1f 40 00 f3 0f 1e fa 55 48 89 e5 48 83 ec 08 RSP: 002b:00007fffdb0dccb0 EFLAGS: 00000202 ORIG_RAX: 000000000000002d RAX: ffffffffffffffda RBX: 00007fffdb0dcdc8 RCX: 00007f8911fcea06 RDX: 0000000000000001 RSI: 00007f8911a5e060 RDI: 0000000000000006 RBP: 00007fffdb0dccd0 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000202 R12: 00007f89119a7d20 R13: ffffffffc4653600 R14: 0000000000000000 R15: 0000000000000000 </TASK>
Allocated by task 315: kasan_save_stack (mm/kasan/common.c:48) kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1)) __kasan_slab_alloc (mm/kasan/common.c:348) kmem_cache_alloc_node_noprof (./include/linux/kasan.h:250 mm/slub.c:4148 mm/slub.c:4197 mm/slub.c:4249) __alloc_skb (net/core/skbuff.c:660 (discriminator 4)) alloc_skb_with_frags (./include/linux/skbuff.h:1336 net/core/skbuff.c:6668) sock_alloc_send_pskb (net/core/sock.c:2993) unix_stream_sendmsg (./include/net/sock.h:1847 net/unix/af_unix.c:2256 net/unix/af_unix.c:2418) __sys_sendto (net/socket.c:712 (discriminator 20) net/socket.c:727 (discriminator 20) net/socket.c:2226 (discriminator 20)) __x64_sys_sendto (net/socket.c:2233 (discriminator 1) net/socket.c:2229 (discriminator 1) net/socket.c:2229 (discriminator 1)) do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
Freed by task 315: kasan_save_stack (mm/kasan/common.c:48) kasan_save_track (mm/kasan/common.c:60 (discriminator 1) mm/kasan/common.c:69 (discriminator 1)) kasan_save_free_info (mm/kasan/generic.c:579 (discriminator 1)) __kasan_slab_free (mm/kasan/common.c:271) kmem_cache_free (mm/slub.c:4643 (discriminator 3) mm/slub.c:4745 (discriminator 3)) unix_stream_read_generic (net/unix/af_unix.c:3010) unix_stream_recvmsg (net/unix/af_unix.c:3048) sock_recvmsg (net/socket.c:1063 (discriminator 20) net/socket.c:1085 (discriminator 20)) __sys_recvfrom (net/socket.c:2278) __x64_sys_recvfrom (net/socket.c:2291 (discriminator 1) net/socket.c:2287 (discriminator 1) net/socket.c:2287 (discriminator 1)) do_syscall_64 (arch/x86/entry/syscall_64.c:63 (discriminator 1) arch/x86/entry/syscall_64.c:94 (discriminator 1)) entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
The buggy address belongs to the object at ffff888106ef28c0 which belongs to the cache skbuff_head_cache of size 224 The buggy address is located 68 bytes inside of freed 224-byte region [ffff888106ef28c0, ffff888106ef29a0)
The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0xffff888106ef3cc0 pfn:0x106ef2 head: order:1 mapcount:0 entire_mapcount:0 nr_pages_mapped:0 pincount:0 flags: 0x200000000000040(head|node=0|zone=2) page_type: f5(slab) raw: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004 raw: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000 head: 0200000000000040 ffff8881001d28c0 ffffea000422fe00 0000000000000004 head: ffff888106ef3cc0 0000000080190010 00000000f5000000 0000000000000000 head: 0200000000000001 ffffea00041bbc81 00000000ffffffff 00000000ffffffff head: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff888106ef2800: 00 00 00 00 00 00 00 00 00 00 00 00 fc fc fc fc ffff888106ef2880: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
ffff888106ef2900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^ ffff888106ef2980: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc ffff888106ef2a00: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
Fixes: 314001f0bf92 ("af_unix: Add OOB support") Reported-by: Jann Horn jannh@google.com Signed-off-by: Kuniyuki Iwashima kuniyu@google.com Reviewed-by: Jann Horn jannh@google.com Link: https://patch.msgid.link/20250619041457.1132791-2-kuni1840@gmail.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/unix/af_unix.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index f78a2492826f9..af003831f4c67 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2597,11 +2597,11 @@ struct unix_stream_read_state { #if IS_ENABLED(CONFIG_AF_UNIX_OOB) static int unix_stream_recv_urg(struct unix_stream_read_state *state) { + struct sk_buff *oob_skb, *read_skb = NULL; struct socket *sock = state->socket; struct sock *sk = sock->sk; struct unix_sock *u = unix_sk(sk); int chunk = 1; - struct sk_buff *oob_skb;
mutex_lock(&u->iolock); unix_state_lock(sk); @@ -2616,9 +2616,16 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
oob_skb = u->oob_skb;
- if (!(state->flags & MSG_PEEK)) + if (!(state->flags & MSG_PEEK)) { WRITE_ONCE(u->oob_skb, NULL);
+ if (oob_skb->prev != (struct sk_buff *)&sk->sk_receive_queue && + !unix_skb_len(oob_skb->prev)) { + read_skb = oob_skb->prev; + __skb_unlink(read_skb, &sk->sk_receive_queue); + } + } + spin_unlock(&sk->sk_receive_queue.lock); unix_state_unlock(sk);
@@ -2629,6 +2636,8 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
mutex_unlock(&u->iolock);
+ consume_skb(read_skb); + if (chunk < 0) return -EFAULT;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christophe JAILLET christophe.jaillet@wanadoo.fr
commit 666c23af755dccca8c25b5d5200ca28153c69a05 upstream.
If an error occurs after calling mux_state_select(), mux_state_deselect() should be called as already done in the remove function.
Fixes: b6ef830c60b6 ("i2c: omap: Add support for setting mux") Signed-off-by: Christophe JAILLET christophe.jaillet@wanadoo.fr Cc: stable@vger.kernel.org # v6.15+ Signed-off-by: Andi Shyti andi.shyti@kernel.org Link: https://lore.kernel.org/r/998542981b6d2435c057dd8b9fe71743927babab.174991314... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/i2c/busses/i2c-omap.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-omap.c b/drivers/i2c/busses/i2c-omap.c index f1cc26ac5b80..8b01df3cc8e9 100644 --- a/drivers/i2c/busses/i2c-omap.c +++ b/drivers/i2c/busses/i2c-omap.c @@ -1461,13 +1461,13 @@ omap_i2c_probe(struct platform_device *pdev) if (IS_ERR(mux_state)) { r = PTR_ERR(mux_state); dev_dbg(&pdev->dev, "failed to get I2C mux: %d\n", r); - goto err_disable_pm; + goto err_put_pm; } omap->mux_state = mux_state; r = mux_state_select(omap->mux_state); if (r) { dev_err(&pdev->dev, "failed to select I2C mux: %d\n", r); - goto err_disable_pm; + goto err_put_pm; } }
@@ -1515,6 +1515,9 @@ omap_i2c_probe(struct platform_device *pdev)
err_unuse_clocks: omap_i2c_write_reg(omap, OMAP_I2C_CON_REG, 0); + if (omap->mux_state) + mux_state_deselect(omap->mux_state); +err_put_pm: pm_runtime_dont_use_autosuspend(omap->dev); pm_runtime_put_sync(omap->dev); err_disable_pm:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukasz Kucharczyk lukasz.kucharczyk@leica-geosystems.com
commit a5d0b9e32745277644cda8d7d334e7080bd339bf upstream.
Acknowledge the byte count submitted by the target. When I2C_SMBUS_BLOCK_DATA read operation is executed by i2c_smbus_xfer_emulated(), the length of the second (read) message is set to 1. Length of the block is supposed to be obtained from the target by the underlying bus driver. The i2c_imx_isr_read() function should emit the acknowledge on i2c bus after reading the first byte (i.e., byte count) while processing such message (as defined in Section 6.5.7 of System Management Bus Specification [1]). Without this acknowledge, the target does not submit subsequent bytes and the controller only reads 0xff's.
In addition, store the length of block data obtained from the target in the buffer provided by i2c_smbus_xfer_emulated() - otherwise the first byte of actual data is erroneously interpreted as length of the data block.
[1] https://smbus.org/specs/SMBus_3_3_20240512.pdf
Fixes: 5f5c2d4579ca ("i2c: imx: prevent rescheduling in non dma mode") Signed-off-by: Lukasz Kucharczyk lukasz.kucharczyk@leica-geosystems.com Cc: stable@vger.kernel.org # v6.13+ Acked-by: Oleksij Rempel o.rempel@pengutronix.de Reviewed-by: Stefan Eichenberger eichest@gmail.com Reviewed-by: Carlos Song carlos.song@nxp.com Signed-off-by: Andi Shyti andi.shyti@kernel.org Link: https://lore.kernel.org/r/20250520122252.1475403-1-lukasz.kucharczyk@leica-g... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/i2c/busses/i2c-imx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index e5732b0557fb..205cc132fdec 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c @@ -1008,7 +1008,7 @@ static inline int i2c_imx_isr_read(struct imx_i2c_struct *i2c_imx) /* setup bus to read data */ temp = imx_i2c_read_reg(i2c_imx, IMX_I2C_I2CR); temp &= ~I2CR_MTX; - if (i2c_imx->msg->len - 1) + if ((i2c_imx->msg->len - 1) || (i2c_imx->msg->flags & I2C_M_RECV_LEN)) temp &= ~I2CR_TXAK;
imx_i2c_write_reg(temp, i2c_imx, IMX_I2C_I2CR); @@ -1063,6 +1063,7 @@ static inline void i2c_imx_isr_read_block_data_len(struct imx_i2c_struct *i2c_im wake_up(&i2c_imx->queue); } i2c_imx->msg->len += len; + i2c_imx->msg->buf[i2c_imx->msg_buf_idx++] = len; }
static irqreturn_t i2c_imx_master_isr(struct imx_i2c_struct *i2c_imx, unsigned int status)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang wsa+renesas@sang-engineering.com
commit cbdb25ccf7566eee0c2b945e35cb98baf9ed0aa6 upstream.
This driver passes the length of an i2c_msg directly to usb_control_msg(). If the message is now a read and of length 0, it violates the USB protocol and a warning will be printed. Enable the I2C_AQ_NO_ZERO_LEN_READ quirk for this adapter thus forbidding 0-length read messages altogether.
Fixes: e8c76eed2ecd ("i2c: New i2c-tiny-usb bus driver") Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Cc: stable@vger.kernel.org # v2.6.22+ Signed-off-by: Andi Shyti andi.shyti@kernel.org Link: https://lore.kernel.org/r/20250522064349.3823-2-wsa+renesas@sang-engineering... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/i2c/busses/i2c-tiny-usb.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/i2c/busses/i2c-tiny-usb.c +++ b/drivers/i2c/busses/i2c-tiny-usb.c @@ -138,6 +138,11 @@ out: return ret; }
+/* prevent invalid 0-length usb_control_msg */ +static const struct i2c_adapter_quirks usb_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN_READ, +}; + /* This is the actual algorithm we define */ static const struct i2c_algorithm usb_algorithm = { .xfer = usb_xfer, @@ -246,6 +251,7 @@ static int i2c_tiny_usb_probe(struct usb /* setup i2c adapter description */ dev->adapter.owner = THIS_MODULE; dev->adapter.class = I2C_CLASS_HWMON; + dev->adapter.quirks = &usb_quirks; dev->adapter.algo = &usb_algorithm; dev->adapter.algo_data = dev; snprintf(dev->adapter.name, sizeof(dev->adapter.name),
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang wsa+renesas@sang-engineering.com
commit 56ad91c1aa9c18064348edf69308080b03c9dc48 upstream.
This driver passes the length of an i2c_msg directly to usb_control_msg(). If the message is now a read and of length 0, it violates the USB protocol and a warning will be printed. Enable the I2C_AQ_NO_ZERO_LEN_READ quirk for this adapter thus forbidding 0-length read messages altogether.
Fixes: 83e53a8f120f ("i2c: Add bus driver for for OSIF USB i2c device.") Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Cc: stable@vger.kernel.org # v3.14+ Signed-off-by: Andi Shyti andi.shyti@kernel.org Link: https://lore.kernel.org/r/20250522064234.3721-2-wsa+renesas@sang-engineering... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/i2c/busses/i2c-robotfuzz-osif.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/i2c/busses/i2c-robotfuzz-osif.c +++ b/drivers/i2c/busses/i2c-robotfuzz-osif.c @@ -111,6 +111,11 @@ static u32 osif_func(struct i2c_adapter return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; }
+/* prevent invalid 0-length usb_control_msg */ +static const struct i2c_adapter_quirks osif_quirks = { + .flags = I2C_AQ_NO_ZERO_LEN_READ, +}; + static const struct i2c_algorithm osif_algorithm = { .xfer = osif_xfer, .functionality = osif_func, @@ -143,6 +148,7 @@ static int osif_probe(struct usb_interfa
priv->adapter.owner = THIS_MODULE; priv->adapter.class = I2C_CLASS_HWMON; + priv->adapter.quirks = &osif_quirks; priv->adapter.algo = &osif_algorithm; priv->adapter.algo_data = priv; snprintf(priv->adapter.name, sizeof(priv->adapter.name),
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit 080e8d2ecdfde588897aa8a87a8884061f4dbbbb upstream.
The variable index is modified and reused as array index when modify register EIOINTC_ENABLE. There will be array index overflow problem.
Cc: stable@vger.kernel.org Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions") Signed-off-by: Bibo Mao maobibo@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kvm/intc/eiointc.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c index f39929d7bf8a..9c47456b805c 100644 --- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -436,17 +436,16 @@ static int loongarch_eiointc_writew(struct kvm_vcpu *vcpu, break; case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END: index = (offset - EIOINTC_ENABLE_START) >> 1; - old_data = s->enable.reg_u32[index]; + old_data = s->enable.reg_u16[index]; s->enable.reg_u16[index] = data; /* * 1: enable irq. * update irq when isr is set. */ data = s->enable.reg_u16[index] & ~old_data & s->isr.reg_u16[index]; - index = index << 1; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - eiointc_enable_irq(vcpu, s, index + i, mask, 1); + eiointc_enable_irq(vcpu, s, index * 2 + i, mask, 1); } /* * 0: disable irq. @@ -455,7 +454,7 @@ static int loongarch_eiointc_writew(struct kvm_vcpu *vcpu, data = ~s->enable.reg_u16[index] & old_data & s->isr.reg_u16[index]; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - eiointc_enable_irq(vcpu, s, index, mask, 0); + eiointc_enable_irq(vcpu, s, index * 2 + i, mask, 0); } break; case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END: @@ -529,10 +528,9 @@ static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu, * update irq when isr is set. */ data = s->enable.reg_u32[index] & ~old_data & s->isr.reg_u32[index]; - index = index << 2; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - eiointc_enable_irq(vcpu, s, index + i, mask, 1); + eiointc_enable_irq(vcpu, s, index * 4 + i, mask, 1); } /* * 0: disable irq. @@ -541,7 +539,7 @@ static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu, data = ~s->enable.reg_u32[index] & old_data & s->isr.reg_u32[index]; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - eiointc_enable_irq(vcpu, s, index, mask, 0); + eiointc_enable_irq(vcpu, s, index * 4 + i, mask, 0); } break; case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END: @@ -615,10 +613,9 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu, * update irq when isr is set. */ data = s->enable.reg_u64[index] & ~old_data & s->isr.reg_u64[index]; - index = index << 3; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - eiointc_enable_irq(vcpu, s, index + i, mask, 1); + eiointc_enable_irq(vcpu, s, index * 8 + i, mask, 1); } /* * 0: disable irq. @@ -627,7 +624,7 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu, data = ~s->enable.reg_u64[index] & old_data & s->isr.reg_u64[index]; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - eiointc_enable_irq(vcpu, s, index, mask, 0); + eiointc_enable_irq(vcpu, s, index * 8 + i, mask, 0); } break; case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit cc8d5b209e09d3b52bca1ffe00045876842d96ae upstream.
The maximum supported cpu number is EIOINTC_ROUTE_MAX_VCPUS about irqchip EIOINTC, here add validation about cpu number to avoid array pointer overflow.
Cc: stable@vger.kernel.org Fixes: 1ad7efa552fd ("LoongArch: KVM: Add EIOINTC user mode read and write functions") Signed-off-by: Bibo Mao maobibo@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kvm/intc/eiointc.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
--- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -784,7 +784,7 @@ static int kvm_eiointc_ctrl_access(struc int ret = 0; unsigned long flags; unsigned long type = (unsigned long)attr->attr; - u32 i, start_irq; + u32 i, start_irq, val; void __user *data; struct loongarch_eiointc *s = dev->kvm->arch.eiointc;
@@ -792,8 +792,14 @@ static int kvm_eiointc_ctrl_access(struc spin_lock_irqsave(&s->lock, flags); switch (type) { case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU: - if (copy_from_user(&s->num_cpu, data, 4)) + if (copy_from_user(&val, data, 4)) ret = -EFAULT; + else { + if (val >= EIOINTC_ROUTE_MAX_VCPUS) + ret = -EINVAL; + else + s->num_cpu = val; + } break; case KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE: if (copy_from_user(&s->features, data, 4)) @@ -821,7 +827,7 @@ static int kvm_eiointc_regs_access(struc struct kvm_device_attr *attr, bool is_write) { - int addr, cpuid, offset, ret = 0; + int addr, cpu, offset, ret = 0; unsigned long flags; void *p = NULL; void __user *data; @@ -829,7 +835,7 @@ static int kvm_eiointc_regs_access(struc
s = dev->kvm->arch.eiointc; addr = attr->attr; - cpuid = addr >> 16; + cpu = addr >> 16; addr &= 0xffff; data = (void __user *)attr->addr; switch (addr) { @@ -854,8 +860,11 @@ static int kvm_eiointc_regs_access(struc p = &s->isr.reg_u32[offset]; break; case EIOINTC_COREISR_START ... EIOINTC_COREISR_END: + if (cpu >= s->num_cpu) + return -EINVAL; + offset = (addr - EIOINTC_COREISR_START) / 4; - p = &s->coreisr.reg_u32[cpuid][offset]; + p = &s->coreisr.reg_u32[cpu][offset]; break; case EIOINTC_COREMAP_START ... EIOINTC_COREMAP_END: offset = (addr - EIOINTC_COREMAP_START) / 4;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit 955853cf83657faa58572ef3f08b44f0f88885c1 upstream.
Property "num_cpu" and "feature" are read-only once eiointc is created, which are set with KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL attr group before device creation.
Attr group KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS is to update register and software state for migration and reset usage, property "num_cpu" and "feature" can not be update again if it is created already.
Here discard write operation with property "num_cpu" and "feature" in attr group KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL.
Cc: stable@vger.kernel.org Fixes: 1ad7efa552fd ("LoongArch: KVM: Add EIOINTC user mode read and write functions") Signed-off-by: Bibo Mao maobibo@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kvm/intc/eiointc.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -905,9 +905,15 @@ static int kvm_eiointc_sw_status_access( data = (void __user *)attr->addr; switch (addr) { case KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_NUM_CPU: + if (is_write) + return ret; + p = &s->num_cpu; break; case KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_FEATURE: + if (is_write) + return ret; + p = &s->features; break; case KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit 9159c5e733cfa35ec863fa81960a3e7435f831fb upstream.
IOCSR instruction supports 1/2/4/8 bytes access, the address should be naturally aligned with its access size. Here address alignment check is added in the EIOINTC kernel emulation.
Cc: stable@vger.kernel.org Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions") Signed-off-by: Bibo Mao maobibo@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kvm/intc/eiointc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c index 9c47456b805c..236cbf979167 100644 --- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -305,6 +305,11 @@ static int kvm_eiointc_read(struct kvm_vcpu *vcpu, return -EINVAL; }
+ if (addr & (len - 1)) { + kvm_err("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len); + return -EINVAL; + } + vcpu->kvm->stat.eiointc_read_exits++; spin_lock_irqsave(&eiointc->lock, flags); switch (len) { @@ -676,6 +681,11 @@ static int kvm_eiointc_write(struct kvm_vcpu *vcpu, return -EINVAL; }
+ if (addr & (len - 1)) { + kvm_err("%s: eiointc not aligned addr %llx len %d\n", __func__, addr, len); + return -EINVAL; + } + vcpu->kvm->stat.eiointc_write_exits++; spin_lock_irqsave(&eiointc->lock, flags); switch (len) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit c34bbc2c990700ba07b271fc7c8113b0bc3e4093 upstream.
With function eiointc_update_sw_coremap(), there is forced assignment like val = *(u64 *)pvalue. Parameter pvalue may be pointer to char type or others, there is problem with forced assignment with u64 type.
Here the detailed value is passed rather address pointer.
Cc: stable@vger.kernel.org Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions") Signed-off-by: Bibo Mao maobibo@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kvm/intc/eiointc.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
--- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -66,10 +66,9 @@ static void eiointc_update_irq(struct lo }
static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s, - int irq, void *pvalue, u32 len, bool notify) + int irq, u64 val, u32 len, bool notify) { int i, cpu; - u64 val = *(u64 *)pvalue;
for (i = 0; i < len; i++) { cpu = val & 0xff; @@ -403,7 +402,7 @@ static int loongarch_eiointc_writeb(stru irq = offset - EIOINTC_COREMAP_START; index = irq; s->coremap.reg_u8[index] = data; - eiointc_update_sw_coremap(s, irq, (void *)&data, sizeof(data), true); + eiointc_update_sw_coremap(s, irq, data, sizeof(data), true); break; default: ret = -EINVAL; @@ -488,7 +487,7 @@ static int loongarch_eiointc_writew(stru irq = offset - EIOINTC_COREMAP_START; index = irq >> 1; s->coremap.reg_u16[index] = data; - eiointc_update_sw_coremap(s, irq, (void *)&data, sizeof(data), true); + eiointc_update_sw_coremap(s, irq, data, sizeof(data), true); break; default: ret = -EINVAL; @@ -573,7 +572,7 @@ static int loongarch_eiointc_writel(stru irq = offset - EIOINTC_COREMAP_START; index = irq >> 2; s->coremap.reg_u32[index] = data; - eiointc_update_sw_coremap(s, irq, (void *)&data, sizeof(data), true); + eiointc_update_sw_coremap(s, irq, data, sizeof(data), true); break; default: ret = -EINVAL; @@ -658,7 +657,7 @@ static int loongarch_eiointc_writeq(stru irq = offset - EIOINTC_COREMAP_START; index = irq >> 3; s->coremap.reg_u64[index] = data; - eiointc_update_sw_coremap(s, irq, (void *)&data, sizeof(data), true); + eiointc_update_sw_coremap(s, irq, data, sizeof(data), true); break; default: ret = -EINVAL; @@ -822,7 +821,7 @@ static int kvm_eiointc_ctrl_access(struc for (i = 0; i < (EIOINTC_IRQS / 4); i++) { start_irq = i * 4; eiointc_update_sw_coremap(s, start_irq, - (void *)&s->coremap.reg_u32[i], sizeof(u32), false); + s->coremap.reg_u32[i], sizeof(u32), false); } break; default:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit 45515c643d0abb75c2cc760a6bc6b235eadafd66 upstream.
With EIOINTC interrupt controller, physical CPU ID is set for irq route. However the function kvm_get_vcpu() is used to get destination vCPU when delivering irq. With API kvm_get_vcpu(), the logical CPU ID is used.
With API kvm_get_vcpu_by_cpuid(), vCPU ID can be searched from physical CPU ID.
Cc: stable@vger.kernel.org Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions") Signed-off-by: Bibo Mao maobibo@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kvm/intc/eiointc.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c index 8d3f48e2a7f0..644fb7785c07 100644 --- a/arch/loongarch/kvm/intc/eiointc.c +++ b/arch/loongarch/kvm/intc/eiointc.c @@ -9,7 +9,8 @@
static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s) { - int ipnum, cpu, irq_index, irq_mask, irq; + int ipnum, cpu, cpuid, irq_index, irq_mask, irq; + struct kvm_vcpu *vcpu;
for (irq = 0; irq < EIOINTC_IRQS; irq++) { ipnum = s->ipmap.reg_u8[irq / 32]; @@ -20,7 +21,12 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s) irq_index = irq / 32; irq_mask = BIT(irq & 0x1f);
- cpu = s->coremap.reg_u8[irq]; + cpuid = s->coremap.reg_u8[irq]; + vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid); + if (!vcpu) + continue; + + cpu = vcpu->vcpu_id; if (!!(s->coreisr.reg_u32[cpu][irq_index] & irq_mask)) set_bit(irq, s->sw_coreisr[cpu][ipnum]); else @@ -68,17 +74,23 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level) static inline void eiointc_update_sw_coremap(struct loongarch_eiointc *s, int irq, u64 val, u32 len, bool notify) { - int i, cpu; + int i, cpu, cpuid; + struct kvm_vcpu *vcpu;
for (i = 0; i < len; i++) { - cpu = val & 0xff; + cpuid = val & 0xff; val = val >> 8;
if (!(s->status & BIT(EIOINTC_ENABLE_CPU_ENCODE))) { - cpu = ffs(cpu) - 1; - cpu = (cpu >= 4) ? 0 : cpu; + cpuid = ffs(cpuid) - 1; + cpuid = (cpuid >= 4) ? 0 : cpuid; }
+ vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid); + if (!vcpu) + continue; + + cpu = vcpu->vcpu_id; if (s->sw_coremap[irq + i] == cpu) continue;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haiyue Wang haiyuewa@163.com
commit befd9a71d859ea625eaa84dae1b243efb3df3eca upstream.
The WARN_ON_ONCE is introduced on truncate_folio_batch_exceptionals() to capture whether the filesystem has removed all DAX entries or not.
And the fix has been applied on the filesystem xfs and ext4 by the commit 0e2f80afcfa6 ("fs/dax: ensure all pages are idle prior to filesystem unmount").
Apply the missed fix on filesystem fuse to fix the runtime warning:
[ 2.011450] ------------[ cut here ]------------ [ 2.011873] WARNING: CPU: 0 PID: 145 at mm/truncate.c:89 truncate_folio_batch_exceptionals+0x272/0x2b0 [ 2.012468] Modules linked in: [ 2.012718] CPU: 0 UID: 1000 PID: 145 Comm: weston Not tainted 6.16.0-rc2-WSL2-STABLE #2 PREEMPT(undef) [ 2.013292] RIP: 0010:truncate_folio_batch_exceptionals+0x272/0x2b0 [ 2.013704] Code: 48 63 d0 41 29 c5 48 8d 1c d5 00 00 00 00 4e 8d 6c 2a 01 49 c1 e5 03 eb 09 48 83 c3 08 49 39 dd 74 83 41 f6 44 1c 08 01 74 ef <0f> 0b 49 8b 34 1e 48 89 ef e8 10 a2 17 00 eb df 48 8b 7d 00 e8 35 [ 2.014845] RSP: 0018:ffffa47ec33f3b10 EFLAGS: 00010202 [ 2.015279] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000 [ 2.015884] RDX: 0000000000000000 RSI: ffffa47ec33f3ca0 RDI: ffff98aa44f3fa80 [ 2.016377] RBP: ffff98aa44f3fbf0 R08: ffffa47ec33f3ba8 R09: 0000000000000000 [ 2.016942] R10: 0000000000000001 R11: 0000000000000000 R12: ffffa47ec33f3ca0 [ 2.017437] R13: 0000000000000008 R14: ffffa47ec33f3ba8 R15: 0000000000000000 [ 2.017972] FS: 000079ce006afa40(0000) GS:ffff98aade441000(0000) knlGS:0000000000000000 [ 2.018510] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 2.018987] CR2: 000079ce03e74000 CR3: 000000010784f006 CR4: 0000000000372eb0 [ 2.019518] Call Trace: [ 2.019729] <TASK> [ 2.019901] truncate_inode_pages_range+0xd8/0x400 [ 2.020280] ? timerqueue_add+0x66/0xb0 [ 2.020574] ? get_nohz_timer_target+0x2a/0x140 [ 2.020904] ? timerqueue_add+0x66/0xb0 [ 2.021231] ? timerqueue_del+0x2e/0x50 [ 2.021646] ? __remove_hrtimer+0x39/0x90 [ 2.022017] ? srso_alias_untrain_ret+0x1/0x10 [ 2.022497] ? psi_group_change+0x136/0x350 [ 2.023046] ? _raw_spin_unlock+0xe/0x30 [ 2.023514] ? finish_task_switch.isra.0+0x8d/0x280 [ 2.024068] ? __schedule+0x532/0xbd0 [ 2.024551] fuse_evict_inode+0x29/0x190 [ 2.025131] evict+0x100/0x270 [ 2.025641] ? _atomic_dec_and_lock+0x39/0x50 [ 2.026316] ? __pfx_generic_delete_inode+0x10/0x10 [ 2.026843] __dentry_kill+0x71/0x180 [ 2.027335] dput+0xeb/0x1b0 [ 2.027725] __fput+0x136/0x2b0 [ 2.028054] __x64_sys_close+0x3d/0x80 [ 2.028469] do_syscall_64+0x6d/0x1b0 [ 2.028832] ? clear_bhb_loop+0x30/0x80 [ 2.029182] ? clear_bhb_loop+0x30/0x80 [ 2.029533] ? clear_bhb_loop+0x30/0x80 [ 2.029902] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 2.030423] RIP: 0033:0x79ce03d0d067 [ 2.030820] Code: b8 ff ff ff ff e9 3e ff ff ff 66 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 b8 03 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 41 c3 48 83 ec 18 89 7c 24 0c e8 c3 a7 f8 ff [ 2.032354] RSP: 002b:00007ffef0498948 EFLAGS: 00000246 ORIG_RAX: 0000000000000003 [ 2.032939] RAX: ffffffffffffffda RBX: 00007ffef0498960 RCX: 000079ce03d0d067 [ 2.033612] RDX: 0000000000000003 RSI: 0000000000001000 RDI: 000000000000000d [ 2.034289] RBP: 00007ffef0498a30 R08: 000000000000000d R09: 0000000000000000 [ 2.034944] R10: 00007ffef0498978 R11: 0000000000000246 R12: 0000000000000001 [ 2.035610] R13: 00007ffef0498960 R14: 000079ce03e09ce0 R15: 0000000000000003 [ 2.036301] </TASK> [ 2.036532] ---[ end trace 0000000000000000 ]---
Link: https://lkml.kernel.org/r/20250621171507.3770-1-haiyuewa@163.com Fixes: bde708f1a65d ("fs/dax: always remove DAX page-cache entries when breaking layouts") Signed-off-by: Haiyue Wang haiyuewa@163.com Cc: Alistair Popple apopple@nvidia.com Cc: Dan Williams dan.j.williams@intel.com Cc: Miklos Szeredi miklos@szeredi.hu Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/fuse/inode.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index bfe8d8af46f3..9572bdef49ee 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -9,6 +9,7 @@ #include "fuse_i.h" #include "dev_uring_i.h"
+#include <linux/dax.h> #include <linux/pagemap.h> #include <linux/slab.h> #include <linux/file.h> @@ -162,6 +163,9 @@ static void fuse_evict_inode(struct inode *inode) /* Will write inode on close/munmap and in all other dirtiers */ WARN_ON(inode->i_state & I_DIRTY_INODE);
+ if (FUSE_IS_DAX(inode)) + dax_break_layout_final(inode); + truncate_inode_pages_final(&inode->i_data); clear_inode(inode); if (inode->i_sb->s_flags & SB_ACTIVE) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Fainelli florian.fainelli@broadcom.com
commit 79300ac805b672a84b64d80d4cbc374d83411599 upstream.
The "d_iname" member was replaced with "d_shortname.string" in the commit referenced in the Fixes tag. This prevented the GDB script "lx-mount" command to properly function:
(gdb) lx-mounts mount super_block devname pathname fstype options 0xff11000002d21180 0xff11000002d24800 rootfs / rootfs rw 0 0 0xff11000002e18a80 0xff11000003713000 /dev/root / ext4 rw,relatime 0 0 Python Exception <class 'gdb.error'>: There is no member named d_iname. Error occurred in Python: There is no member named d_iname.
Link: https://lkml.kernel.org/r/20250619225105.320729-1-florian.fainelli@broadcom.... Fixes: 58cf9c383c5c ("dcache: back inline names with a struct-wrapped array of unsigned long") Signed-off-by: Florian Fainelli florian.fainelli@broadcom.com Cc: Al Viro viro@zeniv.linux.org.uk Cc: Jan Kara jack@suse.cz Cc: Jan Kiszka jan.kiszka@siemens.com Cc: Jeff Layton jlayton@kernel.org Cc: Kieran Bingham kbingham@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- scripts/gdb/linux/vfs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/gdb/linux/vfs.py b/scripts/gdb/linux/vfs.py index c77b9ce75f6d..b5fbb18ccb77 100644 --- a/scripts/gdb/linux/vfs.py +++ b/scripts/gdb/linux/vfs.py @@ -22,7 +22,7 @@ def dentry_name(d): if parent == d or parent == 0: return "" p = dentry_name(d['d_parent']) + "/" - return p + d['d_iname'].string() + return p + d['d_shortname']['string'].string()
class DentryName(gdb.Function): """Return string of the full path of a dentry.
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel cassel@kernel.org
commit 3e0809b1664b9dc650d9dbca9a2d3ac690d4f661 upstream.
ASUS store the board name in DMI_PRODUCT_NAME rather than DMI_PRODUCT_VERSION. (Apparently it is only Lenovo that stores the model-name in DMI_PRODUCT_VERSION.)
Use the correct DMI identifier, DMI_PRODUCT_NAME, to match the ASUSPRO-D840SA board, such that the quirk actually gets applied.
Cc: stable@vger.kernel.org Reported-by: Andy Yang andyybtc79@gmail.com Tested-by: Andy Yang andyybtc79@gmail.com Closes: https://lore.kernel.org/linux-ide/aFb3wXAwJSSJUB7o@ryzen/ Fixes: b5acc3628898 ("ata: ahci: Disallow LPM for ASUSPRO-D840SA motherboard") Reviewed-by: Hans de Goede hansg@kernel.org Reviewed-by: Damien Le Moal dlemoal@kernel.org Link: https://lore.kernel.org/r/20250624074029.963028-2-cassel@kernel.org Signed-off-by: Niklas Cassel cassel@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/ahci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1456,7 +1456,7 @@ static bool ahci_broken_lpm(struct pci_d { .matches = { DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_VERSION, "ASUSPRO D840MB_M840SA"), + DMI_MATCH(DMI_PRODUCT_NAME, "ASUSPRO D840MB_M840SA"), }, /* 320 is broken, there is no known good version. */ },
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher metze@samba.org
commit e97f9540ce001503a4539f337da742c1dfa7d86a upstream.
The generate '[FAILED TO PARSE]' strings in trace-cmd report output like this:
rm-5298 [001] 6084.533748493: smb3_exit_err: [FAILED TO PARSE] xid=972 func_name=cifs_rmdir rc=-39 rm-5298 [001] 6084.533959234: smb3_enter: [FAILED TO PARSE] xid=973 func_name=cifs_closedir rm-5298 [001] 6084.533967630: smb3_close_enter: [FAILED TO PARSE] xid=973 fid=94489281833 tid=1 sesid=96758029877361 rm-5298 [001] 6084.534004008: smb3_cmd_enter: [FAILED TO PARSE] tid=1 sesid=96758029877361 cmd=6 mid=566 rm-5298 [001] 6084.552248232: smb3_cmd_done: [FAILED TO PARSE] tid=1 sesid=96758029877361 cmd=6 mid=566 rm-5298 [001] 6084.552280542: smb3_close_done: [FAILED TO PARSE] xid=973 fid=94489281833 tid=1 sesid=96758029877361 rm-5298 [001] 6084.552316034: smb3_exit_done: [FAILED TO PARSE] xid=973 func_name=cifs_closedir
Cc: stable@vger.kernel.org Signed-off-by: Stefan Metzmacher metze@samba.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/smb/client/trace.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
--- a/fs/smb/client/trace.h +++ b/fs/smb/client/trace.h @@ -140,7 +140,7 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class, __entry->len = len; __entry->rc = rc; ), - TP_printk("\tR=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d", + TP_printk("R=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d", __entry->rreq_debug_id, __entry->rreq_debug_index, __entry->xid, __entry->sesid, __entry->tid, __entry->fid, __entry->offset, __entry->len, __entry->rc) @@ -190,7 +190,7 @@ DECLARE_EVENT_CLASS(smb3_other_err_class __entry->len = len; __entry->rc = rc; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d", + TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d", __entry->xid, __entry->sesid, __entry->tid, __entry->fid, __entry->offset, __entry->len, __entry->rc) ) @@ -247,7 +247,7 @@ DECLARE_EVENT_CLASS(smb3_copy_range_err_ __entry->len = len; __entry->rc = rc; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x source fid=0x%llx source offset=0x%llx target fid=0x%llx target offset=0x%llx len=0x%x rc=%d", + TP_printk("xid=%u sid=0x%llx tid=0x%x source fid=0x%llx source offset=0x%llx target fid=0x%llx target offset=0x%llx len=0x%x rc=%d", __entry->xid, __entry->sesid, __entry->tid, __entry->target_fid, __entry->src_offset, __entry->target_fid, __entry->target_offset, __entry->len, __entry->rc) ) @@ -298,7 +298,7 @@ DECLARE_EVENT_CLASS(smb3_copy_range_done __entry->target_offset = target_offset; __entry->len = len; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x source fid=0x%llx source offset=0x%llx target fid=0x%llx target offset=0x%llx len=0x%x", + TP_printk("xid=%u sid=0x%llx tid=0x%x source fid=0x%llx source offset=0x%llx target fid=0x%llx target offset=0x%llx len=0x%x", __entry->xid, __entry->sesid, __entry->tid, __entry->target_fid, __entry->src_offset, __entry->target_fid, __entry->target_offset, __entry->len) ) @@ -482,7 +482,7 @@ DECLARE_EVENT_CLASS(smb3_fd_class, __entry->tid = tid; __entry->sesid = sesid; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x fid=0x%llx", + TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx", __entry->xid, __entry->sesid, __entry->tid, __entry->fid) )
@@ -521,7 +521,7 @@ DECLARE_EVENT_CLASS(smb3_fd_err_class, __entry->sesid = sesid; __entry->rc = rc; ), - TP_printk("\txid=%u sid=0x%llx tid=0x%x fid=0x%llx rc=%d", + TP_printk("xid=%u sid=0x%llx tid=0x%x fid=0x%llx rc=%d", __entry->xid, __entry->sesid, __entry->tid, __entry->fid, __entry->rc) ) @@ -794,7 +794,7 @@ DECLARE_EVENT_CLASS(smb3_cmd_err_class, __entry->status = status; __entry->rc = rc; ), - TP_printk("\tsid=0x%llx tid=0x%x cmd=%u mid=%llu status=0x%x rc=%d", + TP_printk("sid=0x%llx tid=0x%x cmd=%u mid=%llu status=0x%x rc=%d", __entry->sesid, __entry->tid, __entry->cmd, __entry->mid, __entry->status, __entry->rc) ) @@ -829,7 +829,7 @@ DECLARE_EVENT_CLASS(smb3_cmd_done_class, __entry->cmd = cmd; __entry->mid = mid; ), - TP_printk("\tsid=0x%llx tid=0x%x cmd=%u mid=%llu", + TP_printk("sid=0x%llx tid=0x%x cmd=%u mid=%llu", __entry->sesid, __entry->tid, __entry->cmd, __entry->mid) ) @@ -867,7 +867,7 @@ DECLARE_EVENT_CLASS(smb3_mid_class, __entry->when_sent = when_sent; __entry->when_received = when_received; ), - TP_printk("\tcmd=%u mid=%llu pid=%u, when_sent=%lu when_rcv=%lu", + TP_printk("cmd=%u mid=%llu pid=%u, when_sent=%lu when_rcv=%lu", __entry->cmd, __entry->mid, __entry->pid, __entry->when_sent, __entry->when_received) ) @@ -898,7 +898,7 @@ DECLARE_EVENT_CLASS(smb3_exit_err_class, __assign_str(func_name); __entry->rc = rc; ), - TP_printk("\t%s: xid=%u rc=%d", + TP_printk("%s: xid=%u rc=%d", __get_str(func_name), __entry->xid, __entry->rc) )
@@ -924,7 +924,7 @@ DECLARE_EVENT_CLASS(smb3_sync_err_class, __entry->ino = ino; __entry->rc = rc; ), - TP_printk("\tino=%lu rc=%d", + TP_printk("ino=%lu rc=%d", __entry->ino, __entry->rc) )
@@ -950,7 +950,7 @@ DECLARE_EVENT_CLASS(smb3_enter_exit_clas __entry->xid = xid; __assign_str(func_name); ), - TP_printk("\t%s: xid=%u", + TP_printk("%s: xid=%u", __get_str(func_name), __entry->xid) )
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park sj@kernel.org
commit 4f489fe6afb395dbc79840efa3c05440b760d883 upstream.
memcg_path_store() assigns a newly allocated memory buffer to filter->memcg_path, without deallocating the previously allocated and assigned memory buffer. As a result, users can leak kernel memory by continuously writing a data to memcg_path DAMOS sysfs file. Fix the leak by deallocating the previously set memory buffer.
Link: https://lkml.kernel.org/r/20250619183608.6647-2-sj@kernel.org Fixes: 7ee161f18b5d ("mm/damon/sysfs-schemes: implement filter directory") Signed-off-by: SeongJae Park sj@kernel.org Cc: Shuah Khan shuah@kernel.org Cc: stable@vger.kernel.org [6.3.x] Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/damon/sysfs-schemes.c | 1 + 1 file changed, 1 insertion(+)
--- a/mm/damon/sysfs-schemes.c +++ b/mm/damon/sysfs-schemes.c @@ -471,6 +471,7 @@ static ssize_t memcg_path_store(struct k return -ENOMEM;
strscpy(path, buf, count + 1); + kfree(filter->memcg_path); filter->memcg_path = path; return count; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara pc@manguebit.org
commit ff8abbd248c1f52df0c321690b88454b13ff54b2 upstream.
Some users and customers reported that their backup/copy tools started to fail when the directory being copied contained symlink targets that the client couldn't parse - even when those symlinks weren't followed.
Fix this by allowing lstat(2) and readlink(2) to succeed even when the client can't resolve the symlink target, restoring old behavior.
Cc: linux-cifs@vger.kernel.org Cc: stable@vger.kernel.org Reported-by: Remy Monsen monsen@monsen.cc Closes: https://lore.kernel.org/r/CAN+tdP7y=jqw3pBndZAGjQv0ObFq8Q=+PUDHgB36HdEz9QA6F... Reported-by: Pierguido Lambri plambri@redhat.com Fixes: 12b466eb52d9 ("cifs: Fix creating and resolving absolute NT-style symlinks") Signed-off-by: Paulo Alcantara (Red Hat) pc@manguebit.org Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/smb/client/reparse.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/fs/smb/client/reparse.c b/fs/smb/client/reparse.c index 511611206dab..1c40e42e4d89 100644 --- a/fs/smb/client/reparse.c +++ b/fs/smb/client/reparse.c @@ -875,15 +875,8 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len, abs_path += sizeof("\DosDevices\")-1; else if (strstarts(abs_path, "\GLOBAL??\")) abs_path += sizeof("\GLOBAL??\")-1; - else { - /* Unhandled absolute symlink, points outside of DOS/Win32 */ - cifs_dbg(VFS, - "absolute symlink '%s' cannot be converted from NT format " - "because points to unknown target\n", - smb_target); - rc = -EIO; - goto out; - } + else + goto out_unhandled_target;
/* Sometimes path separator after ?? is double backslash */ if (abs_path[0] == '\') @@ -910,13 +903,7 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len, abs_path++; abs_path[0] = drive_letter; } else { - /* Unhandled absolute symlink. Report an error. */ - cifs_dbg(VFS, - "absolute symlink '%s' cannot be converted from NT format " - "because points to unknown target\n", - smb_target); - rc = -EIO; - goto out; + goto out_unhandled_target; }
abs_path_len = strlen(abs_path)+1; @@ -966,6 +953,7 @@ int smb2_parse_native_symlink(char **target, const char *buf, unsigned int len, * These paths have same format as Linux symlinks, so no * conversion is needed. */ +out_unhandled_target: linux_target = smb_target; smb_target = NULL; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Han Gao rabenda.cn@gmail.com
commit 4262bd0d9cc704ea1365ac00afc1272400c2cbef upstream.
Previously only v0-v7 were correctly saved/restored, and the context of v8-v31 are damanged. Correctly save/restore v8-v31 to avoid breaking userspace.
Fixes: d863910eabaf ("riscv: vector: Support xtheadvector save/restore") Cc: stable@vger.kernel.org Signed-off-by: Han Gao rabenda.cn@gmail.com Tested-by: Xiongchuan Tan tanxiongchuan@isrc.iscas.ac.cn Reviewed-by: Charlie Jenkins charlie@rivosinc.com Reviewed-by: Yanteng Si si.yanteng@linux.dev Reviewed-by: Andy Chiu andybnac@gmail.com Link: https://lore.kernel.org/r/9b9eb2337f3d5336ce813721f8ebea51e0b2b553.174799482... Signed-off-by: Alexandre Ghiti alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/include/asm/vector.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
--- a/arch/riscv/include/asm/vector.h +++ b/arch/riscv/include/asm/vector.h @@ -200,11 +200,11 @@ static inline void __riscv_v_vstate_save THEAD_VSETVLI_T4X0E8M8D1 THEAD_VSB_V_V0T0 "add t0, t0, t4\n\t" - THEAD_VSB_V_V0T0 + THEAD_VSB_V_V8T0 "add t0, t0, t4\n\t" - THEAD_VSB_V_V0T0 + THEAD_VSB_V_V16T0 "add t0, t0, t4\n\t" - THEAD_VSB_V_V0T0 + THEAD_VSB_V_V24T0 : : "r" (datap) : "memory", "t0", "t4"); } else { asm volatile ( @@ -236,11 +236,11 @@ static inline void __riscv_v_vstate_rest THEAD_VSETVLI_T4X0E8M8D1 THEAD_VLB_V_V0T0 "add t0, t0, t4\n\t" - THEAD_VLB_V_V0T0 + THEAD_VLB_V_V8T0 "add t0, t0, t4\n\t" - THEAD_VLB_V_V0T0 + THEAD_VLB_V_V16T0 "add t0, t0, t4\n\t" - THEAD_VLB_V_V0T0 + THEAD_VLB_V_V24T0 : : "r" (datap) : "memory", "t0", "t4"); } else { asm volatile (
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Schramm oliver.schramm97@gmail.com
commit bf39286adc5e10ce3e32eb86ad316ae56f3b52a0 upstream.
It's smaller brother has already received the patch to enable the microphone, now add it too to the DMI quirk table.
Cc: stable@vger.kernel.org Signed-off-by: Oliver Schramm oliver.schramm97@gmail.com Link: https://patch.msgid.link/20250621223000.11817-2-oliver.schramm97@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -356,6 +356,13 @@ static const struct dmi_system_id yc_acp { .driver_data = &acp6x_card, .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83J3"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), DMI_MATCH(DMI_PRODUCT_NAME, "UM5302TA"), }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Klara Modin klarasmodin@gmail.com
commit c5136add3f9b4c23b8bbe5f4d722c95d4cfb936e upstream.
The mailbox controller driver for the Microchip Inter-processor Communication can be built as a module. It uses cpuid_to_hartid_map and commit 4783ce32b080 ("riscv: export __cpuid_to_hartid_map") enables that to work for SMP. However, cpuid_to_hartid_map uses boot_cpu_hartid on non-SMP kernels and this driver can be useful in such configurations[1].
Export boot_cpu_hartid so the driver can be built as a module on non-SMP kernels as well.
Link: https://lore.kernel.org/lkml/20250617-confess-reimburse-876101e099cb@spud/ [1] Cc: stable@vger.kernel.org Fixes: e4b1d67e7141 ("mailbox: add Microchip IPC support") Signed-off-by: Klara Modin klarasmodin@gmail.com Acked-by: Conor Dooley conor.dooley@microchip.com Link: https://lore.kernel.org/r/20250617125847.23829-1-klarasmodin@gmail.com Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/kernel/setup.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c index f7c9a1caa83e..14888e5ea19a 100644 --- a/arch/riscv/kernel/setup.c +++ b/arch/riscv/kernel/setup.c @@ -50,6 +50,7 @@ atomic_t hart_lottery __section(".sdata") #endif ; unsigned long boot_cpu_hartid; +EXPORT_SYMBOL_GPL(boot_cpu_hartid);
/* * Place kernel memory regions on the resource tree so that
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin pchelkin@ispras.ru
commit 7360ee47599af91a1d5f4e74d635d9408a54e489 upstream.
Number of apqn target list entries contained in 'nr_apqns' variable is determined by userspace via an ioctl call so the result of the product in calculation of size passed to memdup_user() may overflow.
In this case the actual size of the allocated area and the value describing it won't be in sync leading to various types of unpredictable behaviour later.
Use a proper memdup_array_user() helper which returns an error if an overflow is detected. Note that it is different from when nr_apqns is initially zero - that case is considered valid and should be handled in subsequent pkey_handler implementations.
Found by Linux Verification Center (linuxtesting.org).
Fixes: f2bbc96e7cfa ("s390/pkey: add CCA AES cipher key support") Cc: stable@vger.kernel.org Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Reviewed-by: Holger Dengler dengler@linux.ibm.com Reviewed-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/20250611192011.206057-1-pchelkin@ispras.ru Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/s390/crypto/pkey_api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -85,7 +85,7 @@ static void *_copy_apqns_from_user(void if (!uapqns || nr_apqns == 0) return NULL;
- return memdup_user(uapqns, nr_apqns * sizeof(struct pkey_apqn)); + return memdup_array_user(uapqns, nr_apqns, sizeof(struct pkey_apqn)); }
static int pkey_ioctl_genseck(struct pkey_genseck __user *ugs)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
commit 5afb4bf9fc62d828647647ec31745083637132e4 upstream.
syzbot complains about an unmapping failure:
[ 108.070381][ T14] kernel BUG at mm/gup.c:71! [ 108.070502][ T14] Internal error: Oops - BUG: 00000000f2000800 [#1] SMP [ 108.123672][ T14] Hardware name: QEMU KVM Virtual Machine, BIOS edk2-20250221-8.fc42 02/21/2025 [ 108.127458][ T14] Workqueue: iou_exit io_ring_exit_work [ 108.174205][ T14] Call trace: [ 108.175649][ T14] sanity_check_pinned_pages+0x7cc/0x7d0 (P) [ 108.178138][ T14] unpin_user_page+0x80/0x10c [ 108.180189][ T14] io_release_ubuf+0x84/0xf8 [ 108.182196][ T14] io_free_rsrc_node+0x250/0x57c [ 108.184345][ T14] io_rsrc_data_free+0x148/0x298 [ 108.186493][ T14] io_sqe_buffers_unregister+0x84/0xa0 [ 108.188991][ T14] io_ring_ctx_free+0x48/0x480 [ 108.191057][ T14] io_ring_exit_work+0x764/0x7d8 [ 108.193207][ T14] process_one_work+0x7e8/0x155c [ 108.195431][ T14] worker_thread+0x958/0xed8 [ 108.197561][ T14] kthread+0x5fc/0x75c [ 108.199362][ T14] ret_from_fork+0x10/0x20
We can pin a tail page of a folio, but then io_uring will try to unpin the head page of the folio. While it should be fine in terms of keeping the page actually alive, mm folks say it's wrong and triggers a debug warning. Use unpin_user_folio() instead of unpin_user_page*.
Cc: stable@vger.kernel.org Debugged-by: David Hildenbrand david@redhat.com Reported-by: syzbot+1d335893772467199ab6@syzkaller.appspotmail.com Closes: https://lkml.kernel.org/r/683f1551.050a0220.55ceb.0017.GAE@google.com Fixes: a8edbb424b139 ("io_uring/rsrc: enable multi-hugepage buffer coalescing") Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/io-uring/a28b0f87339ac2acf14a645dad1e95bbcbf18acd.17... [axboe: adapt to current tree, massage commit message] Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/rsrc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
--- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -112,8 +112,11 @@ static void io_release_ubuf(void *priv) struct io_mapped_ubuf *imu = priv; unsigned int i;
- for (i = 0; i < imu->nr_bvecs; i++) - unpin_user_page(imu->bvec[i].bv_page); + for (i = 0; i < imu->nr_bvecs; i++) { + struct folio *folio = page_folio(imu->bvec[i].bv_page); + + unpin_user_folio(folio, 1); + } }
static struct io_mapped_ubuf *io_alloc_imu(struct io_ring_ctx *ctx, @@ -844,8 +847,10 @@ done: if (ret) { if (imu) io_free_imu(ctx, imu); - if (pages) - unpin_user_pages(pages, nr_pages); + if (pages) { + for (i = 0; i < nr_pages; i++) + unpin_user_folio(page_folio(pages[i]), 1); + } io_cache_free(&ctx->node_cache, node); node = ERR_PTR(ret); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
commit 3a3c6d61577dbb23c09df3e21f6f9eda1ecd634b upstream.
There is no guaranteed alignment for user pointers, however the calculation of an offset of the first page into a folio after coalescing uses some weird bit mask logic, get rid of it.
Cc: stable@vger.kernel.org Reported-by: David Hildenbrand david@redhat.com Fixes: a8edbb424b139 ("io_uring/rsrc: enable multi-hugepage buffer coalescing") Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/io-uring/e387b4c78b33f231105a601d84eefd8301f57954.17... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/rsrc.c | 7 ++++++- io_uring/rsrc.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-)
--- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -738,6 +738,7 @@ bool io_check_coalesce_buffer(struct pag
data->nr_pages_mid = folio_nr_pages(folio); data->folio_shift = folio_shift(folio); + data->first_folio_page_idx = folio_page_idx(folio, page_array[0]);
/* * Check if pages are contiguous inside a folio, and all folios have @@ -831,7 +832,11 @@ static struct io_rsrc_node *io_sqe_buffe if (coalesced) imu->folio_shift = data.folio_shift; refcount_set(&imu->refs, 1); - off = (unsigned long) iov->iov_base & ((1UL << imu->folio_shift) - 1); + + off = (unsigned long)iov->iov_base & ~PAGE_MASK; + if (coalesced) + off += data.first_folio_page_idx << PAGE_SHIFT; + node->buf = imu; ret = 0;
--- a/io_uring/rsrc.h +++ b/io_uring/rsrc.h @@ -49,6 +49,7 @@ struct io_imu_folio_data { unsigned int nr_pages_mid; unsigned int folio_shift; unsigned int nr_folios; + unsigned long first_folio_page_idx; };
bool io_rsrc_cache_init(struct io_ring_ctx *ctx);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
commit e1d7727b73a1f78035316ac35ee184d477059f0b upstream.
There is no guaranteed alignment for user pointers. Don't use mask trickery and adjust the offset by bv_offset.
Cc: stable@vger.kernel.org Reported-by: David Hildenbrand david@redhat.com Fixes: 9ef4cbbcb4ac3 ("io_uring: add infra for importing vectored reg buffers") Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/io-uring/19530391f5c361a026ac9b401ff8e123bde55d98.17... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/rsrc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/io_uring/rsrc.c b/io_uring/rsrc.c index afc67530f912..f2b31fb68992 100644 --- a/io_uring/rsrc.c +++ b/io_uring/rsrc.c @@ -1339,7 +1339,6 @@ static int io_vec_fill_bvec(int ddir, struct iov_iter *iter, { unsigned long folio_size = 1 << imu->folio_shift; unsigned long folio_mask = folio_size - 1; - u64 folio_addr = imu->ubuf & ~folio_mask; struct bio_vec *res_bvec = vec->bvec; size_t total_len = 0; unsigned bvec_idx = 0; @@ -1361,8 +1360,13 @@ static int io_vec_fill_bvec(int ddir, struct iov_iter *iter, if (unlikely(check_add_overflow(total_len, iov_len, &total_len))) return -EOVERFLOW;
- /* by using folio address it also accounts for bvec offset */ - offset = buf_addr - folio_addr; + offset = buf_addr - imu->ubuf; + /* + * Only the first bvec can have non zero bv_offset, account it + * here and work with full folios below. + */ + offset += imu->bvec[0].bv_offset; + src_bvec = imu->bvec + (offset >> imu->folio_shift); offset &= folio_mask;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand david@redhat.com
commit 4a5e85f4eb8fd18b1266342d100e4f0849544ca0 upstream.
is_zero_pfn() does not work for the huge zero folio. Fix it by using is_huge_zero_pmd().
This can cause the PAGEMAP_SCAN ioctl against /proc/pid/pagemap to present pages as PAGE_IS_PRESENT rather than as PAGE_IS_PFNZERO.
Found by code inspection.
Link: https://lkml.kernel.org/r/20250617143532.2375383-1-david@redhat.com Fixes: 52526ca7fdb9 ("fs/proc/task_mmu: implement IOCTL to get and optionally clear info about PTEs") Signed-off-by: David Hildenbrand david@redhat.com Cc: Muhammad Usama Anjum usama.anjum@collabora.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/proc/task_mmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c @@ -2179,7 +2179,7 @@ static unsigned long pagemap_thp_categor categories |= PAGE_IS_FILE; }
- if (is_zero_pfn(pmd_pfn(pmd))) + if (is_huge_zero_pmd(pmd)) categories |= PAGE_IS_PFNZERO; if (pmd_soft_dirty(pmd)) categories |= PAGE_IS_SOFT_DIRTY;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Kuai yukuai3@huawei.com
commit df831e97739405ecbaddb85516bc7d4d1c933d6b upstream.
While testing null_blk with configfs, echo 0 > poll_queues will trigger following panic:
BUG: kernel NULL pointer dereference, address: 0000000000000010 Oops: Oops: 0000 [#1] SMP NOPTI CPU: 27 UID: 0 PID: 920 Comm: bash Not tainted 6.15.0-02023-gadbdb95c8696-dirty #1238 PREEMPT(undef) Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014 RIP: 0010:__bitmap_or+0x48/0x70 Call Trace: <TASK> __group_cpus_evenly+0x822/0x8c0 group_cpus_evenly+0x2d9/0x490 blk_mq_map_queues+0x1e/0x110 null_map_queues+0xc9/0x170 [null_blk] blk_mq_update_queue_map+0xdb/0x160 blk_mq_update_nr_hw_queues+0x22b/0x560 nullb_update_nr_hw_queues+0x71/0xf0 [null_blk] nullb_device_poll_queues_store+0xa4/0x130 [null_blk] configfs_write_iter+0x109/0x1d0 vfs_write+0x26e/0x6f0 ksys_write+0x79/0x180 __x64_sys_write+0x1d/0x30 x64_sys_call+0x45c4/0x45f0 do_syscall_64+0xa5/0x240 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Root cause is that numgrps is set to 0, and ZERO_SIZE_PTR is returned from kcalloc(), and later ZERO_SIZE_PTR will be deferenced.
Fix the problem by checking numgrps first in group_cpus_evenly(), and return NULL directly if numgrps is zero.
[yukuai3@huawei.com: also fix the non-SMP version] Link: https://lkml.kernel.org/r/20250620010958.1265984-1-yukuai1@huaweicloud.com Link: https://lkml.kernel.org/r/20250619132655.3318883-1-yukuai1@huaweicloud.com Fixes: 6a6dcae8f486 ("blk-mq: Build default queue map via group_cpus_evenly()") Signed-off-by: Yu Kuai yukuai3@huawei.com Reviewed-by: Ming Lei ming.lei@redhat.com Reviewed-by: Jens Axboe axboe@kernel.dk Cc: ErKun Yang yangerkun@huawei.com Cc: John Garry john.g.garry@oracle.com Cc: Thomas Gleinxer tglx@linutronix.de Cc: "zhangyi (F)" yi.zhang@huawei.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/group_cpus.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/lib/group_cpus.c +++ b/lib/group_cpus.c @@ -352,6 +352,9 @@ struct cpumask *group_cpus_evenly(unsign int ret = -ENOMEM; struct cpumask *masks = NULL;
+ if (numgrps == 0) + return NULL; + if (!zalloc_cpumask_var(&nmsk, GFP_KERNEL)) return NULL;
@@ -426,8 +429,12 @@ struct cpumask *group_cpus_evenly(unsign #else /* CONFIG_SMP */ struct cpumask *group_cpus_evenly(unsigned int numgrps) { - struct cpumask *masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); + struct cpumask *masks;
+ if (numgrps == 0) + return NULL; + + masks = kcalloc(numgrps, sizeof(*masks), GFP_KERNEL); if (!masks) return NULL;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nam Cao namcao@linutronix.de
commit 890ba5be6335dbbbc99af14ea007befb5f83f174 upstream.
This reverts commit ad5643cf2f69 ("riscv: Define TASK_SIZE_MAX for __access_ok()").
This commit changes TASK_SIZE_MAX to be LONG_MAX to optimize access_ok(), because the previous TASK_SIZE_MAX (default to TASK_SIZE) requires some computation.
The reasoning was that all user addresses are less than LONG_MAX, and all kernel addresses are greater than LONG_MAX. Therefore access_ok() can filter kernel addresses.
Addresses between TASK_SIZE and LONG_MAX are not valid user addresses, but access_ok() let them pass. That was thought to be okay, because they are not valid addresses at hardware level.
Unfortunately, one case is missed: get_user_pages_fast() happily accepts addresses between TASK_SIZE and LONG_MAX. futex(), for instance, uses get_user_pages_fast(). This causes the problem reported by Robert [1].
Therefore, revert this commit. TASK_SIZE_MAX is changed to the default: TASK_SIZE.
This unfortunately reduces performance, because TASK_SIZE is more expensive to compute compared to LONG_MAX. But correctness first, we can think about optimization later, if required.
Reported-by: rtm@csail.mit.edu Closes: https://lore.kernel.org/linux-riscv/77605.1750245028@localhost/ Signed-off-by: Nam Cao namcao@linutronix.de Cc: stable@vger.kernel.org Reviewed-by: Alexandre Ghiti alexghiti@rivosinc.com Fixes: ad5643cf2f69 ("riscv: Define TASK_SIZE_MAX for __access_ok()") Link: https://lore.kernel.org/r/20250619155858.1249789-1-namcao@linutronix.de Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/include/asm/pgtable.h | 1 - 1 file changed, 1 deletion(-)
--- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -980,7 +980,6 @@ static inline pte_t pte_swp_clear_exclus */ #ifdef CONFIG_64BIT #define TASK_SIZE_64 (PGDIR_SIZE * PTRS_PER_PGD / 2) -#define TASK_SIZE_MAX LONG_MAX
#ifdef CONFIG_COMPAT #define TASK_SIZE_32 (_AC(0x80000000, UL) - PAGE_SIZE)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nam Cao namcao@linutronix.de
commit 2f73c62d4e13df67380ff6faca39eec2bf08dd93 upstream.
This reverts commit 61a74ad25462 ("riscv: misaligned: fix sleeping function called during misaligned access handling"). The commit addresses a sleeping in atomic context problem, but it is not the correct fix as explained by Clément:
"Using nofault would lead to failure to read from user memory that is paged out for instance. This is not really acceptable, we should handle user misaligned access even at an address that would generate a page fault."
This bug has been properly fixed by commit 453805f0a28f ("riscv: misaligned: enable IRQs while handling misaligned accesses").
Revert this improper fix.
Link: https://lore.kernel.org/linux-riscv/b779beed-e44e-4a5e-9551-4647682b0d21@riv... Signed-off-by: Nam Cao namcao@linutronix.de Cc: stable@vger.kernel.org Reviewed-by: Clément Léger cleger@rivosinc.com Reviewed-by: Alexandre Ghiti alexghiti@rivosinc.com Fixes: 61a74ad25462 ("riscv: misaligned: fix sleeping function called during misaligned access handling") Link: https://lore.kernel.org/r/20250620110939.1642735-1-namcao@linutronix.de Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/kernel/traps_misaligned.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/riscv/kernel/traps_misaligned.c +++ b/arch/riscv/kernel/traps_misaligned.c @@ -453,7 +453,7 @@ static int handle_scalar_misaligned_load
val.data_u64 = 0; if (user_mode(regs)) { - if (copy_from_user_nofault(&val, (u8 __user *)addr, len)) + if (copy_from_user(&val, (u8 __user *)addr, len)) return -1; } else { memcpy(&val, (u8 *)addr, len); @@ -554,7 +554,7 @@ static int handle_scalar_misaligned_stor return -EOPNOTSUPP;
if (user_mode(regs)) { - if (copy_to_user_nofault((u8 __user *)addr, &val, len)) + if (copy_to_user((u8 __user *)addr, &val, len)) return -1; } else { memcpy((u8 *)addr, &val, len);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak imre.deak@intel.com
commit a3ef3c2da675a8a564c8bea1a511cdd0a2a9aa49 upstream.
Reading DPCD registers has side-effects in general. In particular accessing registers outside of the link training register range (0x102-0x106, 0x202-0x207, 0x200c-0x200f, 0x2216) is explicitly forbidden by the DP v2.1 Standard, see
3.6.5.1 DPTX AUX Transaction Handling Mandates 3.6.7.4 128b/132b DP Link Layer LTTPR Link Training Mandates
Based on my tests, accessing the DPCD_REV register during the link training of an UHBR TBT DP tunnel sink leads to link training failures.
Solve the above by using the DP_LANE0_1_STATUS (0x202) register for the DPCD register access quirk.
Cc: stable@vger.kernel.org Cc: Ville Syrjälä ville.syrjala@linux.intel.com Cc: Jani Nikula jani.nikula@linux.intel.com Acked-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Imre Deak imre.deak@intel.com Link: https://lore.kernel.org/r/20250605082850.65136-2-imre.deak@intel.com (cherry picked from commit a40c5d727b8111b5db424a1e43e14a1dcce1e77f) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -723,7 +723,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_a * monitor doesn't power down exactly after the throw away read. */ if (!aux->is_remote) { - ret = drm_dp_dpcd_probe(aux, DP_DPCD_REV); + ret = drm_dp_dpcd_probe(aux, DP_LANE0_1_STATUS); if (ret < 0) return ret; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai tiwai@suse.de
commit 6847b3b6e84ef37451c074e6a8db3fbd250c8dbf upstream.
When EDID is retrieved via drm_edid_raw(), it doesn't guarantee to return proper EDID bytes the caller wants: it may be either NULL (that leads to an Oops) or with too long bytes over the fixed size raw_edid array (that may lead to memory corruption). The latter was reported actually when connected with a bad adapter.
Add sanity checks for drm_edid_raw() to address the above corner cases, and return EDID_BAD_INPUT accordingly.
Fixes: 48edb2a4256e ("drm/amd/display: switch amdgpu_dm_connector to use struct drm_edid") Link: https://bugzilla.suse.com/show_bug.cgi?id=1236415 Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 648d3f4d209725d51900d6a3ed46b7b600140cdf) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 4 ++++ 1 file changed, 4 insertions(+)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -1016,6 +1016,10 @@ enum dc_edid_status dm_helpers_read_loca return EDID_NO_RESPONSE;
edid = drm_edid_raw(drm_edid); // FIXME: Get rid of drm_edid_raw() + if (!edid || + edid->extensions >= sizeof(sink->dc_edid.raw_edid) / EDID_LENGTH) + return EDID_BAD_INPUT; + sink->dc_edid.length = EDID_LENGTH * (edid->extensions + 1); memmove(sink->dc_edid.raw_edid, (uint8_t *)edid, sink->dc_edid.length);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher alexander.deucher@amd.com
commit 99579c55c3d6132a5236926652c0a72a526b809d upstream.
Seems some older MES firmware versions do not properly support this packet. Add back some the compatibility checks.
v2: switch to fw version check (Shaoyun)
Fixes: f81cd793119e ("drm/amd/amdgpu: Fix MES init sequence") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4295 Cc: Shaoyun Liu shaoyun.liu@amd.com Reviewed-by: shaoyun.liu shaoyun.liu@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 0180e0a5dd5c6ff118043ee42dbbbddaf881f283) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 10 ++++++---- drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 3 ++- 2 files changed, 8 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v11_0.c @@ -1649,10 +1649,12 @@ static int mes_v11_0_hw_init(struct amdg if (r) goto failure;
- r = mes_v11_0_set_hw_resources_1(&adev->mes); - if (r) { - DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r); - goto failure; + if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x50) { + r = mes_v11_0_set_hw_resources_1(&adev->mes); + if (r) { + DRM_ERROR("failed mes_v11_0_set_hw_resources_1, r=%d\n", r); + goto failure; + } }
r = mes_v11_0_query_sched_status(&adev->mes); --- a/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/mes_v12_0.c @@ -1761,7 +1761,8 @@ static int mes_v12_0_hw_init(struct amdg if (r) goto failure;
- mes_v12_0_set_hw_resources_1(&adev->mes, AMDGPU_MES_SCHED_PIPE); + if ((adev->mes.sched_version & AMDGPU_MES_VERSION_MASK) >= 0x4b) + mes_v12_0_set_hw_resources_1(&adev->mes, AMDGPU_MES_SCHED_PIPE);
mes_v12_0_init_aggregated_doorbell(&adev->mes);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li haoxiang_li2024@163.com
commit 62207293479e6c03ef498a70f2914c51f4d31d2c upstream.
Add check for the return value of alloc_ordered_workqueue() in xe_display_create() to catch potential exception.
Fixes: 44e694958b95 ("drm/xe/display: Implement display support") Cc: stable@vger.kernel.org Signed-off-by: Haoxiang Li haoxiang_li2024@163.com Reviewed-by: Matthew Auld matthew.auld@intel.com Link: https://lore.kernel.org/r/4ee1b0e5d1626ce1dde2e82af05c2edaed50c3aa.174739763... Signed-off-by: Jani Nikula jani.nikula@intel.com (cherry picked from commit 5b62d63395d5b7d4094e7cd380bccae4b25415cb) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/display/xe_display.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -104,6 +104,8 @@ int xe_display_create(struct xe_device * spin_lock_init(&xe->display.fb_tracking.lock);
xe->display.hotplug.dp_wq = alloc_ordered_workqueue("xe-dp", 0); + if (!xe->display.hotplug.dp_wq) + return -ENOMEM;
return drmm_add_action_or_reset(&xe->drm, display_destroy, NULL); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ankit Nautiyal ankit.k.nautiyal@intel.com
commit 9205999e9f13a07cb29d5a8836c25afdca186007 upstream.
DIV_ROUND_CLOSEST_ULL uses do_div(), which expects a 32-bit divisor. When passing a 64-bit constant like CURVE2_MULTIPLIER, the value is silently truncated to u32, potentially leading to incorrect results on large divisors.
Replace DIV_ROUND_CLOSEST_ULL with DIV64_U64_ROUND_CLOSEST which correctly handles full 64-bit division.
v2: Use DIV64_U64_ROUND_CLOSEST instead of div64_u64 macro. (Jani)
Fixes: 5947642004bf ("drm/i915/display: Add support for SNPS PHY HDMI PLL algorithm for DG2") Reported-by: Vas Novikov vasya.novikov@gmail.com Closes: https://lore.kernel.org/all/8d7c7958-9558-4c8a-a81a-e9310f2d8852@gmail.com/ Cc: Ankit Nautiyal ankit.k.nautiyal@intel.com Cc: Suraj Kandpal suraj.kandpal@intel.com Cc: Jani Nikula jani.nikula@intel.com Cc: Vas Novikov vasya.novikov@gmail.com Cc: stable@vger.kernel.org # v6.15+ Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Ankit Nautiyal ankit.k.nautiyal@intel.com Link: https://lore.kernel.org/r/20250618130951.1596587-2-ankit.k.nautiyal@intel.co... (cherry picked from commit b300a175a11e6a934d728317dc39787723cc7917) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c index 74bb3bedf30f..5111bdc3075b 100644 --- a/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c +++ b/drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c @@ -103,8 +103,8 @@ static void get_ana_cp_int_prop(u64 vco_clk, DIV_ROUND_DOWN_ULL(curve_1_interpolated, CURVE0_MULTIPLIER)));
ana_cp_int_temp = - DIV_ROUND_CLOSEST_ULL(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1), - CURVE2_MULTIPLIER); + DIV64_U64_ROUND_CLOSEST(DIV_ROUND_DOWN_ULL(adjusted_vco_clk1, curve_2_scaled1), + CURVE2_MULTIPLIER);
*ana_cp_int = max(1, min(ana_cp_int_temp, 127));
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maarten Lankhorst maarten.lankhorst@linux.intel.com
commit a4b1b51ae132ac199412028a2df7b6c267888190 upstream.
Flushing l2 is only needed after all data has been written.
Fixes: 01570b446939 ("drm/xe/bmg: implement Wa_16023588340") Signed-off-by: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Matthew Auld matthew.auld@intel.com Cc: stable@vger.kernel.org # v6.12+ Reviewed-by: Matthew Auld matthew.auld@intel.com Signed-off-by: Matthew Auld matthew.auld@intel.com Reviewed-by: Lucas De Marchi lucas.demarchi@intel.com Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://lore.kernel.org/r/20250606104546.1996818-3-matthew.auld@intel.com Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com (cherry picked from commit 0dd2dd0182bc444a62652e89d08c7f0e4fde15ba) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/display/xe_dsb_buffer.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
--- a/drivers/gpu/drm/xe/display/xe_dsb_buffer.c +++ b/drivers/gpu/drm/xe/display/xe_dsb_buffer.c @@ -17,10 +17,7 @@ u32 intel_dsb_buffer_ggtt_offset(struct
void intel_dsb_buffer_write(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val) { - struct xe_device *xe = dsb_buf->vma->bo->tile->xe; - iosys_map_wr(&dsb_buf->vma->bo->vmap, idx * 4, u32, val); - xe_device_l2_flush(xe); }
u32 intel_dsb_buffer_read(struct intel_dsb_buffer *dsb_buf, u32 idx) @@ -30,12 +27,9 @@ u32 intel_dsb_buffer_read(struct intel_d
void intel_dsb_buffer_memset(struct intel_dsb_buffer *dsb_buf, u32 idx, u32 val, size_t size) { - struct xe_device *xe = dsb_buf->vma->bo->tile->xe; - WARN_ON(idx > (dsb_buf->buf_size - size) / sizeof(*dsb_buf->cmd_buf));
iosys_map_memset(&dsb_buf->vma->bo->vmap, idx * 4, val, size); - xe_device_l2_flush(xe); }
bool intel_dsb_buffer_create(struct intel_crtc *crtc, struct intel_dsb_buffer *dsb_buf, size_t size) @@ -74,9 +68,12 @@ void intel_dsb_buffer_cleanup(struct int
void intel_dsb_buffer_flush_map(struct intel_dsb_buffer *dsb_buf) { + struct xe_device *xe = dsb_buf->vma->bo->tile->xe; + /* * The memory barrier here is to ensure coherency of DSB vs MMIO, * both for weak ordering archs and discrete cards. */ - xe_device_wmb(dsb_buf->vma->bo->tile->xe); + xe_device_wmb(xe); + xe_device_l2_flush(xe); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Auld matthew.auld@intel.com
commit f16873f42a06b620669d48a4b5c3f888cb3653a1 upstream.
Only need the flush for DPT host updates here. Normal GGTT updates don't need special flush.
Fixes: 01570b446939 ("drm/xe/bmg: implement Wa_16023588340") Signed-off-by: Matthew Auld matthew.auld@intel.com Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: stable@vger.kernel.org # v6.12+ Reviewed-by: Ville Syrjälä ville.syrjala@linux.intel.com Reviewed-by: Lucas De Marchi lucas.demarchi@intel.com Link: https://lore.kernel.org/r/20250606104546.1996818-4-matthew.auld@intel.com Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com (cherry picked from commit 35db1da40c8cfd7511dc42f342a133601eb45449) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/display/xe_fb_pin.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/xe/display/xe_fb_pin.c +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c @@ -164,6 +164,9 @@ static int __xe_pin_fb_vma_dpt(const str
vma->dpt = dpt; vma->node = dpt->ggtt_node[tile0->id]; + + /* Ensure DPT writes are flushed */ + xe_device_l2_flush(xe); return 0; }
@@ -333,8 +336,6 @@ static struct i915_vma *__xe_pin_fb_vma( if (ret) goto err_unpin;
- /* Ensure DPT writes are flushed */ - xe_device_l2_flush(xe); return vma;
err_unpin:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Even Xu even.xu@intel.com
[ Upstream commit 73f3a7415d93cf418c7625d03bce72da84344406 ]
During customer board enabling, it was found: some touch devices prepared reset response, but either forgot sending interrupt or THC missed reset interrupt because of timing issue. THC QuickI2C driver depends on interrupt to read reset response, in this case, it will cause driver waiting timeout.
This patch enhances the flow by adding manually reset response reading after waiting for reset interrupt timeout.
Signed-off-by: Even Xu even.xu@intel.com Tested-by: Chong Han chong.han@intel.com Fixes: 66b59bfce6d9 ("HID: intel-thc-hid: intel-quicki2c: Complete THC QuickI2C driver") Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../intel-quicki2c/quicki2c-protocol.c | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c index f493df0d5dc4e..a63f8c833252d 100644 --- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-protocol.c @@ -4,6 +4,7 @@ #include <linux/bitfield.h> #include <linux/hid.h> #include <linux/hid-over-i2c.h> +#include <linux/unaligned.h>
#include "intel-thc-dev.h" #include "intel-thc-dma.h" @@ -200,6 +201,9 @@ int quicki2c_set_report(struct quicki2c_device *qcdev, u8 report_type,
int quicki2c_reset(struct quicki2c_device *qcdev) { + u16 input_reg = le16_to_cpu(qcdev->dev_desc.input_reg); + size_t read_len = HIDI2C_LENGTH_LEN; + u32 prd_len = read_len; int ret;
qcdev->reset_ack = false; @@ -213,12 +217,32 @@ int quicki2c_reset(struct quicki2c_device *qcdev)
ret = wait_event_interruptible_timeout(qcdev->reset_ack_wq, qcdev->reset_ack, HIDI2C_RESET_TIMEOUT * HZ); - if (ret <= 0 || !qcdev->reset_ack) { + if (qcdev->reset_ack) + return 0; + + /* + * Manually read reset response if it wasn't received, in case reset interrupt + * was missed by touch device or THC hardware. + */ + ret = thc_tic_pio_read(qcdev->thc_hw, input_reg, read_len, &prd_len, + (u32 *)qcdev->input_buf); + if (ret) { + dev_err_once(qcdev->dev, "Read Reset Response failed, ret %d\n", ret); + return ret; + } + + /* + * Check response packet length, it's first 16 bits of packet. + * If response packet length is zero, it's reset response, otherwise not. + */ + if (get_unaligned_le16(qcdev->input_buf)) { dev_err_once(qcdev->dev, "Wait reset response timed out ret:%d timeout:%ds\n", ret, HIDI2C_RESET_TIMEOUT); return -ETIMEDOUT; }
+ qcdev->reset_ack = true; + return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zeitlhofer thomas.zeitlhofer+lkml@ze-it.at
[ Upstream commit f3054152c12e2eed1e72704aff47b0ea58229584 ]
Commit fd2a9b29dc9c ("HID: wacom: Remove AES power_supply after extended inactivity") introduced wacom_aes_battery_handler() which is scheduled as a delayed work (aes_battery_work).
In wacom_remove(), aes_battery_work is not canceled. Consequently, if the device is removed while aes_battery_work is still pending, then hard crashes or "Oops: general protection fault..." are experienced when wacom_aes_battery_handler() is finally called. E.g., this happens with built-in USB devices after resume from hibernate when aes_battery_work was still pending at the time of hibernation.
So, take care to cancel aes_battery_work in wacom_remove().
Fixes: fd2a9b29dc9c ("HID: wacom: Remove AES power_supply after extended inactivity") Signed-off-by: Thomas Zeitlhofer thomas.zeitlhofer+lkml@ze-it.at Acked-by: Ping Cheng ping.cheng@wacom.com Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/hid/wacom_sys.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index eaf099b2efdb0..e74c1a4c5b61c 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2901,6 +2901,7 @@ static void wacom_remove(struct hid_device *hdev) hid_hw_stop(hdev);
cancel_delayed_work_sync(&wacom->init_work); + cancel_delayed_work_sync(&wacom->aes_battery_work); cancel_work_sync(&wacom->wireless_work); cancel_work_sync(&wacom->battery_work); cancel_work_sync(&wacom->remote_work);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Williams dan.j.williams@intel.com
[ Upstream commit 3c70ec71abdaf4e4fa48cd8fdfbbd864d78235a8 ]
By inspection, cxl_cper_handle_prot_err() is making a series of fragile assumptions that can lead to crashes:
1/ It assumes that endpoints identified in the record are a CXL-type-3 device, nothing guarantees that.
2/ It assumes that the device is bound to the cxl_pci driver, nothing guarantees that.
3/ Minor, it holds the device lock over the switch-port tracing for no reason as the trace is 100% generated from data in the record.
Correct those by checking that the PCIe endpoint parents a cxl_memdev before assuming the format of the driver data, and move the lock to where it is required. Consequently this also makes the implementation ready for CXL accelerators that are not bound to cxl_pci.
Fixes: 36f257e3b0ba ("acpi/ghes, cxl/pci: Process CXL CPER Protocol Errors") Cc: Terry Bowman terry.bowman@amd.com Cc: Li Ming ming.li@zohomail.com Cc: Alison Schofield alison.schofield@intel.com Cc: Ira Weiny ira.weiny@intel.com Cc: Tony Luck tony.luck@intel.com Reviewed-by: Smita Koralahalli Smita.KoralahalliChannabasappa@amd.com Reviewed-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Dan Williams dan.j.williams@intel.com Reviewed-by: Jonathan Cameron jonathan.cameron@huawei.com Reviewed-by: Li Ming ming.li@zohomail.com Link: https://patch.msgid.link/20250612192043.2254617-1-dan.j.williams@intel.com Signed-off-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cxl/core/ras.c | 47 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/drivers/cxl/core/ras.c b/drivers/cxl/core/ras.c index 485a831695c70..2731ba3a07993 100644 --- a/drivers/cxl/core/ras.c +++ b/drivers/cxl/core/ras.c @@ -31,40 +31,38 @@ static void cxl_cper_trace_uncorr_port_prot_err(struct pci_dev *pdev, ras_cap.header_log); }
-static void cxl_cper_trace_corr_prot_err(struct pci_dev *pdev, - struct cxl_ras_capability_regs ras_cap) +static void cxl_cper_trace_corr_prot_err(struct cxl_memdev *cxlmd, + struct cxl_ras_capability_regs ras_cap) { u32 status = ras_cap.cor_status & ~ras_cap.cor_mask; - struct cxl_dev_state *cxlds;
- cxlds = pci_get_drvdata(pdev); - if (!cxlds) - return; - - trace_cxl_aer_correctable_error(cxlds->cxlmd, status); + trace_cxl_aer_correctable_error(cxlmd, status); }
-static void cxl_cper_trace_uncorr_prot_err(struct pci_dev *pdev, - struct cxl_ras_capability_regs ras_cap) +static void +cxl_cper_trace_uncorr_prot_err(struct cxl_memdev *cxlmd, + struct cxl_ras_capability_regs ras_cap) { u32 status = ras_cap.uncor_status & ~ras_cap.uncor_mask; - struct cxl_dev_state *cxlds; u32 fe;
- cxlds = pci_get_drvdata(pdev); - if (!cxlds) - return; - if (hweight32(status) > 1) fe = BIT(FIELD_GET(CXL_RAS_CAP_CONTROL_FE_MASK, ras_cap.cap_control)); else fe = status;
- trace_cxl_aer_uncorrectable_error(cxlds->cxlmd, status, fe, + trace_cxl_aer_uncorrectable_error(cxlmd, status, fe, ras_cap.header_log); }
+static int match_memdev_by_parent(struct device *dev, const void *uport) +{ + if (is_cxl_memdev(dev) && dev->parent == uport) + return 1; + return 0; +} + static void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data) { unsigned int devfn = PCI_DEVFN(data->prot_err.agent_addr.device, @@ -73,13 +71,12 @@ static void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data) pci_get_domain_bus_and_slot(data->prot_err.agent_addr.segment, data->prot_err.agent_addr.bus, devfn); + struct cxl_memdev *cxlmd; int port_type;
if (!pdev) return;
- guard(device)(&pdev->dev); - port_type = pci_pcie_type(pdev); if (port_type == PCI_EXP_TYPE_ROOT_PORT || port_type == PCI_EXP_TYPE_DOWNSTREAM || @@ -92,10 +89,20 @@ static void cxl_cper_handle_prot_err(struct cxl_cper_prot_err_work_data *data) return; }
+ guard(device)(&pdev->dev); + if (!pdev->dev.driver) + return; + + struct device *mem_dev __free(put_device) = bus_find_device( + &cxl_bus_type, NULL, pdev, match_memdev_by_parent); + if (!mem_dev) + return; + + cxlmd = to_cxl_memdev(mem_dev); if (data->severity == AER_CORRECTABLE) - cxl_cper_trace_corr_prot_err(pdev, data->ras_cap); + cxl_cper_trace_corr_prot_err(cxlmd, data->ras_cap); else - cxl_cper_trace_uncorr_prot_err(pdev, data->ras_cap); + cxl_cper_trace_uncorr_prot_err(cxlmd, data->ras_cap); }
static void cxl_cper_prot_err_work_fn(struct work_struct *work)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier fourier.thomas@gmail.com
[ Upstream commit 85d6fbc47c3087c5d048e6734926b0c36af34fe9 ]
dma_map_XXX() can fail and should be tested for errors with dma_mapping_error().
Fixes: a63e78eb2b0f ("scsi: fnic: Add support for fabric based solicited requests and responses") Signed-off-by: Thomas Fourier fourier.thomas@gmail.com Link: https://lore.kernel.org/r/20250618065715.14740-2-fourier.thomas@gmail.com Reviewed-by: Karan Tilak Kumar kartilak@cisco.com Reviewed-by: John Menghini jmeneghi@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/fnic/fnic_fcs.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index 1e8cd64f9a5c5..103ab6f1f7cd1 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -636,6 +636,8 @@ static int fnic_send_frame(struct fnic *fnic, void *frame, int frame_len) unsigned long flags;
pa = dma_map_single(&fnic->pdev->dev, frame, frame_len, DMA_TO_DEVICE); + if (dma_mapping_error(&fnic->pdev->dev, pa)) + return -ENOMEM;
if ((fnic_fc_trace_set_data(fnic->fnic_num, FNIC_FC_SEND | 0x80, (char *) frame,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet edumazet@google.com
[ Upstream commit b993ea46b3b601915ceaaf3c802adf11e7d6bac6 ]
Blamed commit missed that vcc_destroy_socket() calls clip_push() with a NULL skb.
If clip_devs is NULL, clip_push() then crashes when reading skb->truesize.
Fixes: 93a2014afbac ("atm: fix a UAF in lec_arp_clear_vccs()") Reported-by: syzbot+1316233c4c6803382a8b@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/68556f59.a00a0220.137b3.004e.GAE@google.com/T... Signed-off-by: Eric Dumazet edumazet@google.com Cc: Cong Wang xiyou.wangcong@gmail.com Cc: Gengming Liu l.dmxcsnsbh@gmail.com Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: David S. Miller davem@davemloft.net Signed-off-by: Sasha Levin sashal@kernel.org --- net/atm/clip.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/net/atm/clip.c b/net/atm/clip.c index 61b5b700817de..b234dc3bcb0d4 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c @@ -193,12 +193,6 @@ static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
pr_debug("\n");
- if (!clip_devs) { - atm_return(vcc, skb->truesize); - kfree_skb(skb); - return; - } - if (!skb) { pr_debug("removing VCC %p\n", clip_vcc); if (clip_vcc->entry) @@ -208,6 +202,11 @@ static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb) return; } atm_return(vcc, skb->truesize); + if (!clip_devs) { + kfree_skb(skb); + return; + } + skb->dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : clip_devs; /* clip_vcc->entry == NULL if we don't have an IP address yet */ if (!skb->dev) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vijendar Mukunda Vijendar.Mukunda@amd.com
[ Upstream commit dc6458ed95e40146699f9c523e34cb13ff127170 ]
During the hibernate entry sequence, ACP registers will be reset to default values and acp ip will be completely powered off including acp SoundWire pads. During resume sequence, if acp SoundWire pad keeper enable register is not restored along with pad pulldown control register value, then SoundWire manager links won't be powered on correctly results in peripheral register access failures and completely audio function is broken.
Add code to store the acp SoundWire pad keeper enable register and acp pad pulldown ctrl register values before entering into suspend state and restore the register values during resume sequence based on condition check for acp SoundWire pad keeper enable register for ACP6.3, ACP7.0 & ACP7.1 platforms.
Fixes: 491628388005 ("ASoC: amd: ps: add callback functions for acp pci driver pm ops") Signed-off-by: Vijendar Mukunda Vijendar.Mukunda@amd.com Link: https://patch.msgid.link/20250623084630.3100279-1-Vijendar.Mukunda@amd.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/amd/ps/acp63.h | 4 ++++ sound/soc/amd/ps/ps-common.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+)
diff --git a/sound/soc/amd/ps/acp63.h b/sound/soc/amd/ps/acp63.h index 85feae45c44c5..d7c994e26e4df 100644 --- a/sound/soc/amd/ps/acp63.h +++ b/sound/soc/amd/ps/acp63.h @@ -334,6 +334,8 @@ struct acp_hw_ops { * @addr: pci ioremap address * @reg_range: ACP reigister range * @acp_rev: ACP PCI revision id + * @acp_sw_pad_keeper_en: store acp SoundWire pad keeper enable register value + * @acp_pad_pulldown_ctrl: store acp pad pulldown control register value * @acp63_sdw0-dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire * manager-SW0 instance * @acp63_sdw_dma_intr_stat: DMA interrupt status array for ACP6.3 platform SoundWire @@ -367,6 +369,8 @@ struct acp63_dev_data { u32 addr; u32 reg_range; u32 acp_rev; + u32 acp_sw_pad_keeper_en; + u32 acp_pad_pulldown_ctrl; u16 acp63_sdw0_dma_intr_stat[ACP63_SDW0_DMA_MAX_STREAMS]; u16 acp63_sdw1_dma_intr_stat[ACP63_SDW1_DMA_MAX_STREAMS]; u16 acp70_sdw0_dma_intr_stat[ACP70_SDW0_DMA_MAX_STREAMS]; diff --git a/sound/soc/amd/ps/ps-common.c b/sound/soc/amd/ps/ps-common.c index 1c89fb5fe1da5..7b4966b75dc67 100644 --- a/sound/soc/amd/ps/ps-common.c +++ b/sound/soc/amd/ps/ps-common.c @@ -160,6 +160,8 @@ static int __maybe_unused snd_acp63_suspend(struct device *dev)
adata = dev_get_drvdata(dev); if (adata->is_sdw_dev) { + adata->acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); + adata->acp_pad_pulldown_ctrl = readl(adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); adata->sdw_en_stat = check_acp_sdw_enable_status(adata); if (adata->sdw_en_stat) { writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); @@ -197,6 +199,7 @@ static int __maybe_unused snd_acp63_runtime_resume(struct device *dev) static int __maybe_unused snd_acp63_resume(struct device *dev) { struct acp63_dev_data *adata; + u32 acp_sw_pad_keeper_en; int ret;
adata = dev_get_drvdata(dev); @@ -209,6 +212,12 @@ static int __maybe_unused snd_acp63_resume(struct device *dev) if (ret) dev_err(dev, "ACP init failed\n");
+ acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); + dev_dbg(dev, "ACP_SW0_PAD_KEEPER_EN:0x%x\n", acp_sw_pad_keeper_en); + if (!acp_sw_pad_keeper_en) { + writel(adata->acp_sw_pad_keeper_en, adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); + writel(adata->acp_pad_pulldown_ctrl, adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); + } return ret; }
@@ -408,6 +417,8 @@ static int __maybe_unused snd_acp70_suspend(struct device *dev)
adata = dev_get_drvdata(dev); if (adata->is_sdw_dev) { + adata->acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); + adata->acp_pad_pulldown_ctrl = readl(adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); adata->sdw_en_stat = check_acp_sdw_enable_status(adata); if (adata->sdw_en_stat) { writel(1, adata->acp63_base + ACP_ZSC_DSP_CTRL); @@ -445,6 +456,7 @@ static int __maybe_unused snd_acp70_runtime_resume(struct device *dev) static int __maybe_unused snd_acp70_resume(struct device *dev) { struct acp63_dev_data *adata; + u32 acp_sw_pad_keeper_en; int ret;
adata = dev_get_drvdata(dev); @@ -459,6 +471,12 @@ static int __maybe_unused snd_acp70_resume(struct device *dev) if (ret) dev_err(dev, "ACP init failed\n");
+ acp_sw_pad_keeper_en = readl(adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); + dev_dbg(dev, "ACP_SW0_PAD_KEEPER_EN:0x%x\n", acp_sw_pad_keeper_en); + if (!acp_sw_pad_keeper_en) { + writel(adata->acp_sw_pad_keeper_en, adata->acp63_base + ACP_SW0_PAD_KEEPER_EN); + writel(adata->acp_pad_pulldown_ctrl, adata->acp63_base + ACP_PAD_PULLDOWN_CTRL); + } return ret; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima kuniyu@google.com
[ Upstream commit 1d6123102e9fbedc8d25bf4731da6d513173e49e ]
syzbot reported use-after-free in vhci_flush() without repro. [0]
From the splat, a thread close()d a vhci file descriptor while
its device was being used by iotcl() on another thread.
Once the last fd refcnt is released, vhci_release() calls hci_unregister_dev(), hci_free_dev(), and kfree() for struct vhci_data, which is set to hci_dev->dev->driver_data.
The problem is that there is no synchronisation after unlinking hdev from hci_dev_list in hci_unregister_dev(). There might be another thread still accessing the hdev which was fetched before the unlink operation.
We can use SRCU for such synchronisation.
Let's run hci_dev_reset() under SRCU and wait for its completion in hci_unregister_dev().
Another option would be to restore hci_dev->destruct(), which was removed in commit 587ae086f6e4 ("Bluetooth: Remove unused hci-destruct cb"). However, this would not be a good solution, as we should not run hci_unregister_dev() while there are in-flight ioctl() requests, which could lead to another data-race KCSAN splat.
Note that other drivers seem to have the same problem, for exmaple, virtbt_remove().
[0]: BUG: KASAN: slab-use-after-free in skb_queue_empty_lockless include/linux/skbuff.h:1891 [inline] BUG: KASAN: slab-use-after-free in skb_queue_purge_reason+0x99/0x360 net/core/skbuff.c:3937 Read of size 8 at addr ffff88807cb8d858 by task syz.1.219/6718
CPU: 1 UID: 0 PID: 6718 Comm: syz.1.219 Not tainted 6.16.0-rc1-syzkaller-00196-g08207f42d3ff #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 Call Trace: <TASK> dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 print_address_description mm/kasan/report.c:408 [inline] print_report+0xd2/0x2b0 mm/kasan/report.c:521 kasan_report+0x118/0x150 mm/kasan/report.c:634 skb_queue_empty_lockless include/linux/skbuff.h:1891 [inline] skb_queue_purge_reason+0x99/0x360 net/core/skbuff.c:3937 skb_queue_purge include/linux/skbuff.h:3368 [inline] vhci_flush+0x44/0x50 drivers/bluetooth/hci_vhci.c:69 hci_dev_do_reset net/bluetooth/hci_core.c:552 [inline] hci_dev_reset+0x420/0x5c0 net/bluetooth/hci_core.c:592 sock_do_ioctl+0xd9/0x300 net/socket.c:1190 sock_ioctl+0x576/0x790 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl+0xf9/0x170 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fcf5b98e929 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007fcf5c7b9038 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007fcf5bbb6160 RCX: 00007fcf5b98e929 RDX: 0000000000000000 RSI: 00000000400448cb RDI: 0000000000000009 RBP: 00007fcf5ba10b39 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 0000000000000000 R14: 00007fcf5bbb6160 R15: 00007ffd6353d528 </TASK>
Allocated by task 6535: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 poison_kmalloc_redzone mm/kasan/common.c:377 [inline] __kasan_kmalloc+0x93/0xb0 mm/kasan/common.c:394 kasan_kmalloc include/linux/kasan.h:260 [inline] __kmalloc_cache_noprof+0x230/0x3d0 mm/slub.c:4359 kmalloc_noprof include/linux/slab.h:905 [inline] kzalloc_noprof include/linux/slab.h:1039 [inline] vhci_open+0x57/0x360 drivers/bluetooth/hci_vhci.c:635 misc_open+0x2bc/0x330 drivers/char/misc.c:161 chrdev_open+0x4c9/0x5e0 fs/char_dev.c:414 do_dentry_open+0xdf0/0x1970 fs/open.c:964 vfs_open+0x3b/0x340 fs/open.c:1094 do_open fs/namei.c:3887 [inline] path_openat+0x2ee5/0x3830 fs/namei.c:4046 do_filp_open+0x1fa/0x410 fs/namei.c:4073 do_sys_openat2+0x121/0x1c0 fs/open.c:1437 do_sys_open fs/open.c:1452 [inline] __do_sys_openat fs/open.c:1468 [inline] __se_sys_openat fs/open.c:1463 [inline] __x64_sys_openat+0x138/0x170 fs/open.c:1463 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
Freed by task 6535: kasan_save_stack mm/kasan/common.c:47 [inline] kasan_save_track+0x3e/0x80 mm/kasan/common.c:68 kasan_save_free_info+0x46/0x50 mm/kasan/generic.c:576 poison_slab_object mm/kasan/common.c:247 [inline] __kasan_slab_free+0x62/0x70 mm/kasan/common.c:264 kasan_slab_free include/linux/kasan.h:233 [inline] slab_free_hook mm/slub.c:2381 [inline] slab_free mm/slub.c:4643 [inline] kfree+0x18e/0x440 mm/slub.c:4842 vhci_release+0xbc/0xd0 drivers/bluetooth/hci_vhci.c:671 __fput+0x44c/0xa70 fs/file_table.c:465 task_work_run+0x1d1/0x260 kernel/task_work.c:227 exit_task_work include/linux/task_work.h:40 [inline] do_exit+0x6ad/0x22e0 kernel/exit.c:955 do_group_exit+0x21c/0x2d0 kernel/exit.c:1104 __do_sys_exit_group kernel/exit.c:1115 [inline] __se_sys_exit_group kernel/exit.c:1113 [inline] __x64_sys_exit_group+0x3f/0x40 kernel/exit.c:1113 x64_sys_call+0x21ba/0x21c0 arch/x86/include/generated/asm/syscalls_64.h:232 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0x3b0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
The buggy address belongs to the object at ffff88807cb8d800 which belongs to the cache kmalloc-1k of size 1024 The buggy address is located 88 bytes inside of freed 1024-byte region [ffff88807cb8d800, ffff88807cb8dc00)
Fixes: bf18c7118cf8 ("Bluetooth: vhci: Free driver_data on file release") Reported-by: syzbot+2faa4825e556199361f9@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f62d64848fc4c7c30cd6 Signed-off-by: Kuniyuki Iwashima kuniyu@google.com Acked-by: Paul Menzel pmenzel@molgen.mpg.de Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- include/net/bluetooth/hci_core.h | 2 ++ net/bluetooth/hci_core.c | 34 ++++++++++++++++++++++++++++---- 2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index d15316bffd70b..6e9d2a856a6b0 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -29,6 +29,7 @@ #include <linux/idr.h> #include <linux/leds.h> #include <linux/rculist.h> +#include <linux/srcu.h>
#include <net/bluetooth/hci.h> #include <net/bluetooth/hci_sync.h> @@ -345,6 +346,7 @@ struct adv_monitor {
struct hci_dev { struct list_head list; + struct srcu_struct srcu; struct mutex lock;
struct ida unset_handle_ida; diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index af30a420bab75..abff4690cb88f 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -64,7 +64,7 @@ static DEFINE_IDA(hci_index_ida);
/* Get HCI device by index. * Device is held on return. */ -struct hci_dev *hci_dev_get(int index) +static struct hci_dev *__hci_dev_get(int index, int *srcu_index) { struct hci_dev *hdev = NULL, *d;
@@ -77,6 +77,8 @@ struct hci_dev *hci_dev_get(int index) list_for_each_entry(d, &hci_dev_list, list) { if (d->id == index) { hdev = hci_dev_hold(d); + if (srcu_index) + *srcu_index = srcu_read_lock(&d->srcu); break; } } @@ -84,6 +86,22 @@ struct hci_dev *hci_dev_get(int index) return hdev; }
+struct hci_dev *hci_dev_get(int index) +{ + return __hci_dev_get(index, NULL); +} + +static struct hci_dev *hci_dev_get_srcu(int index, int *srcu_index) +{ + return __hci_dev_get(index, srcu_index); +} + +static void hci_dev_put_srcu(struct hci_dev *hdev, int srcu_index) +{ + srcu_read_unlock(&hdev->srcu, srcu_index); + hci_dev_put(hdev); +} + /* ---- Inquiry support ---- */
bool hci_discovery_active(struct hci_dev *hdev) @@ -568,9 +586,9 @@ static int hci_dev_do_reset(struct hci_dev *hdev) int hci_dev_reset(__u16 dev) { struct hci_dev *hdev; - int err; + int err, srcu_index;
- hdev = hci_dev_get(dev); + hdev = hci_dev_get_srcu(dev, &srcu_index); if (!hdev) return -ENODEV;
@@ -592,7 +610,7 @@ int hci_dev_reset(__u16 dev) err = hci_dev_do_reset(hdev);
done: - hci_dev_put(hdev); + hci_dev_put_srcu(hdev, srcu_index); return err; }
@@ -2419,6 +2437,11 @@ struct hci_dev *hci_alloc_dev_priv(int sizeof_priv) if (!hdev) return NULL;
+ if (init_srcu_struct(&hdev->srcu)) { + kfree(hdev); + return NULL; + } + hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1); hdev->esco_type = (ESCO_HV1); hdev->link_mode = (HCI_LM_ACCEPT); @@ -2664,6 +2687,9 @@ void hci_unregister_dev(struct hci_dev *hdev) list_del(&hdev->list); write_unlock(&hci_dev_list_lock);
+ synchronize_srcu(&hdev->srcu); + cleanup_srcu_struct(&hdev->srcu); + disable_work_sync(&hdev->rx_work); disable_work_sync(&hdev->cmd_work); disable_work_sync(&hdev->tx_work);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youngjun Lee yjjuny.lee@samsung.com
[ Upstream commit fb4e2a6e8f28a3c0ad382e363aeb9cd822007b8a ]
In snd_usb_get_audioformat_uac3(), the length value returned from snd_usb_ctl_msg() is used directly for memory allocation without validation. This length is controlled by the USB device.
The allocated buffer is cast to a uac3_cluster_header_descriptor and its fields are accessed without verifying that the buffer is large enough. If the device returns a smaller than expected length, this leads to an out-of-bounds read.
Add a length check to ensure the buffer is large enough for uac3_cluster_header_descriptor.
Signed-off-by: Youngjun Lee yjjuny.lee@samsung.com Fixes: 9a2fe9b801f5 ("ALSA: usb: initial USB Audio Device Class 3.0 support") Link: https://patch.msgid.link/20250623-uac3-oob-fix-v1-1-527303eaf40a@samsung.com Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/usb/stream.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/usb/stream.c b/sound/usb/stream.c index c1ea8844a46fc..aa91d63749f2c 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -987,6 +987,8 @@ snd_usb_get_audioformat_uac3(struct snd_usb_audio *chip, * and request Cluster Descriptor */ wLength = le16_to_cpu(hc_header.wLength); + if (wLength < sizeof(cluster)) + return NULL; cluster = kzalloc(wLength, GFP_KERNEL); if (!cluster) return ERR_PTR(-ENOMEM);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit ce7df19686530920f2f6b636e71ce5eb1d9303ef ]
If we are propagating across the userns boundary, we need to lock the mounts added there. However, in case when something has already been mounted there and we end up sliding a new tree under that, the stuff that had been there before should not get locked.
IOW, lock_mnt_tree() should be called before we reparent the preexisting tree on top of what we are adding.
Fixes: 3bd045cc9c4b ("separate copying and locking mount tree on cross-userns copies") Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/namespace.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c index d6ac7e533b021..24b087ba88159 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2765,14 +2765,14 @@ static int attach_recursive_mnt(struct mount *source_mnt, hlist_for_each_entry_safe(child, n, &tree_list, mnt_hash) { struct mount *q; hlist_del_init(&child->mnt_hash); - q = __lookup_mnt(&child->mnt_parent->mnt, - child->mnt_mountpoint); - if (q) - mnt_change_mountpoint(child, smp, q); /* Notice when we are propagating across user namespaces */ if (child->mnt_parent->mnt_ns->user_ns != user_ns) lock_mnt_tree(child); child->mnt.mnt_flags &= ~MNT_LOCKED; + q = __lookup_mnt(&child->mnt_parent->mnt, + child->mnt_mountpoint); + if (q) + mnt_change_mountpoint(child, smp, q); commit_tree(child); } put_mountpoint(smp);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Chen chenyuan@kylinos.cn
[ Upstream commit aa485e8789d56a4573f7c8d000a182b749eaa64d ]
When btf_dump__new() fails to allocate memory for the internal hashmap (btf_dump->type_names), it returns an error code. However, the cleanup function btf_dump__free() does not check if btf_dump->type_names is NULL before attempting to free it. This leads to a null pointer dereference when btf_dump__free() is called on a btf_dump object.
Fixes: 351131b51c7a ("libbpf: add btf_dump API for BTF-to-C conversion") Signed-off-by: Yuan Chen chenyuan@kylinos.cn Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20250618011933.11423-1-chenyuan_fl@163.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/btf_dump.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c index 460c3e57fadb6..0381f209920a6 100644 --- a/tools/lib/bpf/btf_dump.c +++ b/tools/lib/bpf/btf_dump.c @@ -226,6 +226,9 @@ static void btf_dump_free_names(struct hashmap *map) size_t bkt; struct hashmap_entry *cur;
+ if (!map) + return; + hashmap__for_each_entry(map, cur, bkt) free((void *)cur->pkey);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao leitao@debian.org
[ Upstream commit f5990207026987a353d5a95204c4d9cb725637fd ]
commit f1fce08e63fe ("netpoll: Eliminate redundant assignment") removed the initialization of the UDP checksum, which was wrong and broke netpoll IPv6 transmission due to bad checksumming.
udph->check needs to be set before calling csum_ipv6_magic().
Fixes: f1fce08e63fe ("netpoll: Eliminate redundant assignment") Signed-off-by: Breno Leitao leitao@debian.org Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/20250620-netpoll_fix-v1-1-f9f0b82bc059@debian.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/netpoll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index 4ddb7490df4b8..6ad84d4a2b464 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c @@ -432,6 +432,7 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len) udph->dest = htons(np->remote_port); udph->len = htons(udp_len);
+ udph->check = 0; if (np->ipv6) { udph->check = csum_ipv6_magic(&np->local_ip.in6, &np->remote_ip.in6, @@ -460,7 +461,6 @@ int netpoll_send_udp(struct netpoll *np, const char *msg, int len) skb_reset_mac_header(skb); skb->protocol = eth->h_proto = htons(ETH_P_IPV6); } else { - udph->check = 0; udph->check = csum_tcpudp_magic(np->local_ip.ip, np->remote_ip.ip, udp_len, IPPROTO_UDP,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier fourier.thomas@gmail.com
[ Upstream commit d5e3241c5a386a2425823c8c7afb77a465bd040f ]
Change error values of `ionic_tx_map_single()` and `ionic_tx_map_frag()` from 0 to `DMA_MAPPING_ERROR` to prevent collision with 0 as a valid address.
This also fixes the use of `dma_mapping_error()` to test against 0 in `ionic_xdp_post_frame()`
Fixes: 0f3154e6bcb3 ("ionic: Add Tx and Rx handling") Fixes: 56e41ee12d2d ("ionic: better dma-map error handling") Fixes: ac8813c0ab7d ("ionic: convert Rx queue buffers to use page_pool") Signed-off-by: Thomas Fourier fourier.thomas@gmail.com Reviewed-by: Brett Creeley brett.creeley@amd.com Link: https://patch.msgid.link/20250619094538.283723-2-fourier.thomas@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c index 2ac59564ded18..d10b58ebf6034 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c @@ -321,7 +321,7 @@ static int ionic_xdp_post_frame(struct ionic_queue *q, struct xdp_frame *frame, len, DMA_TO_DEVICE); } else /* XDP_REDIRECT */ { dma_addr = ionic_tx_map_single(q, frame->data, len); - if (!dma_addr) + if (dma_addr == DMA_MAPPING_ERROR) return -EIO; }
@@ -357,7 +357,7 @@ static int ionic_xdp_post_frame(struct ionic_queue *q, struct xdp_frame *frame, } else { dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag)); - if (dma_mapping_error(q->dev, dma_addr)) { + if (dma_addr == DMA_MAPPING_ERROR) { ionic_tx_desc_unmap_bufs(q, desc_info); return -EIO; } @@ -1083,7 +1083,7 @@ static dma_addr_t ionic_tx_map_single(struct ionic_queue *q, net_warn_ratelimited("%s: DMA single map failed on %s!\n", dev_name(dev), q->name); q_to_tx_stats(q)->dma_map_err++; - return 0; + return DMA_MAPPING_ERROR; } return dma_addr; } @@ -1100,7 +1100,7 @@ static dma_addr_t ionic_tx_map_frag(struct ionic_queue *q, net_warn_ratelimited("%s: DMA frag map failed on %s!\n", dev_name(dev), q->name); q_to_tx_stats(q)->dma_map_err++; - return 0; + return DMA_MAPPING_ERROR; } return dma_addr; } @@ -1116,7 +1116,7 @@ static int ionic_tx_map_skb(struct ionic_queue *q, struct sk_buff *skb, int frag_idx;
dma_addr = ionic_tx_map_single(q, skb->data, skb_headlen(skb)); - if (!dma_addr) + if (dma_addr == DMA_MAPPING_ERROR) return -EIO; buf_info->dma_addr = dma_addr; buf_info->len = skb_headlen(skb); @@ -1126,7 +1126,7 @@ static int ionic_tx_map_skb(struct ionic_queue *q, struct sk_buff *skb, nfrags = skb_shinfo(skb)->nr_frags; for (frag_idx = 0; frag_idx < nfrags; frag_idx++, frag++) { dma_addr = ionic_tx_map_frag(q, frag, 0, skb_frag_size(frag)); - if (!dma_addr) + if (dma_addr == DMA_MAPPING_ERROR) goto dma_fail; buf_info->dma_addr = dma_addr; buf_info->len = skb_frag_size(frag);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel idosch@nvidia.com
[ Upstream commit 7544f3f5b0b58c396f374d060898b5939da31709 ]
The bridge maintains a global list of ports behind which a multicast router resides. The list is consulted during forwarding to ensure multicast packets are forwarded to these ports even if the ports are not member in the matching MDB entry.
When per-VLAN multicast snooping is enabled, the per-port multicast context is disabled on each port and the port is removed from the global router port list:
# ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 # ip link add name dummy1 up master br1 type dummy # ip link set dev dummy1 type bridge_slave mcast_router 2 $ bridge -d mdb show | grep router router ports on br1: dummy1 # ip link set dev br1 type bridge mcast_vlan_snooping 1 $ bridge -d mdb show | grep router
However, the port can be re-added to the global list even when per-VLAN multicast snooping is enabled:
# ip link set dev dummy1 type bridge_slave mcast_router 0 # ip link set dev dummy1 type bridge_slave mcast_router 2 $ bridge -d mdb show | grep router router ports on br1: dummy1
Since commit 4b30ae9adb04 ("net: bridge: mcast: re-implement br_multicast_{enable, disable}_port functions"), when per-VLAN multicast snooping is enabled, multicast disablement on a port will disable the per-{port, VLAN} multicast contexts and not the per-port one. As a result, a port will remain in the global router port list even after it is deleted. This will lead to a use-after-free [1] when the list is traversed (when adding a new port to the list, for example):
# ip link del dev dummy1 # ip link add name dummy2 up master br1 type dummy # ip link set dev dummy2 type bridge_slave mcast_router 2
Similarly, stale entries can also be found in the per-VLAN router port list. When per-VLAN multicast snooping is disabled, the per-{port, VLAN} contexts are disabled on each port and the port is removed from the per-VLAN router port list:
# ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1 # ip link add name dummy1 up master br1 type dummy # bridge vlan add vid 2 dev dummy1 # bridge vlan global set vid 2 dev br1 mcast_snooping 1 # bridge vlan set vid 2 dev dummy1 mcast_router 2 $ bridge vlan global show dev br1 vid 2 | grep router router ports: dummy1 # ip link set dev br1 type bridge mcast_vlan_snooping 0 $ bridge vlan global show dev br1 vid 2 | grep router
However, the port can be re-added to the per-VLAN list even when per-VLAN multicast snooping is disabled:
# bridge vlan set vid 2 dev dummy1 mcast_router 0 # bridge vlan set vid 2 dev dummy1 mcast_router 2 $ bridge vlan global show dev br1 vid 2 | grep router router ports: dummy1
When the VLAN is deleted from the port, the per-{port, VLAN} multicast context will not be disabled since multicast snooping is not enabled on the VLAN. As a result, the port will remain in the per-VLAN router port list even after it is no longer member in the VLAN. This will lead to a use-after-free [2] when the list is traversed (when adding a new port to the list, for example):
# ip link add name dummy2 up master br1 type dummy # bridge vlan add vid 2 dev dummy2 # bridge vlan del vid 2 dev dummy1 # bridge vlan set vid 2 dev dummy2 mcast_router 2
Fix these issues by removing the port from the relevant (global or per-VLAN) router port list in br_multicast_port_ctx_deinit(). The function is invoked during port deletion with the per-port multicast context and during VLAN deletion with the per-{port, VLAN} multicast context.
Note that deleting the multicast router timer is not enough as it only takes care of the temporary multicast router states (1 or 3) and not the permanent one (2).
[1] BUG: KASAN: slab-out-of-bounds in br_multicast_add_router.part.0+0x3f1/0x560 Write of size 8 at addr ffff888004a67328 by task ip/384 [...] Call Trace: <TASK> dump_stack_lvl+0x6f/0xa0 print_address_description.constprop.0+0x6f/0x350 print_report+0x108/0x205 kasan_report+0xdf/0x110 br_multicast_add_router.part.0+0x3f1/0x560 br_multicast_set_port_router+0x74e/0xac0 br_setport+0xa55/0x1870 br_port_slave_changelink+0x95/0x120 __rtnl_newlink+0x5e8/0xa40 rtnl_newlink+0x627/0xb00 rtnetlink_rcv_msg+0x6fb/0xb70 netlink_rcv_skb+0x11f/0x350 netlink_unicast+0x426/0x710 netlink_sendmsg+0x75a/0xc20 __sock_sendmsg+0xc1/0x150 ____sys_sendmsg+0x5aa/0x7b0 ___sys_sendmsg+0xfc/0x180 __sys_sendmsg+0x124/0x1c0 do_syscall_64+0xbb/0x360 entry_SYSCALL_64_after_hwframe+0x4b/0x53
[2] BUG: KASAN: slab-use-after-free in br_multicast_add_router.part.0+0x378/0x560 Read of size 8 at addr ffff888009f00840 by task bridge/391 [...] Call Trace: <TASK> dump_stack_lvl+0x6f/0xa0 print_address_description.constprop.0+0x6f/0x350 print_report+0x108/0x205 kasan_report+0xdf/0x110 br_multicast_add_router.part.0+0x378/0x560 br_multicast_set_port_router+0x6f9/0xac0 br_vlan_process_options+0x8b6/0x1430 br_vlan_rtm_process_one+0x605/0xa30 br_vlan_rtm_process+0x396/0x4c0 rtnetlink_rcv_msg+0x2f7/0xb70 netlink_rcv_skb+0x11f/0x350 netlink_unicast+0x426/0x710 netlink_sendmsg+0x75a/0xc20 __sock_sendmsg+0xc1/0x150 ____sys_sendmsg+0x5aa/0x7b0 ___sys_sendmsg+0xfc/0x180 __sys_sendmsg+0x124/0x1c0 do_syscall_64+0xbb/0x360 entry_SYSCALL_64_after_hwframe+0x4b/0x53
Fixes: 2796d846d74a ("net: bridge: vlan: convert mcast router global option to per-vlan entry") Fixes: 4b30ae9adb04 ("net: bridge: mcast: re-implement br_multicast_{enable, disable}_port functions") Reported-by: syzbot+7bfa4b72c6a5da128d32@syzkaller.appspotmail.com Closes: https://lore.kernel.org/all/684c18bd.a00a0220.279073.000b.GAE@google.com/T/ Signed-off-by: Ido Schimmel idosch@nvidia.com Link: https://patch.msgid.link/20250619182228.1656906-1-idosch@nvidia.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/bridge/br_multicast.c | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 7e0b2362b9ee5..d35a409b5e4aa 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -2014,10 +2014,19 @@ void br_multicast_port_ctx_init(struct net_bridge_port *port,
void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) { + struct net_bridge *br = pmctx->port->br; + bool del = false; + #if IS_ENABLED(CONFIG_IPV6) timer_delete_sync(&pmctx->ip6_mc_router_timer); #endif timer_delete_sync(&pmctx->ip4_mc_router_timer); + + spin_lock_bh(&br->multicast_lock); + del |= br_ip6_multicast_rport_del(pmctx); + del |= br_ip4_multicast_rport_del(pmctx); + br_multicast_rport_del_notify(pmctx, del); + spin_unlock_bh(&br->multicast_lock); }
int br_multicast_add_port(struct net_bridge_port *port)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lachlan Hodges lachlan.hodges@morsemicro.com
[ Upstream commit 7a3750ff0f2e8fee338a9c168f429f6c37f0e820 ]
As we are converting from TU to usecs, a beacon interval of 100*1024 usecs will lead to integer wrapping. To fix change to use a u32.
Fixes: 057d5f4ba1e4 ("mac80211: sync dtim_count to TSF") Signed-off-by: Lachlan Hodges lachlan.hodges@morsemicro.com Link: https://patch.msgid.link/20250621123209.511796-1-lachlan.hodges@morsemicro.c... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index dec6e16b8c7d2..82256eddd16bd 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -3899,7 +3899,7 @@ void ieee80211_recalc_dtim(struct ieee80211_local *local, { u64 tsf = drv_get_tsf(local, sdata); u64 dtim_count = 0; - u16 beacon_int = sdata->vif.bss_conf.beacon_int * 1024; + u32 beacon_int = sdata->vif.bss_conf.beacon_int * 1024; u8 dtim_period = sdata->vif.bss_conf.dtim_period; struct ps_data *ps; u8 bcns_from_dtim;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima kuniyu@google.com
[ Upstream commit 2a5a4841846b079b5fca5752fe94e59346fbda40 ]
Christian Brauner reported that even after MSG_OOB data is consumed, calling close() on the receiver socket causes the peer's recv() to return -ECONNRESET:
1. send() and recv() an OOB data.
>>> from socket import * >>> s1, s2 = socketpair(AF_UNIX, SOCK_STREAM) >>> s1.send(b'x', MSG_OOB) 1 >>> s2.recv(1, MSG_OOB) b'x'
2. close() for s2 sets ECONNRESET to s1->sk_err even though s2 consumed the OOB data
>>> s2.close() >>> s1.recv(10, MSG_DONTWAIT) ... ConnectionResetError: [Errno 104] Connection reset by peer
Even after being consumed, the skb holding the OOB 1-byte data stays in the recv queue to mark the OOB boundary and break recv() at that point.
This must be considered while close()ing a socket.
Let's skip the leading consumed OOB skb while checking the -ECONNRESET condition in unix_release_sock().
Fixes: 314001f0bf92 ("af_unix: Add OOB support") Reported-by: Christian Brauner brauner@kernel.org Closes: https://lore.kernel.org/netdev/20250529-sinkt-abfeuern-e7b08200c6b0@brauner/ Signed-off-by: Kuniyuki Iwashima kuniyu@google.com Acked-by: Christian Brauner brauner@kernel.org Link: https://patch.msgid.link/20250619041457.1132791-4-kuni1840@gmail.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/unix/af_unix.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index af003831f4c67..52f2812d2fa5b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -654,6 +654,11 @@ static void unix_sock_destructor(struct sock *sk) #endif }
+static unsigned int unix_skb_len(const struct sk_buff *skb) +{ + return skb->len - UNIXCB(skb).consumed; +} + static void unix_release_sock(struct sock *sk, int embrion) { struct unix_sock *u = unix_sk(sk); @@ -688,10 +693,16 @@ static void unix_release_sock(struct sock *sk, int embrion)
if (skpair != NULL) { if (sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) { + struct sk_buff *skb = skb_peek(&sk->sk_receive_queue); + +#if IS_ENABLED(CONFIG_AF_UNIX_OOB) + if (skb && !unix_skb_len(skb)) + skb = skb_peek_next(skb, &sk->sk_receive_queue); +#endif unix_state_lock(skpair); /* No more writes */ WRITE_ONCE(skpair->sk_shutdown, SHUTDOWN_MASK); - if (!skb_queue_empty_lockless(&sk->sk_receive_queue) || embrion) + if (skb || embrion) WRITE_ONCE(skpair->sk_err, ECONNRESET); unix_state_unlock(skpair); skpair->sk_state_change(skpair); @@ -2578,11 +2589,6 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, return timeo; }
-static unsigned int unix_skb_len(const struct sk_buff *skb) -{ - return skb->len - UNIXCB(skb).consumed; -} - struct unix_stream_read_state { int (*recv_actor)(struct sk_buff *, int, int, struct unix_stream_read_state *);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muna Sinada muna.sinada@oss.qualcomm.com
[ Upstream commit f61c7b3d442bef91dd432d468d08f72eadcc3209 ]
Currently before iterating through valid links we are utilizing open-coding when checking if vif valid_links is a non-zero value.
Add new macro, for_each_link_data(), which iterates through link_id and checks if it is set on vif valid_links. If it is a valid link then access link data for that link id.
Signed-off-by: Muna Sinada muna.sinada@oss.qualcomm.com Link: https://patch.msgid.link/20250325213125.1509362-2-muna.sinada@oss.qualcomm.c... Signed-off-by: Johannes Berg johannes.berg@intel.com Stable-dep-of: d87c3ca0f8f1 ("wifi: mac80211: finish link init before RCU publish") Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/ieee80211_i.h | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index fb05f3cd37ec4..c956072e0d77e 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -1226,6 +1226,15 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) if ((_link = wiphy_dereference((_local)->hw.wiphy, \ ___sdata->link[___link_id])))
+#define for_each_link_data(sdata, __link) \ + struct ieee80211_sub_if_data *__sdata = sdata; \ + for (int __link_id = 0; \ + __link_id < ARRAY_SIZE((__sdata)->link); __link_id++) \ + if ((!(__sdata)->vif.valid_links || \ + (__sdata)->vif.valid_links & BIT(__link_id)) && \ + ((__link) = sdata_dereference((__sdata)->link[__link_id], \ + (__sdata)))) + static inline int ieee80211_get_mbssid_beacon_len(struct cfg80211_mbssid_elems *elems, struct cfg80211_rnr_elems *rnr_elems,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Muna Sinada muna.sinada@oss.qualcomm.com
[ Upstream commit 90233b0ad215efc9ea56a7c0b09021bcd4eea4ac ]
Currently, MLD links for an AP_VLAN interface type is not fully supported.
Add allocation of separate links for each VLAN interface and copy chanctx and chandef of AP bss to VLAN where necessary. Separate links are created because for Dynamic VLAN each link will have its own default_multicast_key.
Signed-off-by: Muna Sinada muna.sinada@oss.qualcomm.com Link: https://patch.msgid.link/20250325213125.1509362-3-muna.sinada@oss.qualcomm.c... Signed-off-by: Johannes Berg johannes.berg@intel.com Stable-dep-of: d87c3ca0f8f1 ("wifi: mac80211: finish link init before RCU publish") Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/chan.c | 3 ++ net/mac80211/ieee80211_i.h | 3 ++ net/mac80211/iface.c | 12 ++++- net/mac80211/link.c | 90 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 103 insertions(+), 5 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index c3bfac58151f6..3aaf5abf1acc1 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -2131,6 +2131,9 @@ void ieee80211_link_release_channel(struct ieee80211_link_data *link) { struct ieee80211_sub_if_data *sdata = link->sdata;
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) + return; + lockdep_assert_wiphy(sdata->local->hw.wiphy);
if (rcu_access_pointer(link->conf->chanctx_conf)) diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index c956072e0d77e..e0b44dbebe001 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -2087,6 +2087,9 @@ static inline void ieee80211_vif_clear_links(struct ieee80211_sub_if_data *sdata ieee80211_vif_set_links(sdata, 0, 0); }
+void ieee80211_apvlan_link_setup(struct ieee80211_sub_if_data *sdata); +void ieee80211_apvlan_link_clear(struct ieee80211_sub_if_data *sdata); + /* tx handling */ void ieee80211_clear_tx_pending(struct ieee80211_local *local); void ieee80211_tx_pending(struct tasklet_struct *t); diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 969b3e2c496af..7d93e5aa595b2 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -485,6 +485,9 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do case NL80211_IFTYPE_MONITOR: list_del_rcu(&sdata->u.mntr.list); break; + case NL80211_IFTYPE_AP_VLAN: + ieee80211_apvlan_link_clear(sdata); + break; default: break; } @@ -1268,6 +1271,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) sdata->crypto_tx_tailroom_needed_cnt += master->crypto_tx_tailroom_needed_cnt;
+ ieee80211_apvlan_link_setup(sdata); + break; } case NL80211_IFTYPE_AP: @@ -1324,7 +1329,12 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_AP_VLAN: /* no need to tell driver, but set carrier and chanctx */ if (sdata->bss->active) { - ieee80211_link_vlan_copy_chanctx(&sdata->deflink); + struct ieee80211_link_data *link; + + for_each_link_data(sdata, link) { + ieee80211_link_vlan_copy_chanctx(link); + } + netif_carrier_on(dev); ieee80211_set_vif_encap_ops(sdata); } else { diff --git a/net/mac80211/link.c b/net/mac80211/link.c index 58a76bcd6ae68..d40c2bd3b50b0 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -12,6 +12,71 @@ #include "key.h" #include "debugfs_netdev.h"
+static void ieee80211_update_apvlan_links(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_sub_if_data *vlan; + struct ieee80211_link_data *link; + u16 ap_bss_links = sdata->vif.valid_links; + u16 new_links, vlan_links; + unsigned long add; + + list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list) { + int link_id; + + if (!vlan) + continue; + + /* No support for 4addr with MLO yet */ + if (vlan->wdev.use_4addr) + return; + + vlan_links = vlan->vif.valid_links; + + new_links = ap_bss_links; + + add = new_links & ~vlan_links; + if (!add) + continue; + + ieee80211_vif_set_links(vlan, add, 0); + + for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) { + link = sdata_dereference(vlan->link[link_id], vlan); + ieee80211_link_vlan_copy_chanctx(link); + } + } +} + +void ieee80211_apvlan_link_setup(struct ieee80211_sub_if_data *sdata) +{ + struct ieee80211_sub_if_data *ap_bss = container_of(sdata->bss, + struct ieee80211_sub_if_data, u.ap); + u16 new_links = ap_bss->vif.valid_links; + unsigned long add; + int link_id; + + if (!ap_bss->vif.valid_links) + return; + + add = new_links; + for_each_set_bit(link_id, &add, IEEE80211_MLD_MAX_NUM_LINKS) { + sdata->wdev.valid_links |= BIT(link_id); + ether_addr_copy(sdata->wdev.links[link_id].addr, + ap_bss->wdev.links[link_id].addr); + } + + ieee80211_vif_set_links(sdata, new_links, 0); +} + +void ieee80211_apvlan_link_clear(struct ieee80211_sub_if_data *sdata) +{ + if (!sdata->wdev.valid_links) + return; + + sdata->wdev.valid_links = 0; + ieee80211_vif_clear_links(sdata); +} + void ieee80211_link_setup(struct ieee80211_link_data *link) { if (link->sdata->vif.type == NL80211_IFTYPE_STATION) @@ -31,6 +96,17 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf); rcu_assign_pointer(sdata->link[link_id], link);
+ if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { + struct ieee80211_sub_if_data *ap_bss; + struct ieee80211_bss_conf *ap_bss_conf; + + ap_bss = container_of(sdata->bss, + struct ieee80211_sub_if_data, u.ap); + ap_bss_conf = sdata_dereference(ap_bss->vif.link_conf[link_id], + ap_bss); + memcpy(link_conf, ap_bss_conf, sizeof(*link_conf)); + } + link->sdata = sdata; link->link_id = link_id; link->conf = link_conf; @@ -54,6 +130,7 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, if (!deflink) { switch (sdata->vif.type) { case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: ether_addr_copy(link_conf->addr, sdata->wdev.links[link_id].addr); link_conf->bssid = link_conf->addr; @@ -177,6 +254,7 @@ static void ieee80211_set_vif_links_bitmaps(struct ieee80211_sub_if_data *sdata,
switch (sdata->vif.type) { case NL80211_IFTYPE_AP: + case NL80211_IFTYPE_AP_VLAN: /* in an AP all links are always active */ sdata->vif.active_links = valid_links;
@@ -278,12 +356,16 @@ static int ieee80211_vif_update_links(struct ieee80211_sub_if_data *sdata, ieee80211_set_vif_links_bitmaps(sdata, new_links, dormant_links);
/* tell the driver */ - ret = drv_change_vif_links(sdata->local, sdata, - old_links & old_active, - new_links & sdata->vif.active_links, - old); + if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN) + ret = drv_change_vif_links(sdata->local, sdata, + old_links & old_active, + new_links & sdata->vif.active_links, + old); if (!new_links) ieee80211_debugfs_recreate_netdev(sdata, false); + + if (sdata->vif.type == NL80211_IFTYPE_AP) + ieee80211_update_apvlan_links(sdata); }
if (ret) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Berg johannes.berg@intel.com
[ Upstream commit d87c3ca0f8f1ca4c25f2ed819e954952f4d8d709 ]
Since the link/conf pointers can be accessed without any protection other than RCU, make sure the data is actually set up before publishing the structures.
Fixes: b2e8434f1829 ("wifi: mac80211: set up/tear down client vif links properly") Link: https://patch.msgid.link/20250624130749.9a308b713c74.I4a80f5eead112a38730939... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/mac80211/link.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/mac80211/link.c b/net/mac80211/link.c index d40c2bd3b50b0..4f7b7d0f64f24 100644 --- a/net/mac80211/link.c +++ b/net/mac80211/link.c @@ -93,9 +93,6 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata, if (link_id < 0) link_id = 0;
- rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf); - rcu_assign_pointer(sdata->link[link_id], link); - if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { struct ieee80211_sub_if_data *ap_bss; struct ieee80211_bss_conf *ap_bss_conf; @@ -145,6 +142,9 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
ieee80211_link_debugfs_add(link); } + + rcu_assign_pointer(sdata->vif.link_conf[link_id], link_conf); + rcu_assign_pointer(sdata->link[link_id], link); }
void ieee80211_link_stop(struct ieee80211_link_data *link)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 0748e553df0225754c316a92af3a77fdc057b358 ]
Once want_mount_setattr() has returned a positive, it does require finish_mount_kattr() to release ->mnt_userns. Failing do_mount_setattr() does not change that.
As the result, we can end up leaking userns and possibly mnt_idmap as well.
Fixes: c4a16820d901 ("fs: add open_tree_attr()") Reviewed-by: Christian Brauner brauner@kernel.org Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- fs/namespace.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c index 24b087ba88159..dfb72f827d4a7 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -5307,16 +5307,12 @@ SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename, kattr.kflags |= MOUNT_KATTR_RECURSE;
ret = wants_mount_setattr(uattr, usize, &kattr); - if (ret < 0) - return ret; - - if (ret) { + if (ret > 0) { ret = do_mount_setattr(&file->f_path, &kattr); - if (ret) - return ret; - finish_mount_kattr(&kattr); } + if (ret) + return ret; }
fd = get_unused_fd_flags(flags & O_CLOEXEC);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefano Garzarella sgarzare@redhat.com
[ Upstream commit 22bbc1dcd0d6785fb390c41f0dd5b5e218d23bdd ]
If a userspace application just include <linux/vm_sockets.h> will fail to build with the following errors:
/usr/include/linux/vm_sockets.h:182:39: error: invalid application of ‘sizeof’ to incomplete type ‘struct sockaddr’ 182 | unsigned char svm_zero[sizeof(struct sockaddr) - | ^~~~~~ /usr/include/linux/vm_sockets.h:183:39: error: ‘sa_family_t’ undeclared here (not in a function) 183 | sizeof(sa_family_t) - |
Include <sys/socket.h> for userspace (guarded by ifndef __KERNEL__) where `struct sockaddr` and `sa_family_t` are defined. We already do something similar in <linux/mptcp.h> and <linux/if.h>.
Fixes: d021c344051a ("VSOCK: Introduce VM Sockets") Reported-by: Daan De Meyer daan.j.demeyer@gmail.com Signed-off-by: Stefano Garzarella sgarzare@redhat.com Link: https://patch.msgid.link/20250623100053.40979-1-sgarzare@redhat.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- include/uapi/linux/vm_sockets.h | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/include/uapi/linux/vm_sockets.h b/include/uapi/linux/vm_sockets.h index ed07181d4eff9..e05280e415228 100644 --- a/include/uapi/linux/vm_sockets.h +++ b/include/uapi/linux/vm_sockets.h @@ -17,6 +17,10 @@ #ifndef _UAPI_VM_SOCKETS_H #define _UAPI_VM_SOCKETS_H
+#ifndef __KERNEL__ +#include <sys/socket.h> /* for struct sockaddr and sa_family_t */ +#endif + #include <linux/socket.h> #include <linux/types.h>
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yan Zhai yan@cloudflare.com
[ Upstream commit 9caca6ac0e26cd20efd490d8b3b2ffb1c7c00f6f ]
We encountered following crash when testing a XDP_REDIRECT feature in production:
[56251.579676] list_add corruption. next->prev should be prev (ffff93120dd40f30), but was ffffb301ef3a6740. (next=ffff93120dd 40f30). [56251.601413] ------------[ cut here ]------------ [56251.611357] kernel BUG at lib/list_debug.c:29! [56251.621082] Oops: invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [56251.632073] CPU: 111 UID: 0 PID: 0 Comm: swapper/111 Kdump: loaded Tainted: P O 6.12.33-cloudflare-2025.6. 3 #1 [56251.653155] Tainted: [P]=PROPRIETARY_MODULE, [O]=OOT_MODULE [56251.663877] Hardware name: MiTAC GC68B-B8032-G11P6-GPU/S8032GM-HE-CFR, BIOS V7.020.B10-sig 01/22/2025 [56251.682626] RIP: 0010:__list_add_valid_or_report+0x4b/0xa0 [56251.693203] Code: 0e 48 c7 c7 68 e7 d9 97 e8 42 16 fe ff 0f 0b 48 8b 52 08 48 39 c2 74 14 48 89 f1 48 c7 c7 90 e7 d9 97 48 89 c6 e8 25 16 fe ff <0f> 0b 4c 8b 02 49 39 f0 74 14 48 89 d1 48 c7 c7 e8 e7 d9 97 4c 89 [56251.725811] RSP: 0018:ffff93120dd40b80 EFLAGS: 00010246 [56251.736094] RAX: 0000000000000075 RBX: ffffb301e6bba9d8 RCX: 0000000000000000 [56251.748260] RDX: 0000000000000000 RSI: ffff9149afda0b80 RDI: ffff9149afda0b80 [56251.760349] RBP: ffff9131e49c8000 R08: 0000000000000000 R09: ffff93120dd40a18 [56251.772382] R10: ffff9159cf2ce1a8 R11: 0000000000000003 R12: ffff911a80850000 [56251.784364] R13: ffff93120fbc7000 R14: 0000000000000010 R15: ffff9139e7510e40 [56251.796278] FS: 0000000000000000(0000) GS:ffff9149afd80000(0000) knlGS:0000000000000000 [56251.809133] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [56251.819561] CR2: 00007f5e85e6f300 CR3: 00000038b85e2006 CR4: 0000000000770ef0 [56251.831365] PKRU: 55555554 [56251.838653] Call Trace: [56251.845560] <IRQ> [56251.851943] cpu_map_enqueue.cold+0x5/0xa [56251.860243] xdp_do_redirect+0x2d9/0x480 [56251.868388] bnxt_rx_xdp+0x1d8/0x4c0 [bnxt_en] [56251.877028] bnxt_rx_pkt+0x5f7/0x19b0 [bnxt_en] [56251.885665] ? cpu_max_write+0x1e/0x100 [56251.893510] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.902276] __bnxt_poll_work+0x190/0x340 [bnxt_en] [56251.911058] bnxt_poll+0xab/0x1b0 [bnxt_en] [56251.919041] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.927568] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.935958] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.944250] __napi_poll+0x2b/0x160 [56251.951155] bpf_trampoline_6442548651+0x79/0x123 [56251.959262] __napi_poll+0x5/0x160 [56251.966037] net_rx_action+0x3d2/0x880 [56251.973133] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.981265] ? srso_alias_return_thunk+0x5/0xfbef5 [56251.989262] ? __hrtimer_run_queues+0x162/0x2a0 [56251.996967] ? srso_alias_return_thunk+0x5/0xfbef5 [56252.004875] ? srso_alias_return_thunk+0x5/0xfbef5 [56252.012673] ? bnxt_msix+0x62/0x70 [bnxt_en] [56252.019903] handle_softirqs+0xcf/0x270 [56252.026650] irq_exit_rcu+0x67/0x90 [56252.032933] common_interrupt+0x85/0xa0 [56252.039498] </IRQ> [56252.044246] <TASK> [56252.048935] asm_common_interrupt+0x26/0x40 [56252.055727] RIP: 0010:cpuidle_enter_state+0xb8/0x420 [56252.063305] Code: dc 01 00 00 e8 f9 79 3b ff e8 64 f7 ff ff 49 89 c5 0f 1f 44 00 00 31 ff e8 a5 32 3a ff 45 84 ff 0f 85 ae 01 00 00 fb 45 85 f6 <0f> 88 88 01 00 00 48 8b 04 24 49 63 ce 4c 89 ea 48 6b f1 68 48 29 [56252.088911] RSP: 0018:ffff93120c97fe98 EFLAGS: 00000202 [56252.096912] RAX: ffff9149afd80000 RBX: ffff9141d3a72800 RCX: 0000000000000000 [56252.106844] RDX: 00003329176c6b98 RSI: ffffffe36db3fdc7 RDI: 0000000000000000 [56252.116733] RBP: 0000000000000002 R08: 0000000000000002 R09: 000000000000004e [56252.126652] R10: ffff9149afdb30c4 R11: 071c71c71c71c71c R12: ffffffff985ff860 [56252.136637] R13: 00003329176c6b98 R14: 0000000000000002 R15: 0000000000000000 [56252.146667] ? cpuidle_enter_state+0xab/0x420 [56252.153909] cpuidle_enter+0x2d/0x40 [56252.160360] do_idle+0x176/0x1c0 [56252.166456] cpu_startup_entry+0x29/0x30 [56252.173248] start_secondary+0xf7/0x100 [56252.179941] common_startup_64+0x13e/0x141 [56252.186886] </TASK>
From the crash dump, we found that the cpu_map_flush_list inside
redirect info is partially corrupted: its list_head->next points to itself, but list_head->prev points to a valid list of unflushed bq entries.
This turned out to be a result of missed XDP flush on redirect lists. By digging in the actual source code, we found that commit 7f0a168b0441 ("bnxt_en: Add completion ring pointer in TX and RX ring structures") incorrectly overwrites the event mask for XDP_REDIRECT in bnxt_rx_xdp. We can stably reproduce this crash by returning XDP_TX and XDP_REDIRECT randomly for incoming packets in a naive XDP program. Properly propagate the XDP_REDIRECT events back fixes the crash.
Fixes: a7559bc8c17c ("bnxt: support transmit and free of aggregation buffers") Tested-by: Andrew Rzeznik arzeznik@cloudflare.com Signed-off-by: Yan Zhai yan@cloudflare.com Acked-by: Jesper Dangaard Brouer hawk@kernel.org Reviewed-by: Michael Chan michael.chan@broadcom.com Reviewed-by: Andy Gospodarek gospo@broadcom.com Link: https://patch.msgid.link/aFl7jpCNzscumuN2@debian.debian Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index c365a9e64f728..9de6eefad9791 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -2958,6 +2958,7 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, { struct bnxt_napi *bnapi = cpr->bnapi; u32 raw_cons = cpr->cp_raw_cons; + bool flush_xdp = false; u32 cons; int rx_pkts = 0; u8 event = 0; @@ -3011,6 +3012,8 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, else rc = bnxt_force_rx_discard(bp, cpr, &raw_cons, &event); + if (event & BNXT_REDIRECT_EVENT) + flush_xdp = true; if (likely(rc >= 0)) rx_pkts += rc; /* Increment rx_pkts when rc is -ENOMEM to count towards @@ -3035,7 +3038,7 @@ static int __bnxt_poll_work(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, } }
- if (event & BNXT_REDIRECT_EVENT) { + if (flush_xdp) { xdp_do_flush(); event &= ~BNXT_REDIRECT_EVENT; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiwei Bie tiwei.btw@antgroup.com
[ Upstream commit c55c7a85e02a7bfee20a3ffebdff7cbeb41613ef ]
The subsequent call to os_set_fd_block() overwrites the previous return value. OR the two return values together to fix it.
Fixes: f88f0bdfc32f ("um: UBD Improvements") Signed-off-by: Tiwei Bie tiwei.btw@antgroup.com Link: https://patch.msgid.link/20250606124428.148164-2-tiwei.btw@antgroup.com Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/drivers/ubd_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c index c5e6545f6fcf6..8e8a8bf518b63 100644 --- a/arch/um/drivers/ubd_user.c +++ b/arch/um/drivers/ubd_user.c @@ -41,7 +41,7 @@ int start_io_thread(struct os_helper_thread **td_out, int *fd_out) *fd_out = fds[1];
err = os_set_fd_block(*fd_out, 0); - err = os_set_fd_block(kernel_fd, 0); + err |= os_set_fd_block(kernel_fd, 0); if (err) { printk("start_io_thread - failed to set nonblocking I/O.\n"); goto out_close;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe axboe@kernel.dk
[ Upstream commit 9a709b7e98e6fa51600b5f2d24c5068efa6d39de ]
A bigger array of vecs could've been allocated, but io_ring_buffers_peek() still decided to cap the mapped range depending on how much data was available. Hence don't rely on the segment count to know if the request should be marked as needing cleanup, always check upfront if the iov array is different than the fast_iov array.
Fixes: 26ec15e4b0c1 ("io_uring/kbuf: don't truncate end buffer for multiple buffer peeks") Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/net.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/io_uring/net.c b/io_uring/net.c index 3feceb2b5b97e..adfdcea01e39b 100644 --- a/io_uring/net.c +++ b/io_uring/net.c @@ -1084,6 +1084,12 @@ static int io_recv_buf_select(struct io_kiocb *req, struct io_async_msghdr *kmsg if (unlikely(ret < 0)) return ret;
+ if (arg.iovs != &kmsg->fast_iov && arg.iovs != kmsg->vec.iovec) { + kmsg->vec.nr = ret; + kmsg->vec.iovec = arg.iovs; + req->flags |= REQ_F_NEED_CLEANUP; + } + /* special case 1 vec, can be a fast path */ if (ret == 1) { sr->buf = arg.iovs[0].iov_base; @@ -1092,11 +1098,6 @@ static int io_recv_buf_select(struct io_kiocb *req, struct io_async_msghdr *kmsg } iov_iter_init(&kmsg->msg.msg_iter, ITER_DEST, arg.iovs, ret, arg.out_len); - if (arg.iovs != &kmsg->fast_iov && arg.iovs != kmsg->vec.iovec) { - kmsg->vec.nr = ret; - kmsg->vec.iovec = arg.iovs; - req->flags |= REQ_F_NEED_CLEANUP; - } } else { void __user *buf;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adin Scannell amscanne@meta.com
[ Upstream commit fa6f092cc0a02d0fcee37e9e8172eda372a03d33 ]
The `name` field in `obj->externs` points into the BTF data at initial open time. However, some functions may invalidate this after opening and before loading (e.g. `bpf_map__set_value_size`), which results in pointers into freed memory and undefined behavior.
The simplest solution is to simply `strdup` these strings, similar to the `essent_name`, and free them at the same time.
In order to test this path, the `global_map_resize` BPF selftest is modified slightly to ensure the presence of an extern, which causes this test to fail prior to the fix. Given there isn't an obvious API or error to test against, I opted to add this to the existing test as an aspect of the resizing feature rather than duplicate the test.
Fixes: 9d0a23313b1a ("libbpf: Add capability for resizing datasec maps") Signed-off-by: Adin Scannell amscanne@meta.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20250625050215.2777374-1-amscanne@meta.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/lib/bpf/libbpf.c | 10 +++++++--- .../selftests/bpf/progs/test_global_map_resize.c | 16 ++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 30cf210261032..97605ea8093ff 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -597,7 +597,7 @@ struct extern_desc { int sym_idx; int btf_id; int sec_btf_id; - const char *name; + char *name; char *essent_name; bool is_set; bool is_weak; @@ -4259,7 +4259,9 @@ static int bpf_object__collect_externs(struct bpf_object *obj) return ext->btf_id; } t = btf__type_by_id(obj->btf, ext->btf_id); - ext->name = btf__name_by_offset(obj->btf, t->name_off); + ext->name = strdup(btf__name_by_offset(obj->btf, t->name_off)); + if (!ext->name) + return -ENOMEM; ext->sym_idx = i; ext->is_weak = ELF64_ST_BIND(sym->st_info) == STB_WEAK;
@@ -9138,8 +9140,10 @@ void bpf_object__close(struct bpf_object *obj) zfree(&obj->btf_custom_path); zfree(&obj->kconfig);
- for (i = 0; i < obj->nr_extern; i++) + for (i = 0; i < obj->nr_extern; i++) { + zfree(&obj->externs[i].name); zfree(&obj->externs[i].essent_name); + }
zfree(&obj->externs); obj->nr_extern = 0; diff --git a/tools/testing/selftests/bpf/progs/test_global_map_resize.c b/tools/testing/selftests/bpf/progs/test_global_map_resize.c index a3f220ba7025b..ee65bad0436d0 100644 --- a/tools/testing/selftests/bpf/progs/test_global_map_resize.c +++ b/tools/testing/selftests/bpf/progs/test_global_map_resize.c @@ -32,6 +32,16 @@ int my_int_last SEC(".data.array_not_last");
int percpu_arr[1] SEC(".data.percpu_arr");
+/* at least one extern is included, to ensure that a specific + * regression is tested whereby resizing resulted in a free-after-use + * bug after type information is invalidated by the resize operation. + * + * There isn't a particularly good API to test for this specific condition, + * but by having externs for the resizing tests it will cover this path. + */ +extern int LINUX_KERNEL_VERSION __kconfig; +long version_sink; + SEC("tp/syscalls/sys_enter_getpid") int bss_array_sum(void *ctx) { @@ -44,6 +54,9 @@ int bss_array_sum(void *ctx) for (size_t i = 0; i < bss_array_len; ++i) sum += array[i];
+ /* see above; ensure this is not optimized out */ + version_sink = LINUX_KERNEL_VERSION; + return 0; }
@@ -59,6 +72,9 @@ int data_array_sum(void *ctx) for (size_t i = 0; i < data_array_len; ++i) sum += my_array[i];
+ /* see above; ensure this is not optimized out */ + version_sink = LINUX_KERNEL_VERSION; + return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Simon Horman horms@kernel.org
[ Upstream commit 7b515f35a911fdc31fbde6531828dcd6ae9803d3 ]
enetc_hw.h provides two versions of _enetc_rd_reg64. One which simply calls ioread64() when available. And another that composes the 64-bit result from ioread32() calls.
In the second case the code appears to assume that each ioread32() call returns a little-endian value. However both the shift and logical or used to compose the return value would not work correctly on big endian systems if this were the case. Moreover, this is inconsistent with the first case where the return value of ioread64() is assumed to be in host byte order.
It appears that the correct approach is for both versions to treat the return value of ioread*() functions as being in host byte order. And this patch corrects the ioread32()-based version to do so.
This is a bug but would only manifest on big endian systems that make use of the ioread32-based implementation of _enetc_rd_reg64. While all in-tree users of this driver are little endian and make use of the ioread64-based implementation of _enetc_rd_reg64. Thus, no in-tree user of this driver is affected by this bug.
Flagged by Sparse. Compile tested only.
Fixes: 16eb4c85c964 ("enetc: Add ethtool statistics") Closes: https://lore.kernel.org/all/AM9PR04MB850500D3FC24FE23DEFCEA158879A@AM9PR04MB... Signed-off-by: Simon Horman horms@kernel.org Reviewed-by: Wei Fang wei.fang@nxp.com Link: https://patch.msgid.link/20250624-etnetc-le-v1-1-a73a95d96e4e@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc_hw.h b/drivers/net/ethernet/freescale/enetc/enetc_hw.h index 4098f01479bc0..53e8d18c7a34a 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc_hw.h +++ b/drivers/net/ethernet/freescale/enetc/enetc_hw.h @@ -507,7 +507,7 @@ static inline u64 _enetc_rd_reg64(void __iomem *reg) tmp = ioread32(reg + 4); } while (high != tmp);
- return le64_to_cpu((__le64)high << 32 | low); + return (u64)high << 32 | low; } #endif
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit eef0eaeca7fa8e358a31e89802f564451b797718 ]
We're trying to add a strict regexp for the name format in the spec. Underscores will not be allowed, dashes should be used instead. This makes no difference to C (codegen, if used, replaces special chars in names) but it gives more uniform naming in Python.
Fixes: a1bcfde83669 ("doc/netlink/specs: Add a spec for tc") Reviewed-by: Donald Hunter donald.hunter@gmail.com Link: https://patch.msgid.link/20250624211002.3475021-10-kuba@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/netlink/specs/tc.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/Documentation/netlink/specs/tc.yaml b/Documentation/netlink/specs/tc.yaml index 953aa837958b3..5702a6d21038c 100644 --- a/Documentation/netlink/specs/tc.yaml +++ b/Documentation/netlink/specs/tc.yaml @@ -227,7 +227,7 @@ definitions: type: u8 doc: log(P_max / (qth-max - qth-min)) - - name: Scell_log + name: Scell-log type: u8 doc: cell size for idle damping - @@ -248,7 +248,7 @@ definitions: name: DPs type: u32 - - name: def_DP + name: def-DP type: u32 - name: grio
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima kuniyu@google.com
[ Upstream commit a433791aeaea6e84df709e0b9584b9bbe040cd1c ]
syzbot reported a warning below during atm_dev_register(). [0]
Before creating a new device and procfs/sysfs for it, atm_dev_register() looks up a duplicated device by __atm_dev_lookup(). These operations are done under atm_dev_mutex.
However, when removing a device in atm_dev_deregister(), it releases the mutex just after removing the device from the list that __atm_dev_lookup() iterates over.
So, there will be a small race window where the device does not exist on the device list but procfs/sysfs are still not removed, triggering the splat.
Let's hold the mutex until procfs/sysfs are removed in atm_dev_deregister().
[0]: proc_dir_entry 'atm/atmtcp:0' already registered WARNING: CPU: 0 PID: 5919 at fs/proc/generic.c:377 proc_register+0x455/0x5f0 fs/proc/generic.c:377 Modules linked in: CPU: 0 UID: 0 PID: 5919 Comm: syz-executor284 Not tainted 6.16.0-rc2-syzkaller-00047-g52da431bf03b #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/07/2025 RIP: 0010:proc_register+0x455/0x5f0 fs/proc/generic.c:377 Code: 48 89 f9 48 c1 e9 03 80 3c 01 00 0f 85 a2 01 00 00 48 8b 44 24 10 48 c7 c7 20 c0 c2 8b 48 8b b0 d8 00 00 00 e8 0c 02 1c ff 90 <0f> 0b 90 90 48 c7 c7 80 f2 82 8e e8 0b de 23 09 48 8b 4c 24 28 48 RSP: 0018:ffffc9000466fa30 EFLAGS: 00010282 RAX: 0000000000000000 RBX: 0000000000000000 RCX: ffffffff817ae248 RDX: ffff888026280000 RSI: ffffffff817ae255 RDI: 0000000000000001 RBP: ffff8880232bed48 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000001 R12: ffff888076ed2140 R13: dffffc0000000000 R14: ffff888078a61340 R15: ffffed100edda444 FS: 00007f38b3b0c6c0(0000) GS:ffff888124753000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f38b3bdf953 CR3: 0000000076d58000 CR4: 00000000003526f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> proc_create_data+0xbe/0x110 fs/proc/generic.c:585 atm_proc_dev_register+0x112/0x1e0 net/atm/proc.c:361 atm_dev_register+0x46d/0x890 net/atm/resources.c:113 atmtcp_create+0x77/0x210 drivers/atm/atmtcp.c:369 atmtcp_attach drivers/atm/atmtcp.c:403 [inline] atmtcp_ioctl+0x2f9/0xd60 drivers/atm/atmtcp.c:464 do_vcc_ioctl+0x12c/0x930 net/atm/ioctl.c:159 sock_do_ioctl+0x115/0x280 net/socket.c:1190 sock_ioctl+0x227/0x6b0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:907 [inline] __se_sys_ioctl fs/ioctl.c:893 [inline] __x64_sys_ioctl+0x18b/0x210 fs/ioctl.c:893 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x4c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f38b3b74459 Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 51 18 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f38b3b0c198 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 00007f38b3bfe318 RCX: 00007f38b3b74459 RDX: 0000000000000000 RSI: 0000000000006180 RDI: 0000000000000005 RBP: 00007f38b3bfe310 R08: 65732f636f72702f R09: 65732f636f72702f R10: 65732f636f72702f R11: 0000000000000246 R12: 00007f38b3bcb0ac R13: 00007f38b3b0c1a0 R14: 0000200000000200 R15: 00007f38b3bcb03b </TASK>
Fixes: 64bf69ddff76 ("[ATM]: deregistration removes device from atm_devs list immediately") Reported-by: syzbot+8bd335d2ad3b93e80715@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/685316de.050a0220.216029.0087.GAE@google.com/ Tested-by: syzbot+8bd335d2ad3b93e80715@syzkaller.appspotmail.com Signed-off-by: Kuniyuki Iwashima kuniyu@google.com Link: https://patch.msgid.link/20250624214505.570679-1-kuni1840@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/atm/resources.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/net/atm/resources.c b/net/atm/resources.c index 995d29e7fb138..b19d851e1f443 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c @@ -146,11 +146,10 @@ void atm_dev_deregister(struct atm_dev *dev) */ mutex_lock(&atm_dev_mutex); list_del(&dev->dev_list); - mutex_unlock(&atm_dev_mutex); - atm_dev_release_vccs(dev); atm_unregister_sysfs(dev); atm_proc_dev_deregister(dev); + mutex_unlock(&atm_dev_mutex);
atm_dev_put(dev); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salvatore Bonaccorso carnil@debian.org
[ Upstream commit 7ab6847a03229e73bb7c58ca397630f699e79b53 ]
The built-in mic of ASUS VivoBook X507UAR is broken recently by the fix of the pin sort. The fixup ALC256_FIXUP_ASUS_MIC_NO_PRESENCE is working for addressing the regression, too.
Fixes: 3b4309546b48 ("ALSA: hda: Fix headset detection failure due to unstable sort") Reported-by: Igor Tamara igor.tamara@gmail.com Closes: https://bugs.debian.org/1108069 Signed-off-by: Salvatore Bonaccorso carnil@debian.org Link: https://lore.kernel.org/CADdHDco7_o=4h_epjEAb92Dj-vUz_PoTC2-W9g5ncT2E0NzfeQ@... Signed-off-by: Takashi Iwai tiwai@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 02a424b7a9920..03ffaec49998d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11002,6 +11002,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1df3, "ASUS UM5606WA", ALC294_FIXUP_BASS_SPEAKER_15), SND_PCI_QUIRK(0x1043, 0x1264, "ASUS UM5606KA", ALC294_FIXUP_BASS_SPEAKER_15), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402ZA", ALC245_FIXUP_CS35L41_SPI_2), + SND_PCI_QUIRK(0x1043, 0x1e10, "ASUS VivoBook X507UAR", ALC256_FIXUP_ASUS_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1e1f, "ASUS Vivobook 15 X1504VAP", ALC2XX_FIXUP_HEADSET_MIC),
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski kuba@kernel.org
[ Upstream commit 8d89661a36dd3bb8c9902cff36dc0c144dce3faf ]
The length in the pseudo header should be the length of the L3 payload AKA the L4 header+payload. The selftest code builds the packet from the lower layers up, so all the headers are pushed already when it constructs L4. We need to subtract the lower layer headers from skb->len.
Fixes: 3e1e58d64c3d ("net: add generic selftest support") Signed-off-by: Jakub Kicinski kuba@kernel.org Reviewed-by: Gerhard Engleder gerhard@engleder-embedded.com Reported-by: Oleksij Rempel o.rempel@pengutronix.de Tested-by: Oleksij Rempel o.rempel@pengutronix.de Reviewed-by: Oleksij Rempel o.rempel@pengutronix.de Link: https://patch.msgid.link/20250624183258.3377740-1-kuba@kernel.org Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/selftests.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/core/selftests.c b/net/core/selftests.c index 35f807ea99523..406faf8e5f3f9 100644 --- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -160,8 +160,9 @@ static struct sk_buff *net_test_get_skb(struct net_device *ndev, skb->csum = 0; skb->ip_summed = CHECKSUM_PARTIAL; if (attr->tcp) { - thdr->check = ~tcp_v4_check(skb->len, ihdr->saddr, - ihdr->daddr, 0); + int l4len = skb->len - skb_transport_offset(skb); + + thdr->check = ~tcp_v4_check(l4len, ihdr->saddr, ihdr->daddr, 0); skb->csum_start = skb_transport_header(skb) - skb->head; skb->csum_offset = offsetof(struct tcphdr, check); } else {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig hch@lst.de
[ Upstream commit b2e607fecac15e07f50269c080e2e71b5049dfa2 ]
Move all the code out of nvme_update_disk_info into the helper, and rename the helper to have a somewhat less clumsy name.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Luis Chamberlain mcgrof@kernel.org Reviewed-by: John Garry john.g.garry@oracle.com Stable-dep-of: f46d273449ba ("nvme: fix atomic write size validation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 72 +++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 34 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 93a8119ad5ca6..1c853c5b8169b 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -1996,21 +1996,51 @@ static void nvme_configure_metadata(struct nvme_ctrl *ctrl, }
-static void nvme_update_atomic_write_disk_info(struct nvme_ns *ns, - struct nvme_id_ns *id, struct queue_limits *lim, - u32 bs, u32 atomic_bs) +static u32 nvme_configure_atomic_write(struct nvme_ns *ns, + struct nvme_id_ns *id, struct queue_limits *lim, u32 bs) { - unsigned int boundary = 0; + u32 atomic_bs, boundary = 0;
- if (id->nsfeat & NVME_NS_FEAT_ATOMICS && id->nawupf) { - if (le16_to_cpu(id->nabspf)) + /* + * We do not support an offset for the atomic boundaries. + */ + if (id->nabo) + return bs; + + if ((id->nsfeat & NVME_NS_FEAT_ATOMICS) && id->nawupf) { + /* + * Use the per-namespace atomic write unit when available. + */ + atomic_bs = (1 + le16_to_cpu(id->nawupf)) * bs; + if (id->nabspf) boundary = (le16_to_cpu(id->nabspf) + 1) * bs; + } else { + /* + * Use the controller wide atomic write unit. This sucks + * because the limit is defined in terms of logical blocks while + * namespaces can have different formats, and because there is + * no clear language in the specification prohibiting different + * values for different controllers in the subsystem. + */ + atomic_bs = (1 + ns->ctrl->awupf) * bs; + } + + if (!ns->ctrl->subsys->atomic_bs) { + ns->ctrl->subsys->atomic_bs = atomic_bs; + } else if (ns->ctrl->subsys->atomic_bs != atomic_bs) { + dev_err_ratelimited(ns->ctrl->device, + "%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n", + ns->disk ? ns->disk->disk_name : "?", + ns->ctrl->subsys->atomic_bs, + atomic_bs); } + lim->atomic_write_hw_max = atomic_bs; lim->atomic_write_hw_boundary = boundary; lim->atomic_write_hw_unit_min = bs; lim->atomic_write_hw_unit_max = rounddown_pow_of_two(atomic_bs); lim->features |= BLK_FEAT_ATOMIC_WRITES; + return atomic_bs; }
static u32 nvme_max_drv_segments(struct nvme_ctrl *ctrl) @@ -2048,34 +2078,8 @@ static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id, valid = false; }
- atomic_bs = phys_bs = bs; - if (id->nabo == 0) { - /* - * Bit 1 indicates whether NAWUPF is defined for this namespace - * and whether it should be used instead of AWUPF. If NAWUPF == - * 0 then AWUPF must be used instead. - */ - if (id->nsfeat & NVME_NS_FEAT_ATOMICS && id->nawupf) - atomic_bs = (1 + le16_to_cpu(id->nawupf)) * bs; - else - atomic_bs = (1 + ns->ctrl->awupf) * bs; - - /* - * Set subsystem atomic bs. - */ - if (ns->ctrl->subsys->atomic_bs) { - if (atomic_bs != ns->ctrl->subsys->atomic_bs) { - dev_err_ratelimited(ns->ctrl->device, - "%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n", - ns->disk ? ns->disk->disk_name : "?", - ns->ctrl->subsys->atomic_bs, - atomic_bs); - } - } else - ns->ctrl->subsys->atomic_bs = atomic_bs; - - nvme_update_atomic_write_disk_info(ns, id, lim, bs, atomic_bs); - } + phys_bs = bs; + atomic_bs = nvme_configure_atomic_write(ns, id, lim, bs);
if (id->nsfeat & NVME_NS_FEAT_IO_OPT) { /* NPWG = Namespace Preferred Write Granularity */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig hch@lst.de
[ Upstream commit f46d273449ba65afd53f3dd8fe0182c9df877e08 ]
Don't mix the namespace and controller values, and validate the per-controller limit when probing the controller. This avoid spurious failures for controllers with namespaces that have different namespaces with different logical block sizes, or report the per-namespace values only for some namespaces.
It also fixes a missing queue_limits_cancel_update in an error path by removing that error path.
Fixes: 8695f060a029 ("nvme: all namespaces in a subsystem must adhere to a common atomic write size") Reported-by: Yi Zhang yi.zhang@redhat.com Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Luis Chamberlain mcgrof@kernel.org Reviewed-by: John Garry john.g.garry@oracle.com Tested-by: Yi Zhang yi.zhang@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 33 +++++++++++---------------------- drivers/nvme/host/nvme.h | 3 +-- 2 files changed, 12 insertions(+), 24 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1c853c5b8169b..d253b82901110 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2022,17 +2022,7 @@ static u32 nvme_configure_atomic_write(struct nvme_ns *ns, * no clear language in the specification prohibiting different * values for different controllers in the subsystem. */ - atomic_bs = (1 + ns->ctrl->awupf) * bs; - } - - if (!ns->ctrl->subsys->atomic_bs) { - ns->ctrl->subsys->atomic_bs = atomic_bs; - } else if (ns->ctrl->subsys->atomic_bs != atomic_bs) { - dev_err_ratelimited(ns->ctrl->device, - "%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n", - ns->disk ? ns->disk->disk_name : "?", - ns->ctrl->subsys->atomic_bs, - atomic_bs); + atomic_bs = (1 + ns->ctrl->subsys->awupf) * bs; }
lim->atomic_write_hw_max = atomic_bs; @@ -2219,16 +2209,6 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns, if (!nvme_update_disk_info(ns, id, &lim)) capacity = 0;
- /* - * Validate the max atomic write size fits within the subsystem's - * atomic write capabilities. - */ - if (lim.atomic_write_hw_max > ns->ctrl->subsys->atomic_bs) { - blk_mq_unfreeze_queue(ns->disk->queue, memflags); - ret = -ENXIO; - goto out; - } - nvme_config_discard(ns, &lim); if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) && ns->head->ids.csi == NVME_CSI_ZNS) @@ -3044,6 +3024,7 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id) memcpy(subsys->model, id->mn, sizeof(subsys->model)); subsys->vendor_id = le16_to_cpu(id->vid); subsys->cmic = id->cmic; + subsys->awupf = le16_to_cpu(id->awupf);
/* Versions prior to 1.4 don't necessarily report a valid type */ if (id->cntrltype == NVME_CTRL_DISC || @@ -3373,6 +3354,15 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl) if (ret) goto out_free; } + + if (le16_to_cpu(id->awupf) != ctrl->subsys->awupf) { + dev_err_ratelimited(ctrl->device, + "inconsistent AWUPF, controller not added (%u/%u).\n", + le16_to_cpu(id->awupf), ctrl->subsys->awupf); + ret = -EINVAL; + goto out_free; + } + memcpy(ctrl->subsys->firmware_rev, id->fr, sizeof(ctrl->subsys->firmware_rev));
@@ -3468,7 +3458,6 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl) dev_pm_qos_expose_latency_tolerance(ctrl->device); else if (!ctrl->apst_enabled && prev_apst_enabled) dev_pm_qos_hide_latency_tolerance(ctrl->device); - ctrl->awupf = le16_to_cpu(id->awupf); out_free: kfree(id); return ret; diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 8fc4683418a3a..d8c4e545f732c 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -410,7 +410,6 @@ struct nvme_ctrl {
enum nvme_ctrl_type cntrltype; enum nvme_dctype dctype; - u16 awupf; /* 0's based value. */ };
static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl) @@ -443,11 +442,11 @@ struct nvme_subsystem { u8 cmic; enum nvme_subsys_type subtype; u16 vendor_id; + u16 awupf; /* 0's based value. */ struct ida ns_ida; #ifdef CONFIG_NVME_MULTIPATH enum nvme_iopolicy iopolicy; #endif - u32 atomic_bs; };
/*
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charles Mirabile cmirabil@redhat.com
[ Upstream commit 8d90d9872edae7e78c3a12b98e239bfaa66f3639 ]
the `__runtime_fixup_32` function does not handle the case where `val` is zero correctly (as might occur when patching a nommu kernel and referring to a physical address below the 4GiB boundary whose upper 32 bits are all zero) because nothing in the existing logic prevents the code from taking the `else` branch of both nop-checks and emitting two `nop` instructions.
This leaves random garbage in the register that is supposed to receive the upper 32 bits of the pointer instead of zero that when combined with the value for the lower 32 bits yields an invalid pointer and causes a kernel panic when that pointer is eventually accessed.
The author clearly considered the fact that if the `lui` is converted into a `nop` that the second instruction needs to be adjusted to become an `li` instead of an `addi`, hence introducing the `addi_insn_mask` variable, but didn't follow that logic through fully to the case where the `else` branch executes. To fix it just adjust the logic to ensure that the second `else` branch is not taken if the first instruction will be patched to a `nop`.
Fixes: a44fb5722199 ("riscv: Add runtime constant support")
Signed-off-by: Charles Mirabile cmirabil@redhat.com Reviewed-by: Charlie Jenkins charlie@rivosinc.com Tested-by: Charlie Jenkins charlie@rivosinc.com Link: https://lore.kernel.org/r/20250530211422.784415-2-cmirabil@redhat.com Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/include/asm/runtime-const.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/runtime-const.h b/arch/riscv/include/asm/runtime-const.h index 451fd76b88115..d766e2b9e6df1 100644 --- a/arch/riscv/include/asm/runtime-const.h +++ b/arch/riscv/include/asm/runtime-const.h @@ -206,7 +206,7 @@ static inline void __runtime_fixup_32(__le16 *lui_parcel, __le16 *addi_parcel, u addi_insn_mask &= 0x07fff; }
- if (lower_immediate & 0x00000fff) { + if (lower_immediate & 0x00000fff || lui_insn == RISCV_INSN_NOP4) { /* replace upper 12 bits of addi with lower 12 bits of val */ addi_insn &= addi_insn_mask; addi_insn |= (lower_immediate & 0x00000fff) << 20;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Louis Chauvet louis.chauvet@bootlin.com
[ Upstream commit fb721b2c35b1829b8ecf62e3adb41cf30260316a ]
The drm_writeback_connector_cleanup have the signature:
static void drm_writeback_connector_cleanup( struct drm_device *dev, struct drm_writeback_connector *wb_connector)
But it is stored and used as a drmres_release_t
typedef void (*drmres_release_t)(struct drm_device *dev, void *res);
While the current code is valid and does not produce any warning, the CFI runtime check (CONFIG_CFI_CLANG) can fail because the function signature is not the same as drmres_release_t.
In order to fix this, change the function signature to match what is expected by drmres_release_t.
Fixes: 1914ba2b91ea ("drm: writeback: Create drmm variants for drm_writeback_connector initialization")
Suggested-by: Mark Yacoub markyacoub@google.com Reviewed-by: Maíra Canal mcanal@igalia.com Link: https://lore.kernel.org/r/20250429-drm-fix-writeback-cleanup-v2-1-548ff3a4e2... Signed-off-by: Louis Chauvet louis.chauvet@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/drm_writeback.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index edbeab88ff2b6..d983ee85cf134 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -343,17 +343,18 @@ EXPORT_SYMBOL(drm_writeback_connector_init_with_encoder); /** * drm_writeback_connector_cleanup - Cleanup the writeback connector * @dev: DRM device - * @wb_connector: Pointer to the writeback connector to clean up + * @data: Pointer to the writeback connector to clean up * * This will decrement the reference counter of blobs and destroy properties. It * will also clean the remaining jobs in this writeback connector. Caution: This helper will not * clean up the attached encoder and the drm_connector. */ static void drm_writeback_connector_cleanup(struct drm_device *dev, - struct drm_writeback_connector *wb_connector) + void *data) { unsigned long flags; struct drm_writeback_job *pos, *n; + struct drm_writeback_connector *wb_connector = data;
delete_writeback_properties(dev); drm_property_blob_put(wb_connector->pixel_formats_blob_ptr); @@ -405,7 +406,7 @@ int drmm_writeback_connector_init(struct drm_device *dev, if (ret) return ret;
- ret = drmm_add_action_or_reset(dev, (void *)drm_writeback_connector_cleanup, + ret = drmm_add_action_or_reset(dev, drm_writeback_connector_cleanup, wb_connector); if (ret) return ret;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 73eab78721f7b85216f1ca8c7b732f13213b5b32 ]
commit 017fbb6690c2 ("drm/amdgpu/discovery: check ip_discovery fw file available") added support for reading an amdgpu IP discovery bin file for some specific products. If it's not found then it will fallback to hardcoded values. However if it's not found there is also a lot of noise about missing files and errors.
Adjust the error handling to decrease most messages to DEBUG and to show users less about missing files.
Reviewed-by: Lijo Lazar lijo.lazar@amd.com Reported-by: Marcus Seyfarth m.seyfarth@gmail.com Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4312 Tested-by: Marcus Seyfarth m.seyfarth@gmail.com Fixes: 017fbb6690c2 ("drm/amdgpu/discovery: check ip_discovery fw file available") Acked-by: Alex Deucher alexander.deucher@amd.com Link: https://lore.kernel.org/r/20250617183052.1692059-1-superm1@kernel.org Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 49f1f9f6c3c9febf8ba93f94a8d9c8d03e1ea0a1) Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c index 9e738fae2b74f..6d34eac0539d4 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c @@ -311,10 +311,12 @@ static int amdgpu_discovery_read_binary_from_file(struct amdgpu_device *adev, const struct firmware *fw; int r;
- r = request_firmware(&fw, fw_name, adev->dev); + r = firmware_request_nowarn(&fw, fw_name, adev->dev); if (r) { - dev_err(adev->dev, "can't load firmware "%s"\n", - fw_name); + if (amdgpu_discovery == 2) + dev_err(adev->dev, "can't load firmware "%s"\n", fw_name); + else + drm_info(&adev->ddev, "Optional firmware "%s" was not found\n", fw_name); return r; }
@@ -449,16 +451,12 @@ static int amdgpu_discovery_init(struct amdgpu_device *adev) /* Read from file if it is the preferred option */ fw_name = amdgpu_discovery_get_fw_name(adev); if (fw_name != NULL) { - dev_info(adev->dev, "use ip discovery information from file"); + drm_dbg(&adev->ddev, "use ip discovery information from file"); r = amdgpu_discovery_read_binary_from_file(adev, adev->mman.discovery_bin, fw_name); - - if (r) { - dev_err(adev->dev, "failed to read ip discovery binary from file\n"); - r = -EINVAL; + if (r) goto out; - } - } else { + drm_dbg(&adev->ddev, "use ip discovery information from memory"); r = amdgpu_discovery_read_binary_from_mem( adev, adev->mman.discovery_bin); if (r) @@ -1328,10 +1326,8 @@ static int amdgpu_discovery_reg_base_init(struct amdgpu_device *adev) int r;
r = amdgpu_discovery_init(adev); - if (r) { - DRM_ERROR("amdgpu_discovery_init failed\n"); + if (r) return r; - }
wafl_ver = 0; adev->gfx.xcc_mask = 0; @@ -2569,8 +2565,10 @@ int amdgpu_discovery_set_ip_blocks(struct amdgpu_device *adev) break; default: r = amdgpu_discovery_reg_base_init(adev); - if (r) - return -EINVAL; + if (r) { + drm_err(&adev->ddev, "discovery failed: %d\n", r); + return r; + }
amdgpu_discovery_harvest_ip(adev); amdgpu_discovery_get_gfx_info(adev);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit d02b2103a08b6d6908f1d3d8e8783d3f342555ac ]
An earlier patch fixed a build failure with clang, but I still see the same problem with some configurations using gcc:
drivers/gpu/drm/i915/i915_pmu.c: In function 'config_mask': include/linux/compiler_types.h:568:38: error: call to '__compiletime_assert_462' declared with attribute error: BUILD_BUG_ON failed: bit > BITS_PER_TYPE(typeof_member(struct i915_pmu, enable)) - 1 drivers/gpu/drm/i915/i915_pmu.c:116:3: note: in expansion of macro 'BUILD_BUG_ON' 116 | BUILD_BUG_ON(bit >
As I understand it, the problem is that the function is not always fully inlined, but the __builtin_constant_p() can still evaluate the argument as being constant.
Marking it as __always_inline so far works for me in all configurations.
Fixes: a7137b1825b5 ("drm/i915/pmu: Fix build error with GCOV and AutoFDO enabled") Fixes: a644fde77ff7 ("drm/i915/pmu: Change bitmask of enabled events to u32") Reviewed-by: Rodrigo Vivi rodrigo.vivi@intel.com Signed-off-by: Arnd Bergmann arnd@arndb.de Link: https://lore.kernel.org/r/20250620111824.3395007-1-arnd@kernel.org Signed-off-by: Rodrigo Vivi rodrigo.vivi@intel.com (cherry picked from commit ef69f9dd1cd7301cdf04ba326ed28152a3affcf6) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/i915/i915_pmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/i915/i915_pmu.c b/drivers/gpu/drm/i915/i915_pmu.c index 990bfaba3ce4e..5bc696bfbb0fe 100644 --- a/drivers/gpu/drm/i915/i915_pmu.c +++ b/drivers/gpu/drm/i915/i915_pmu.c @@ -108,7 +108,7 @@ static unsigned int config_bit(const u64 config) return other_bit(config); }
-static u32 config_mask(const u64 config) +static __always_inline u32 config_mask(const u64 config) { unsigned int bit = config_bit(config);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wolfram Sang wsa+renesas@sang-engineering.com
[ Upstream commit 1d1f7b15cb9c11974cebfd39da51dc69b8cb31ff ]
Do not create a custom directory in debugfs-root, but use the debugfs_init callback to create a custom directory at the given place for the bridge. The new directory layout looks like this on a Renesas GrayHawk-Single with a R-Car V4M SoC:
/sys/kernel/debug/dri/feb00000.display/DP-1/1-002c
Signed-off-by: Wolfram Sang wsa+renesas@sang-engineering.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Reviewed-by: Douglas Anderson dianders@chromium.org Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://patchwork.freedesktop.org/patch/msgid/20250315201651.7339-2-wsa+rene... Stable-dep-of: 55e8ff842051 ("drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 40 +++++++-------------------- 1 file changed, 10 insertions(+), 30 deletions(-)
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index 01d456b955abb..c1ed1a3d68447 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -423,36 +423,8 @@ static int status_show(struct seq_file *s, void *data)
return 0; } - DEFINE_SHOW_ATTRIBUTE(status);
-static void ti_sn65dsi86_debugfs_remove(void *data) -{ - debugfs_remove_recursive(data); -} - -static void ti_sn65dsi86_debugfs_init(struct ti_sn65dsi86 *pdata) -{ - struct device *dev = pdata->dev; - struct dentry *debugfs; - int ret; - - debugfs = debugfs_create_dir(dev_name(dev), NULL); - - /* - * We might get an error back if debugfs wasn't enabled in the kernel - * so let's just silently return upon failure. - */ - if (IS_ERR_OR_NULL(debugfs)) - return; - - ret = devm_add_action_or_reset(dev, ti_sn65dsi86_debugfs_remove, debugfs); - if (ret) - return; - - debugfs_create_file("status", 0600, debugfs, pdata, &status_fops); -} - /* ----------------------------------------------------------------------------- * Auxiliary Devices (*not* AUX) */ @@ -1216,6 +1188,15 @@ static const struct drm_edid *ti_sn_bridge_edid_read(struct drm_bridge *bridge, return drm_edid_read_ddc(connector, &pdata->aux.ddc); }
+static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry *root) +{ + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + struct dentry *debugfs; + + debugfs = debugfs_create_dir(dev_name(pdata->dev), root); + debugfs_create_file("status", 0600, debugfs, pdata, &status_fops); +} + static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .attach = ti_sn_bridge_attach, .detach = ti_sn_bridge_detach, @@ -1229,6 +1210,7 @@ static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .atomic_reset = drm_atomic_helper_bridge_reset, .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .debugfs_init = ti_sn65dsi86_debugfs_init, };
static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata, @@ -1937,8 +1919,6 @@ static int ti_sn65dsi86_probe(struct i2c_client *client) if (ret) return ret;
- ti_sn65dsi86_debugfs_init(pdata); - /* * Break ourselves up into a collection of aux devices. The only real * motiviation here is to solve the chicken-and-egg problem of probe
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jayesh Choudhary j-choudhary@ti.com
[ Upstream commit 55e8ff842051b1150461d7595d8f1d033c69d66b ]
By default, HPD was disabled on SN65DSI86 bridge. When the driver was added (commit "a095f15c00e27"), the HPD_DISABLE bit was set in pre-enable call which was moved to other function calls subsequently. Later on, commit "c312b0df3b13" added detect utility for DP mode. But with HPD_DISABLE bit set, all the HPD events are disabled[0] and the debounced state always return 1 (always connected state).
Set HPD_DISABLE bit conditionally based on display sink's connector type. Since the HPD_STATE is reflected correctly only after waiting for debounce time (~100-400ms) and adding this delay in detect() is not feasible owing to the performace impact (glitches and frame drop), remove runtime calls in detect() and add hpd_enable()/disable() bridge hooks with runtime calls, to detect hpd properly without any delay.
[0]: https://www.ti.com/lit/gpn/SN65DSI86 (Pg. 32)
Fixes: c312b0df3b13 ("drm/bridge: ti-sn65dsi86: Implement bridge connector operations for DP") Cc: Max Krummenacher max.krummenacher@toradex.com Reviewed-by: Douglas Anderson dianders@chromium.org Tested-by: Ernest Van Hoecke ernest.vanhoecke@toradex.com Signed-off-by: Jayesh Choudhary j-choudhary@ti.com Signed-off-by: Douglas Anderson dianders@chromium.org Link: https://lore.kernel.org/r/20250624044835.165708-1-j-choudhary@ti.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 69 +++++++++++++++++++++++---- 1 file changed, 60 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c index c1ed1a3d68447..4ea13e5a3a54a 100644 --- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c +++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c @@ -330,12 +330,18 @@ static void ti_sn65dsi86_enable_comms(struct ti_sn65dsi86 *pdata) * 200 ms. We'll assume that the panel driver will have the hardcoded * delay in its prepare and always disable HPD. * - * If HPD somehow makes sense on some future panel we'll have to - * change this to be conditional on someone specifying that HPD should - * be used. + * For DisplayPort bridge type, we need HPD. So we use the bridge type + * to conditionally disable HPD. + * NOTE: The bridge type is set in ti_sn_bridge_probe() but enable_comms() + * can be called before. So for DisplayPort, HPD will be enabled once + * bridge type is set. We are using bridge type instead of "no-hpd" + * property because it is not used properly in devicetree description + * and hence is unreliable. */ - regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE, - HPD_DISABLE); + + if (pdata->bridge.type != DRM_MODE_CONNECTOR_DisplayPort) + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE, + HPD_DISABLE);
pdata->comms_enabled = true;
@@ -1172,9 +1178,14 @@ static enum drm_connector_status ti_sn_bridge_detect(struct drm_bridge *bridge) struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); int val = 0;
- pm_runtime_get_sync(pdata->dev); + /* + * Runtime reference is grabbed in ti_sn_bridge_hpd_enable() + * as the chip won't report HPD just after being powered on. + * HPD_DEBOUNCED_STATE reflects correct state only after the + * debounce time (~100-400 ms). + */ + regmap_read(pdata->regmap, SN_HPD_DISABLE_REG, &val); - pm_runtime_put_autosuspend(pdata->dev);
return val & HPD_DEBOUNCED_STATE ? connector_status_connected : connector_status_disconnected; @@ -1197,6 +1208,26 @@ static void ti_sn65dsi86_debugfs_init(struct drm_bridge *bridge, struct dentry * debugfs_create_file("status", 0600, debugfs, pdata, &status_fops); }
+static void ti_sn_bridge_hpd_enable(struct drm_bridge *bridge) +{ + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + + /* + * Device needs to be powered on before reading the HPD state + * for reliable hpd detection in ti_sn_bridge_detect() due to + * the high debounce time. + */ + + pm_runtime_get_sync(pdata->dev); +} + +static void ti_sn_bridge_hpd_disable(struct drm_bridge *bridge) +{ + struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge); + + pm_runtime_put_autosuspend(pdata->dev); +} + static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .attach = ti_sn_bridge_attach, .detach = ti_sn_bridge_detach, @@ -1211,6 +1242,8 @@ static const struct drm_bridge_funcs ti_sn_bridge_funcs = { .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, .debugfs_init = ti_sn65dsi86_debugfs_init, + .hpd_enable = ti_sn_bridge_hpd_enable, + .hpd_disable = ti_sn_bridge_hpd_disable, };
static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata, @@ -1299,8 +1332,26 @@ static int ti_sn_bridge_probe(struct auxiliary_device *adev, pdata->bridge.type = pdata->next_bridge->type == DRM_MODE_CONNECTOR_DisplayPort ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;
- if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) - pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT; + if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) { + pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT | + DRM_BRIDGE_OP_HPD; + /* + * If comms were already enabled they would have been enabled + * with the wrong value of HPD_DISABLE. Update it now. Comms + * could be enabled if anyone is holding a pm_runtime reference + * (like if a GPIO is in use). Note that in most cases nobody + * is doing AUX channel xfers before the bridge is added so + * HPD doesn't _really_ matter then. The only exception is in + * the eDP case where the panel wants to read the EDID before + * the bridge is added. We always consistently have HPD disabled + * for eDP. + */ + mutex_lock(&pdata->comms_mutex); + if (pdata->comms_enabled) + regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, + HPD_DISABLE, 0); + mutex_unlock(&pdata->comms_mutex); + };
drm_bridge_add(&pdata->bridge);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Wajdeczko michal.wajdeczko@intel.com
[ Upstream commit ad40098da5c3b43114d860a5b5740e7204158534 ]
During driver probe we might be briefly using CT safe mode, which is based on a delayed work, but usually we are able to stop this once we have IRQ fully operational. However, if we abort the probe quite early then during unwind we might try to destroy the workqueue while there is still a pending delayed work that attempts to restart itself which triggers a WARN.
This was recently observed during unsuccessful VF initialization:
[ ] xe 0000:00:02.1: probe with driver xe failed with error -62 [ ] ------------[ cut here ]------------ [ ] workqueue: cannot queue safe_mode_worker_func [xe] on wq xe-g2h-wq [ ] WARNING: CPU: 9 PID: 0 at kernel/workqueue.c:2257 __queue_work+0x287/0x710 [ ] RIP: 0010:__queue_work+0x287/0x710 [ ] Call Trace: [ ] delayed_work_timer_fn+0x19/0x30 [ ] call_timer_fn+0xa1/0x2a0
Exit the CT safe mode on unwind to avoid that warning.
Fixes: 09b286950f29 ("drm/xe/guc: Allow CTB G2H processing without G2H IRQ") Signed-off-by: Michal Wajdeczko michal.wajdeczko@intel.com Cc: Matthew Brost matthew.brost@intel.com Reviewed-by: Matthew Brost matthew.brost@intel.com Link: https://lore.kernel.org/r/20250612220937.857-3-michal.wajdeczko@intel.com (cherry picked from commit 2ddbb73ec20b98e70a5200cb85deade22ccea2ec) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_guc_ct.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_guc_ct.c b/drivers/gpu/drm/xe/xe_guc_ct.c index 72ad576fc18eb..c9abca63998b1 100644 --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -34,6 +34,11 @@ #include "xe_pm.h" #include "xe_trace_guc.h"
+static void receive_g2h(struct xe_guc_ct *ct); +static void g2h_worker_func(struct work_struct *w); +static void safe_mode_worker_func(struct work_struct *w); +static void ct_exit_safe_mode(struct xe_guc_ct *ct); + #if IS_ENABLED(CONFIG_DRM_XE_DEBUG) enum { /* Internal states, not error conditions */ @@ -186,14 +191,11 @@ static void guc_ct_fini(struct drm_device *drm, void *arg) { struct xe_guc_ct *ct = arg;
+ ct_exit_safe_mode(ct); destroy_workqueue(ct->g2h_wq); xa_destroy(&ct->fence_lookup); }
-static void receive_g2h(struct xe_guc_ct *ct); -static void g2h_worker_func(struct work_struct *w); -static void safe_mode_worker_func(struct work_struct *w); - static void primelockdep(struct xe_guc_ct *ct) { if (!IS_ENABLED(CONFIG_LOCKDEP))
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Wajdeczko michal.wajdeczko@intel.com
[ Upstream commit af2b588abe006bd55ddd358c4c3b87523349c475 ]
While we are indirectly draining our dedicated workqueue ggtt->wq that we use to complete asynchronous removal of some GGTT nodes, this happends as part of the managed-drm unwinding (ggtt_fini_early), which could be later then manage-device unwinding, where we could already unmap our MMIO/GMS mapping (mmio_fini).
This was recently observed during unsuccessful VF initialization:
[ ] xe 0000:00:02.1: probe with driver xe failed with error -62 [ ] xe 0000:00:02.1: DEVRES REL ffff88811e747340 __xe_bo_unpin_map_no_vm (16 bytes) [ ] xe 0000:00:02.1: DEVRES REL ffff88811e747540 __xe_bo_unpin_map_no_vm (16 bytes) [ ] xe 0000:00:02.1: DEVRES REL ffff88811e747240 __xe_bo_unpin_map_no_vm (16 bytes) [ ] xe 0000:00:02.1: DEVRES REL ffff88811e747040 tiles_fini (16 bytes) [ ] xe 0000:00:02.1: DEVRES REL ffff88811e746840 mmio_fini (16 bytes) [ ] xe 0000:00:02.1: DEVRES REL ffff88811e747f40 xe_bo_pinned_fini (16 bytes) [ ] xe 0000:00:02.1: DEVRES REL ffff88811e746b40 devm_drm_dev_init_release (16 bytes) [ ] xe 0000:00:02.1: [drm:drm_managed_release] drmres release begin [ ] xe 0000:00:02.1: [drm:drm_managed_release] REL ffff88810ef81640 __fini_relay (8 bytes) [ ] xe 0000:00:02.1: [drm:drm_managed_release] REL ffff88810ef80d40 guc_ct_fini (8 bytes) [ ] xe 0000:00:02.1: [drm:drm_managed_release] REL ffff88810ef80040 __drmm_mutex_release (8 bytes) [ ] xe 0000:00:02.1: [drm:drm_managed_release] REL ffff88810ef80140 ggtt_fini_early (8 bytes)
and this was leading to:
[ ] BUG: unable to handle page fault for address: ffffc900058162a0 [ ] #PF: supervisor write access in kernel mode [ ] #PF: error_code(0x0002) - not-present page [ ] Oops: Oops: 0002 [#1] SMP NOPTI [ ] Tainted: [W]=WARN [ ] Workqueue: xe-ggtt-wq ggtt_node_remove_work_func [xe] [ ] RIP: 0010:xe_ggtt_set_pte+0x6d/0x350 [xe] [ ] Call Trace: [ ] <TASK> [ ] xe_ggtt_clear+0xb0/0x270 [xe] [ ] ggtt_node_remove+0xbb/0x120 [xe] [ ] ggtt_node_remove_work_func+0x30/0x50 [xe] [ ] process_one_work+0x22b/0x6f0 [ ] worker_thread+0x1e8/0x3d
Add managed-device action that will explicitly drain the workqueue with all pending node removals prior to releasing MMIO/GSM mapping.
Fixes: 919bb54e989c ("drm/xe: Fix missing runtime outer protection for ggtt_remove_node") Signed-off-by: Michal Wajdeczko michal.wajdeczko@intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Cc: Lucas De Marchi lucas.demarchi@intel.com Reviewed-by: Rodrigo Vivi rodrigo.vivi@intel.com Link: https://lore.kernel.org/r/20250612220937.857-2-michal.wajdeczko@intel.com (cherry picked from commit 89d2835c3680ab1938e22ad81b1c9f8c686bd391) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_ggtt.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_ggtt.c b/drivers/gpu/drm/xe/xe_ggtt.c index 5fcb2b4c2c139..60bce5de52725 100644 --- a/drivers/gpu/drm/xe/xe_ggtt.c +++ b/drivers/gpu/drm/xe/xe_ggtt.c @@ -201,6 +201,13 @@ static const struct xe_ggtt_pt_ops xelpg_pt_wa_ops = { .ggtt_set_pte = xe_ggtt_set_pte_and_flush, };
+static void dev_fini_ggtt(void *arg) +{ + struct xe_ggtt *ggtt = arg; + + drain_workqueue(ggtt->wq); +} + /** * xe_ggtt_init_early - Early GGTT initialization * @ggtt: the &xe_ggtt to be initialized @@ -257,6 +264,10 @@ int xe_ggtt_init_early(struct xe_ggtt *ggtt) if (err) return err;
+ err = devm_add_action_or_reset(xe->drm.dev, dev_fini_ggtt, ggtt); + if (err) + return err; + if (IS_SRIOV_VF(xe)) { err = xe_gt_sriov_vf_prepare_ggtt(xe_tile_get_gt(ggtt->tile, 0)); if (err)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara pc@manguebit.org
[ Upstream commit 711741f94ac3cf9f4e3aa73aa171e76d188c0819 ]
Fix cifs_signal_cifsd_for_reconnect() to take the correct lock order and prevent the following deadlock from happening
====================================================== WARNING: possible circular locking dependency detected 6.16.0-rc3-build2+ #1301 Tainted: G S W ------------------------------------------------------ cifsd/6055 is trying to acquire lock: ffff88810ad56038 (&tcp_ses->srv_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x134/0x200
but task is already holding lock: ffff888119c64330 (&ret_buf->chan_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0xcf/0x200
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #2 (&ret_buf->chan_lock){+.+.}-{3:3}: validate_chain+0x1cf/0x270 __lock_acquire+0x60e/0x780 lock_acquire.part.0+0xb4/0x1f0 _raw_spin_lock+0x2f/0x40 cifs_setup_session+0x81/0x4b0 cifs_get_smb_ses+0x771/0x900 cifs_mount_get_session+0x7e/0x170 cifs_mount+0x92/0x2d0 cifs_smb3_do_mount+0x161/0x460 smb3_get_tree+0x55/0x90 vfs_get_tree+0x46/0x180 do_new_mount+0x1b0/0x2e0 path_mount+0x6ee/0x740 do_mount+0x98/0xe0 __do_sys_mount+0x148/0x180 do_syscall_64+0xa4/0x260 entry_SYSCALL_64_after_hwframe+0x76/0x7e
-> #1 (&ret_buf->ses_lock){+.+.}-{3:3}: validate_chain+0x1cf/0x270 __lock_acquire+0x60e/0x780 lock_acquire.part.0+0xb4/0x1f0 _raw_spin_lock+0x2f/0x40 cifs_match_super+0x101/0x320 sget+0xab/0x270 cifs_smb3_do_mount+0x1e0/0x460 smb3_get_tree+0x55/0x90 vfs_get_tree+0x46/0x180 do_new_mount+0x1b0/0x2e0 path_mount+0x6ee/0x740 do_mount+0x98/0xe0 __do_sys_mount+0x148/0x180 do_syscall_64+0xa4/0x260 entry_SYSCALL_64_after_hwframe+0x76/0x7e
-> #0 (&tcp_ses->srv_lock){+.+.}-{3:3}: check_noncircular+0x95/0xc0 check_prev_add+0x115/0x2f0 validate_chain+0x1cf/0x270 __lock_acquire+0x60e/0x780 lock_acquire.part.0+0xb4/0x1f0 _raw_spin_lock+0x2f/0x40 cifs_signal_cifsd_for_reconnect+0x134/0x200 __cifs_reconnect+0x8f/0x500 cifs_handle_standard+0x112/0x280 cifs_demultiplex_thread+0x64d/0xbc0 kthread+0x2f7/0x310 ret_from_fork+0x2a/0x230 ret_from_fork_asm+0x1a/0x30
other info that might help us debug this:
Chain exists of: &tcp_ses->srv_lock --> &ret_buf->ses_lock --> &ret_buf->chan_lock
Possible unsafe locking scenario:
CPU0 CPU1 ---- ---- lock(&ret_buf->chan_lock); lock(&ret_buf->ses_lock); lock(&ret_buf->chan_lock); lock(&tcp_ses->srv_lock);
*** DEADLOCK ***
3 locks held by cifsd/6055: #0: ffffffff857de398 (&cifs_tcp_ses_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x7b/0x200 #1: ffff888119c64060 (&ret_buf->ses_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0x9c/0x200 #2: ffff888119c64330 (&ret_buf->chan_lock){+.+.}-{3:3}, at: cifs_signal_cifsd_for_reconnect+0xcf/0x200
Cc: linux-cifs@vger.kernel.org Reported-by: David Howells dhowells@redhat.com Fixes: d7d7a66aacd6 ("cifs: avoid use of global locks for high contention data") Reviewed-by: David Howells dhowells@redhat.com Tested-by: David Howells dhowells@redhat.com Signed-off-by: Paulo Alcantara (Red Hat) pc@manguebit.org Signed-off-by: David Howells dhowells@redhat.com Signed-off-by: Steve French stfrench@microsoft.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/smb/client/cifsglob.h | 1 + fs/smb/client/connect.c | 58 +++++++++++++++++++++++++--------------- 2 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h index 214e53acf72a8..56381cbb63990 100644 --- a/fs/smb/client/cifsglob.h +++ b/fs/smb/client/cifsglob.h @@ -709,6 +709,7 @@ inc_rfc1001_len(void *buf, int count) struct TCP_Server_Info { struct list_head tcp_ses_list; struct list_head smb_ses_list; + struct list_head rlist; /* reconnect list */ spinlock_t srv_lock; /* protect anything here that is not protected */ __u64 conn_id; /* connection identifier (useful for debugging) */ int srv_count; /* reference counter */ diff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c index f9aef60f1901a..e92c7b71626fd 100644 --- a/fs/smb/client/connect.c +++ b/fs/smb/client/connect.c @@ -124,6 +124,14 @@ static void smb2_query_server_interfaces(struct work_struct *work) (SMB_INTERFACE_POLL_INTERVAL * HZ)); }
+#define set_need_reco(server) \ +do { \ + spin_lock(&server->srv_lock); \ + if (server->tcpStatus != CifsExiting) \ + server->tcpStatus = CifsNeedReconnect; \ + spin_unlock(&server->srv_lock); \ +} while (0) + /* * Update the tcpStatus for the server. * This is used to signal the cifsd thread to call cifs_reconnect @@ -137,39 +145,45 @@ void cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server, bool all_channels) { - struct TCP_Server_Info *pserver; + struct TCP_Server_Info *nserver; struct cifs_ses *ses; + LIST_HEAD(reco); int i;
- /* If server is a channel, select the primary channel */ - pserver = SERVER_IS_CHAN(server) ? server->primary_server : server; - /* if we need to signal just this channel */ if (!all_channels) { - spin_lock(&server->srv_lock); - if (server->tcpStatus != CifsExiting) - server->tcpStatus = CifsNeedReconnect; - spin_unlock(&server->srv_lock); + set_need_reco(server); return; }
- spin_lock(&cifs_tcp_ses_lock); - list_for_each_entry(ses, &pserver->smb_ses_list, smb_ses_list) { - if (cifs_ses_exiting(ses)) - continue; - spin_lock(&ses->chan_lock); - for (i = 0; i < ses->chan_count; i++) { - if (!ses->chans[i].server) + if (SERVER_IS_CHAN(server)) + server = server->primary_server; + scoped_guard(spinlock, &cifs_tcp_ses_lock) { + set_need_reco(server); + list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { + spin_lock(&ses->ses_lock); + if (ses->ses_status == SES_EXITING) { + spin_unlock(&ses->ses_lock); continue; - - spin_lock(&ses->chans[i].server->srv_lock); - if (ses->chans[i].server->tcpStatus != CifsExiting) - ses->chans[i].server->tcpStatus = CifsNeedReconnect; - spin_unlock(&ses->chans[i].server->srv_lock); + } + spin_lock(&ses->chan_lock); + for (i = 1; i < ses->chan_count; i++) { + nserver = ses->chans[i].server; + if (!nserver) + continue; + nserver->srv_count++; + list_add(&nserver->rlist, &reco); + } + spin_unlock(&ses->chan_lock); + spin_unlock(&ses->ses_lock); } - spin_unlock(&ses->chan_lock); } - spin_unlock(&cifs_tcp_ses_lock); + + list_for_each_entry_safe(server, nserver, &reco, rlist) { + list_del_init(&server->rlist); + set_need_reco(server); + cifs_put_tcp_session(server, 0); + } }
/*
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avadhut Naik avadhut.naik@amd.com
commit a3f3040657417aeadb9622c629d4a0c2693a0f93 upstream.
Each Chip-Select (CS) of a Unified Memory Controller (UMC) on AMD Zen-based SOCs has an Address Mask and a Secondary Address Mask register associated with it. The amd64_edac module logs DIMM sizes on a per-UMC per-CS granularity during init using these two registers.
Currently, the module primarily considers only the Address Mask register for computing DIMM sizes. The Secondary Address Mask register is only considered for odd CS. Additionally, if it has been considered, the Address Mask register is ignored altogether for that CS. For power-of-two DIMMs i.e. DIMMs whose total capacity is a power of two (32GB, 64GB, etc), this is not an issue since only the Address Mask register is used.
For non-power-of-two DIMMs i.e., DIMMs whose total capacity is not a power of two (48GB, 96GB, etc), however, the Secondary Address Mask register is used in conjunction with the Address Mask register. However, since the module only considers either of the two registers for a CS, the size computed by the module is incorrect. The Secondary Address Mask register is not considered for even CS, and the Address Mask register is not considered for odd CS.
Introduce a new helper function so that both Address Mask and Secondary Address Mask registers are considered, when valid, for computing DIMM sizes. Furthermore, also rename some variables for greater clarity.
Fixes: 81f5090db843 ("EDAC/amd64: Support asymmetric dual-rank DIMMs") Closes: https://lore.kernel.org/dbec22b6-00f2-498b-b70d-ab6f8a5ec87e@natrix.lt Reported-by: Žilvinas Žaltiena zilvinas@natrix.lt Signed-off-by: Avadhut Naik avadhut.naik@amd.com Signed-off-by: Borislav Petkov (AMD) bp@alien8.de Reviewed-by: Yazen Ghannam yazen.ghannam@amd.com Tested-by: Žilvinas Žaltiena zilvinas@natrix.lt Cc: stable@vger.kernel.org Link: https://lore.kernel.org/20250529205013.403450-1-avadhut.naik@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/edac/amd64_edac.c | 57 +++++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 21 deletions(-)
--- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -1209,7 +1209,9 @@ static int umc_get_cs_mode(int dimm, u8 if (csrow_enabled(2 * dimm + 1, ctrl, pvt)) cs_mode |= CS_ODD_PRIMARY;
- /* Asymmetric dual-rank DIMM support. */ + if (csrow_sec_enabled(2 * dimm, ctrl, pvt)) + cs_mode |= CS_EVEN_SECONDARY; + if (csrow_sec_enabled(2 * dimm + 1, ctrl, pvt)) cs_mode |= CS_ODD_SECONDARY;
@@ -1230,12 +1232,13 @@ static int umc_get_cs_mode(int dimm, u8 return cs_mode; }
-static int __addr_mask_to_cs_size(u32 addr_mask_orig, unsigned int cs_mode, - int csrow_nr, int dimm) +static int calculate_cs_size(u32 mask, unsigned int cs_mode) { - u32 msb, weight, num_zero_bits; - u32 addr_mask_deinterleaved; - int size = 0; + int msb, weight, num_zero_bits; + u32 deinterleaved_mask; + + if (!mask) + return 0;
/* * The number of zero bits in the mask is equal to the number of bits @@ -1248,19 +1251,30 @@ static int __addr_mask_to_cs_size(u32 ad * without swapping with the most significant bit. This can be handled * by keeping the MSB where it is and ignoring the single zero bit. */ - msb = fls(addr_mask_orig) - 1; - weight = hweight_long(addr_mask_orig); + msb = fls(mask) - 1; + weight = hweight_long(mask); num_zero_bits = msb - weight - !!(cs_mode & CS_3R_INTERLEAVE);
/* Take the number of zero bits off from the top of the mask. */ - addr_mask_deinterleaved = GENMASK_ULL(msb - num_zero_bits, 1); + deinterleaved_mask = GENMASK(msb - num_zero_bits, 1); + edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", deinterleaved_mask); + + return (deinterleaved_mask >> 2) + 1; +} + +static int __addr_mask_to_cs_size(u32 addr_mask, u32 addr_mask_sec, + unsigned int cs_mode, int csrow_nr, int dimm) +{ + int size;
edac_dbg(1, "CS%d DIMM%d AddrMasks:\n", csrow_nr, dimm); - edac_dbg(1, " Original AddrMask: 0x%x\n", addr_mask_orig); - edac_dbg(1, " Deinterleaved AddrMask: 0x%x\n", addr_mask_deinterleaved); + edac_dbg(1, " Primary AddrMask: 0x%x\n", addr_mask);
/* Register [31:1] = Address [39:9]. Size is in kBs here. */ - size = (addr_mask_deinterleaved >> 2) + 1; + size = calculate_cs_size(addr_mask, cs_mode); + + edac_dbg(1, " Secondary AddrMask: 0x%x\n", addr_mask_sec); + size += calculate_cs_size(addr_mask_sec, cs_mode);
/* Return size in MBs. */ return size >> 10; @@ -1269,8 +1283,8 @@ static int __addr_mask_to_cs_size(u32 ad static int umc_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, unsigned int cs_mode, int csrow_nr) { + u32 addr_mask = 0, addr_mask_sec = 0; int cs_mask_nr = csrow_nr; - u32 addr_mask_orig; int dimm, size = 0;
/* No Chip Selects are enabled. */ @@ -1308,13 +1322,13 @@ static int umc_addr_mask_to_cs_size(stru if (!pvt->flags.zn_regs_v2) cs_mask_nr >>= 1;
- /* Asymmetric dual-rank DIMM support. */ - if ((csrow_nr & 1) && (cs_mode & CS_ODD_SECONDARY)) - addr_mask_orig = pvt->csels[umc].csmasks_sec[cs_mask_nr]; - else - addr_mask_orig = pvt->csels[umc].csmasks[cs_mask_nr]; + if (cs_mode & (CS_EVEN_PRIMARY | CS_ODD_PRIMARY)) + addr_mask = pvt->csels[umc].csmasks[cs_mask_nr]; + + if (cs_mode & (CS_EVEN_SECONDARY | CS_ODD_SECONDARY)) + addr_mask_sec = pvt->csels[umc].csmasks_sec[cs_mask_nr];
- return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, dimm); + return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, dimm); }
static void umc_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl) @@ -3512,9 +3526,10 @@ static void gpu_get_err_info(struct mce static int gpu_addr_mask_to_cs_size(struct amd64_pvt *pvt, u8 umc, unsigned int cs_mode, int csrow_nr) { - u32 addr_mask_orig = pvt->csels[umc].csmasks[csrow_nr]; + u32 addr_mask = pvt->csels[umc].csmasks[csrow_nr]; + u32 addr_mask_sec = pvt->csels[umc].csmasks_sec[csrow_nr];
- return __addr_mask_to_cs_size(addr_mask_orig, cs_mode, csrow_nr, csrow_nr >> 1); + return __addr_mask_to_cs_size(addr_mask, addr_mask_sec, cs_mode, csrow_nr, csrow_nr >> 1); }
static void gpu_debug_display_dimm_sizes(struct amd64_pvt *pvt, u8 ctrl)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Li (Intel) xin@zytor.com
commit 5f465c148c61e876b6d6eacd8e8e365f2d47758f upstream.
Initialize DR6 by writing its architectural reset value to avoid incorrectly zeroing DR6 to clear DR6.BLD at boot time, which leads to a false bus lock detected warning.
The Intel SDM says:
1) Certain debug exceptions may clear bits 0-3 of DR6.
2) BLD induced #DB clears DR6.BLD and any other debug exception doesn't modify DR6.BLD.
3) RTM induced #DB clears DR6.RTM and any other debug exception sets DR6.RTM.
To avoid confusion in identifying debug exceptions, debug handlers should set DR6.BLD and DR6.RTM, and clear other DR6 bits before returning.
The DR6 architectural reset value 0xFFFF0FF0, already defined as macro DR6_RESERVED, satisfies these requirements, so just use it to reinitialize DR6 whenever needed.
Since clear_all_debug_regs() no longer zeros all debug registers, rename it to initialize_debug_regs() to better reflect its current behavior.
Since debug_read_clear_dr6() no longer clears DR6, rename it to debug_read_reset_dr6() to better reflect its current behavior.
Fixes: ebb1064e7c2e9 ("x86/traps: Handle #DB for bus lock") Reported-by: Sohil Mehta sohil.mehta@intel.com Suggested-by: H. Peter Anvin (Intel) hpa@zytor.com Signed-off-by: Xin Li (Intel) xin@zytor.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Reviewed-by: H. Peter Anvin (Intel) hpa@zytor.com Reviewed-by: Sohil Mehta sohil.mehta@intel.com Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Tested-by: Sohil Mehta sohil.mehta@intel.com Link: https://lore.kernel.org/lkml/06e68373-a92b-472e-8fd9-ba548119770c@intel.com/ Cc:stable@vger.kernel.org Link: https://lore.kernel.org/all/20250620231504.2676902-2-xin%40zytor.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/uapi/asm/debugreg.h | 21 ++++++++++++++++++++- arch/x86/kernel/cpu/common.c | 24 ++++++++++-------------- arch/x86/kernel/traps.c | 34 +++++++++++++++++++++------------- 3 files changed, 51 insertions(+), 28 deletions(-)
--- a/arch/x86/include/uapi/asm/debugreg.h +++ b/arch/x86/include/uapi/asm/debugreg.h @@ -15,7 +15,26 @@ which debugging register was responsible for the trap. The other bits are either reserved or not of interest to us. */
-/* Define reserved bits in DR6 which are always set to 1 */ +/* + * Define bits in DR6 which are set to 1 by default. + * + * This is also the DR6 architectural value following Power-up, Reset or INIT. + * + * Note, with the introduction of Bus Lock Detection (BLD) and Restricted + * Transactional Memory (RTM), the DR6 register has been modified: + * + * 1) BLD flag (bit 11) is no longer reserved to 1 if the CPU supports + * Bus Lock Detection. The assertion of a bus lock could clear it. + * + * 2) RTM flag (bit 16) is no longer reserved to 1 if the CPU supports + * restricted transactional memory. #DB occurred inside an RTM region + * could clear it. + * + * Apparently, DR6.BLD and DR6.RTM are active low bits. + * + * As a result, DR6_RESERVED is an incorrect name now, but it is kept for + * compatibility. + */ #define DR6_RESERVED (0xFFFF0FF0)
#define DR_TRAP0 (0x1) /* db0 */ --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -2205,20 +2205,16 @@ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard) #endif #endif
-/* - * Clear all 6 debug registers: - */ -static void clear_all_debug_regs(void) +static void initialize_debug_regs(void) { - int i; - - for (i = 0; i < 8; i++) { - /* Ignore db4, db5 */ - if ((i == 4) || (i == 5)) - continue; - - set_debugreg(0, i); - } + /* Control register first -- to make sure everything is disabled. */ + set_debugreg(0, 7); + set_debugreg(DR6_RESERVED, 6); + /* dr5 and dr4 don't exist */ + set_debugreg(0, 3); + set_debugreg(0, 2); + set_debugreg(0, 1); + set_debugreg(0, 0); }
#ifdef CONFIG_KGDB @@ -2379,7 +2375,7 @@ void cpu_init(void)
load_mm_ldt(&init_mm);
- clear_all_debug_regs(); + initialize_debug_regs(); dbg_restore_debug_regs();
doublefault_init_cpu_tss(); --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -1021,24 +1021,32 @@ static bool is_sysenter_singlestep(struc #endif }
-static __always_inline unsigned long debug_read_clear_dr6(void) +static __always_inline unsigned long debug_read_reset_dr6(void) { unsigned long dr6;
+ get_debugreg(dr6, 6); + dr6 ^= DR6_RESERVED; /* Flip to positive polarity */ + /* * The Intel SDM says: * - * Certain debug exceptions may clear bits 0-3. The remaining - * contents of the DR6 register are never cleared by the - * processor. To avoid confusion in identifying debug - * exceptions, debug handlers should clear the register before - * returning to the interrupted task. + * Certain debug exceptions may clear bits 0-3 of DR6. + * + * BLD induced #DB clears DR6.BLD and any other debug + * exception doesn't modify DR6.BLD. * - * Keep it simple: clear DR6 immediately. + * RTM induced #DB clears DR6.RTM and any other debug + * exception sets DR6.RTM. + * + * To avoid confusion in identifying debug exceptions, + * debug handlers should set DR6.BLD and DR6.RTM, and + * clear other DR6 bits before returning. + * + * Keep it simple: write DR6 with its architectural reset + * value 0xFFFF0FF0, defined as DR6_RESERVED, immediately. */ - get_debugreg(dr6, 6); set_debugreg(DR6_RESERVED, 6); - dr6 ^= DR6_RESERVED; /* Flip to positive polarity */
return dr6; } @@ -1238,13 +1246,13 @@ out: /* IST stack entry */ DEFINE_IDTENTRY_DEBUG(exc_debug) { - exc_debug_kernel(regs, debug_read_clear_dr6()); + exc_debug_kernel(regs, debug_read_reset_dr6()); }
/* User entry, runs on regular task stack */ DEFINE_IDTENTRY_DEBUG_USER(exc_debug) { - exc_debug_user(regs, debug_read_clear_dr6()); + exc_debug_user(regs, debug_read_reset_dr6()); }
#ifdef CONFIG_X86_FRED @@ -1263,7 +1271,7 @@ DEFINE_FREDENTRY_DEBUG(exc_debug) { /* * FRED #DB stores DR6 on the stack in the format which - * debug_read_clear_dr6() returns for the IDT entry points. + * debug_read_reset_dr6() returns for the IDT entry points. */ unsigned long dr6 = fred_event_data(regs);
@@ -1278,7 +1286,7 @@ DEFINE_FREDENTRY_DEBUG(exc_debug) /* 32 bit does not have separate entry points. */ DEFINE_IDTENTRY_RAW(exc_debug) { - unsigned long dr6 = debug_read_clear_dr6(); + unsigned long dr6 = debug_read_reset_dr6();
if (user_mode(regs)) exc_debug_user(regs, dr6);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor nathan@kernel.org
commit a55bc4ffc06d8c965a7d6f0a01ed0ed41380df28 upstream.
After commit 6f110a5e4f99 ("Disable SLUB_TINY for build testing"), which causes CONFIG_KASAN to be enabled in allmodconfig again, arm64 allmodconfig builds with older versions of clang (15 through 17) show an instance of -Wframe-larger-than (which breaks the build with CONFIG_WERROR=y):
drivers/staging/rtl8723bs/core/rtw_security.c:1287:5: error: stack frame size (2208) exceeds limit (2048) in 'rtw_aes_decrypt' [-Werror,-Wframe-larger-than] 1287 | u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) | ^
This comes from aes_decipher() being inlined in rtw_aes_decrypt(). Running the same build with CONFIG_FRAME_WARN=128 shows aes_cipher() also uses a decent amount of stack, just under the limit of 2048:
drivers/staging/rtl8723bs/core/rtw_security.c:864:19: warning: stack frame size (1952) exceeds limit (128) in 'aes_cipher' [-Wframe-larger-than] 864 | static signed int aes_cipher(u8 *key, uint hdrlen, | ^
-Rpass-analysis=stack-frame-layout only shows one large structure on the stack, which is the ctx variable inlined from aes128k128d(). A good number of the other variables come from the additional checks of fortified string routines, which are present in memset(), which both aes_cipher() and aes_decipher() use to initialize some temporary buffers. In this case, since the size is known at compile time, these additional checks should not result in any code generation changes but allmodconfig has several sanitizers enabled, which may make it harder for the compiler to eliminate the compile time checks and the variables that come about from them.
The memset() calls are just initializing these buffers to zero, so use '= {}' instead, which is used all over the kernel and does the exact same thing as memset() without the fortify checks, which drops the stack usage of these functions by a few hundred kilobytes.
drivers/staging/rtl8723bs/core/rtw_security.c:864:19: warning: stack frame size (1584) exceeds limit (128) in 'aes_cipher' [-Wframe-larger-than] 864 | static signed int aes_cipher(u8 *key, uint hdrlen, | ^ drivers/staging/rtl8723bs/core/rtw_security.c:1271:5: warning: stack frame size (1456) exceeds limit (128) in 'rtw_aes_decrypt' [-Wframe-larger-than] 1271 | u32 rtw_aes_decrypt(struct adapter *padapter, u8 *precvframe) | ^
Cc: stable@vger.kernel.org Fixes: 554c0a3abf21 ("staging: Add rtl8723bs sdio wifi driver") Signed-off-by: Nathan Chancellor nathan@kernel.org Reviewed-by: Dan Carpenter dan.carpenter@linaro.org Link: https://lore.kernel.org/r/20250609-rtl8723bs-fix-clang-arm64-wflt-v1-1-e2acc... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/staging/rtl8723bs/core/rtw_security.c | 44 ++++++++------------------ 1 file changed, 14 insertions(+), 30 deletions(-)
--- a/drivers/staging/rtl8723bs/core/rtw_security.c +++ b/drivers/staging/rtl8723bs/core/rtw_security.c @@ -868,29 +868,21 @@ static signed int aes_cipher(u8 *key, ui num_blocks, payload_index;
u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; + u8 mic_iv[16] = {}; + u8 mic_header1[16] = {}; + u8 mic_header2[16] = {}; + u8 ctr_preload[16] = {};
/* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; + u8 chain_buffer[16] = {}; + u8 aes_out[16] = {}; + u8 padded_buffer[16] = {}; u8 mic[8]; uint frtype = GetFrameType(pframe); uint frsubtype = GetFrameSubType(pframe);
frsubtype = frsubtype>>4;
- memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - if ((hdrlen == WLAN_HDR_A3_LEN) || (hdrlen == WLAN_HDR_A3_QOS_LEN)) a4_exists = 0; else @@ -1080,15 +1072,15 @@ static signed int aes_decipher(u8 *key, num_blocks, payload_index; signed int res = _SUCCESS; u8 pn_vector[6]; - u8 mic_iv[16]; - u8 mic_header1[16]; - u8 mic_header2[16]; - u8 ctr_preload[16]; + u8 mic_iv[16] = {}; + u8 mic_header1[16] = {}; + u8 mic_header2[16] = {}; + u8 ctr_preload[16] = {};
/* Intermediate Buffers */ - u8 chain_buffer[16]; - u8 aes_out[16]; - u8 padded_buffer[16]; + u8 chain_buffer[16] = {}; + u8 aes_out[16] = {}; + u8 padded_buffer[16] = {}; u8 mic[8];
uint frtype = GetFrameType(pframe); @@ -1096,14 +1088,6 @@ static signed int aes_decipher(u8 *key,
frsubtype = frsubtype>>4;
- memset((void *)mic_iv, 0, 16); - memset((void *)mic_header1, 0, 16); - memset((void *)mic_header2, 0, 16); - memset((void *)ctr_preload, 0, 16); - memset((void *)chain_buffer, 0, 16); - memset((void *)aes_out, 0, 16); - memset((void *)padded_buffer, 0, 16); - /* start to decrypt the payload */
num_blocks = (plen-8) / 16; /* plen including LLC, payload_length and mic) */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yao Zi ziyao@disroot.org
commit 09812134071b3941fb81def30b61ed36d3a5dfb5 upstream.
The 8250 binding before converting to json-schema states,
- clock-frequency : the input clock frequency for the UART or - clocks phandle to refer to the clk used as per Documentation/devicetree
for clock-related properties, where "or" indicates these properties shouldn't exist at the same time.
Additionally, the behavior of Linux's driver is strange when both clocks and clock-frequency are specified: it ignores clocks and obtains the frequency from clock-frequency, left the specified clocks unclaimed. It may even be disabled, which is undesired most of the time.
But "anyOf" doesn't prevent these two properties from coexisting, as it considers the object valid as long as there's at LEAST one match.
Let's switch to "oneOf" and disallows the other property if one exists, precisely matching the original binding and avoiding future confusion on the driver's behavior.
Fixes: e69f5dc623f9 ("dt-bindings: serial: Convert 8250 to json-schema") Cc: stable stable@kernel.org Signed-off-by: Yao Zi ziyao@disroot.org Reviewed-by: Conor Dooley conor.dooley@microchip.com Link: https://lore.kernel.org/r/20250623093445.62327-1-ziyao@disroot.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- Documentation/devicetree/bindings/serial/8250.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/Documentation/devicetree/bindings/serial/8250.yaml +++ b/Documentation/devicetree/bindings/serial/8250.yaml @@ -45,7 +45,7 @@ allOf: - ns16550 - ns16550a then: - anyOf: + oneOf: - required: [ clock-frequency ] - required: [ clocks ]
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aidan Stewart astewart@tektelic.com
commit d36f0e9a0002f04f4d6dd9be908d58fe5bd3a279 upstream.
Since in v6.8-rc1, the of_node symlink under tty devices is missing. This breaks any udev rules relying on this information.
Link the of_node information in the serial controller device with the parent defined in the device tree. This will also apply to the serial device which takes the serial controller as a parent device.
Fixes: b286f4e87e32 ("serial: core: Move tty and serdev to be children of serial core port device") Cc: stable@vger.kernel.org Signed-off-by: Aidan Stewart astewart@tektelic.com Link: https://lore.kernel.org/r/20250617164819.13912-1-astewart@tektelic.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/serial_base_bus.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/tty/serial/serial_base_bus.c +++ b/drivers/tty/serial/serial_base_bus.c @@ -72,6 +72,7 @@ static int serial_base_device_init(struc dev->parent = parent_dev; dev->bus = &serial_base_bus_type; dev->release = release; + device_set_of_node_from_dev(dev, parent_dev);
if (!serial_base_initialized) { dev_dbg(port->dev, "uart_add_one_port() called before arch_initcall()?\n");
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fabio Estevam festevam@gmail.com
commit f23c52aafb1675ab1d1f46914556d8e29cbbf7b3 upstream.
Commit 7a637784d517 ("serial: imx: reduce RX interrupt frequency") introduced a regression on the i.MX6UL EVK board. The issue can be reproduced with the following steps:
- Open vi on the board. - Paste a text file (~150 characters). - Save the file, then repeat the process. - Compare the sha256sum of the saved files.
The checksums do not match due to missing characters or entire lines.
Fix this by restoring the RXTL value to 1 when the UART is used as a console.
This ensures timely RX interrupts and reliable data reception in console mode.
With this change, pasted content is saved correctly, and checksums are always consistent.
Cc: stable stable@kernel.org Fixes: 7a637784d517 ("serial: imx: reduce RX interrupt frequency") Signed-off-by: Fabio Estevam festevam@gmail.com Reviewed-by: Stefan Wahren wahrenst@gmx.net Link: https://lore.kernel.org/r/20250619114617.2791939-1-festevam@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/imx.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
--- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -235,6 +235,7 @@ struct imx_port { enum imx_tx_state tx_state; struct hrtimer trigger_start_tx; struct hrtimer trigger_stop_tx; + unsigned int rxtl; };
struct imx_port_ucrs { @@ -1339,6 +1340,7 @@ static void imx_uart_clear_rx_errors(str
#define TXTL_DEFAULT 8 #define RXTL_DEFAULT 8 /* 8 characters or aging timer */ +#define RXTL_CONSOLE_DEFAULT 1 #define TXTL_DMA 8 /* DMA burst setting */ #define RXTL_DMA 9 /* DMA burst setting */
@@ -1457,7 +1459,7 @@ static void imx_uart_disable_dma(struct ucr1 &= ~(UCR1_RXDMAEN | UCR1_TXDMAEN | UCR1_ATDMAEN); imx_uart_writel(sport, ucr1, UCR1);
- imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
sport->dma_is_enabled = 0; } @@ -1482,7 +1484,12 @@ static int imx_uart_startup(struct uart_ return retval; }
- imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + if (uart_console(&sport->port)) + sport->rxtl = RXTL_CONSOLE_DEFAULT; + else + sport->rxtl = RXTL_DEFAULT; + + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
/* disable the DREN bit (Data Ready interrupt enable) before * requesting IRQs @@ -1948,7 +1955,7 @@ static int imx_uart_poll_init(struct uar if (retval) clk_disable_unprepare(sport->clk_ipg);
- imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
uart_port_lock_irqsave(&sport->port, &flags);
@@ -2040,7 +2047,7 @@ static int imx_uart_rs485_config(struct /* If the receiver trigger is 0, set it to a default value */ ufcr = imx_uart_readl(sport, UFCR); if ((ufcr & UFCR_RXTL_MASK) == 0) - imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl); imx_uart_start_rx(port); }
@@ -2302,7 +2309,7 @@ imx_uart_console_setup(struct console *c else imx_uart_console_get_options(sport, &baud, &parity, &bits);
- imx_uart_setup_ufcr(sport, TXTL_DEFAULT, RXTL_DEFAULT); + imx_uart_setup_ufcr(sport, TXTL_DEFAULT, sport->rxtl);
retval = uart_set_options(&sport->port, co, baud, parity, bits, flow);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frédéric Danis frederic.danis@collabora.com
commit 042bb9603c44620dce98717a2d23235ca57a00d7 upstream.
OBEX download from iPhone is currently slow due to small packet size used to transfer data which doesn't follow the MTU negotiated during L2CAP connection, i.e. 672 bytes instead of 32767:
< ACL Data TX: Handle 11 flags 0x00 dlen 12 L2CAP: Connection Request (0x02) ident 18 len 4 PSM: 4103 (0x1007) Source CID: 72
ACL Data RX: Handle 11 flags 0x02 dlen 16
L2CAP: Connection Response (0x03) ident 18 len 8 Destination CID: 14608 Source CID: 72 Result: Connection successful (0x0000) Status: No further information available (0x0000) < ACL Data TX: Handle 11 flags 0x00 dlen 27 L2CAP: Configure Request (0x04) ident 20 len 19 Destination CID: 14608 Flags: 0x0000 Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009
ACL Data RX: Handle 11 flags 0x02 dlen 26
L2CAP: Configure Request (0x04) ident 72 len 18 Destination CID: 72 Flags: 0x0000 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 0 Monitor timeout: 0 Maximum PDU size: 65527 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) < ACL Data TX: Handle 11 flags 0x00 dlen 29 L2CAP: Configure Response (0x05) ident 72 len 21 Source CID: 14608 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 672 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009
ACL Data RX: Handle 11 flags 0x02 dlen 32
L2CAP: Configure Response (0x05) ident 20 len 24 Source CID: 72 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) ...
ACL Data RX: Handle 11 flags 0x02 dlen 680
Channel: 72 len 676 ctrl 0x0202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Unsegmented TxSeq 1 ReqSeq 2 < ACL Data TX: Handle 11 flags 0x00 dlen 13 Channel: 14608 len 9 ctrl 0x0204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Unsegmented TxSeq 2 ReqSeq 2
ACL Data RX: Handle 11 flags 0x02 dlen 680
Channel: 72 len 676 ctrl 0x0304 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Unsegmented TxSeq 2 ReqSeq 3
The MTUs are negotiated for each direction. In this traces 32767 for iPhone->localhost and no MTU for localhost->iPhone, which based on '4.4 L2CAP_CONFIGURATION_REQ' (Core specification v5.4, Vol. 3, Part A):
The only parameters that should be included in the L2CAP_CONFIGURATION_REQ packet are those that require different values than the default or previously agreed values. ... Any missing configuration parameters are assumed to have their most recently explicitly or implicitly accepted values.
and '5.1 Maximum transmission unit (MTU)':
If the remote device sends a positive L2CAP_CONFIGURATION_RSP packet it should include the actual MTU to be used on this channel for traffic flowing into the local device. ... The default value is 672 octets.
is set by BlueZ to 672 bytes.
It seems that the iPhone used the lowest negotiated value to transfer data to the localhost instead of the negotiated one for the incoming direction.
This could be fixed by using the MTU negotiated for the other direction, if exists, in the L2CAP_CONFIGURATION_RSP. This allows to use segmented packets as in the following traces:
< ACL Data TX: Handle 11 flags 0x00 dlen 12 L2CAP: Connection Request (0x02) ident 22 len 4 PSM: 4103 (0x1007) Source CID: 72 < ACL Data TX: Handle 11 flags 0x00 dlen 27 L2CAP: Configure Request (0x04) ident 24 len 19 Destination CID: 2832 Flags: 0x0000 Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009
ACL Data RX: Handle 11 flags 0x02 dlen 26
L2CAP: Configure Request (0x04) ident 15 len 18 Destination CID: 72 Flags: 0x0000 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 0 Monitor timeout: 0 Maximum PDU size: 65527 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) < ACL Data TX: Handle 11 flags 0x00 dlen 29 L2CAP: Configure Response (0x05) ident 15 len 21 Source CID: 2832 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 32 Max transmit: 255 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009
ACL Data RX: Handle 11 flags 0x02 dlen 32
L2CAP: Configure Response (0x05) ident 24 len 24 Source CID: 72 Flags: 0x0000 Result: Success (0x0000) Option: Maximum Transmission Unit (0x01) [mandatory] MTU: 32767 Option: Retransmission and Flow Control (0x04) [mandatory] Mode: Enhanced Retransmission (0x03) TX window size: 63 Max transmit: 3 Retransmission timeout: 2000 Monitor timeout: 12000 Maximum PDU size: 1009 Option: Frame Check Sequence (0x05) [mandatory] FCS: 16-bit FCS (0x01) ...
ACL Data RX: Handle 11 flags 0x02 dlen 1009
Channel: 72 len 1005 ctrl 0x4202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Start (len 21884) TxSeq 1 ReqSeq 2
ACL Data RX: Handle 11 flags 0x02 dlen 1009
Channel: 72 len 1005 ctrl 0xc204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} I-frame: Continuation TxSeq 2 ReqSeq 2
This has been tested with kernel 5.4 and BlueZ 5.77.
Cc: stable@vger.kernel.org Signed-off-by: Frédéric Danis frederic.danis@collabora.com Signed-off-by: Luiz Augusto von Dentz luiz.von.dentz@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/bluetooth/l2cap_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
--- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c @@ -3415,7 +3415,7 @@ static int l2cap_parse_conf_req(struct l struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; struct l2cap_conf_efs efs; u8 remote_efs = 0; - u16 mtu = L2CAP_DEFAULT_MTU; + u16 mtu = 0; u16 result = L2CAP_CONF_SUCCESS; u16 size;
@@ -3520,6 +3520,13 @@ done: /* Configure output options and let the other side know * which ones we don't like. */
+ /* If MTU is not provided in configure request, use the most recently + * explicitly or implicitly accepted value for the other direction, + * or the default value. + */ + if (mtu == 0) + mtu = chan->imtu ? chan->imtu : L2CAP_DEFAULT_MTU; + if (mtu < L2CAP_DEFAULT_MIN_MTU) result = L2CAP_CONF_UNACCEPT; else {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heinz Mauelshagen heinzm@redhat.com
commit db53805156f1e0aa6d059c0d3f9ac660d4ef3eb4 upstream.
Replace "rdev" with correct loop variable name "r".
Signed-off-by: Heinz Mauelshagen heinzm@redhat.com Cc: stable@vger.kernel.org Fixes: 63c32ed4afc2 ("dm raid: add raid4/5/6 journaling support") Signed-off-by: Mikulas Patocka mpatocka@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/dm-raid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -2410,7 +2410,7 @@ static int super_init_validation(struct */ sb_retrieve_failed_devices(sb, failed_devices); rdev_for_each(r, mddev) { - if (test_bit(Journal, &rdev->flags) || + if (test_bit(Journal, &r->flags) || !r->sb_page) continue; sb2 = page_address(r->sb_page);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuan-Wei Chiu visitorckw@gmail.com
commit 95b2e31e1752494d477c5da89d6789f769b0d67b upstream.
After reverting the transition to the generic min heap library, bcache no longer depends on MIN_HEAP. The select entry can be removed to reduce code size and shrink the kernel's attack surface.
This change effectively reverts the bcache-related part of commit 92a8b224b833 ("lib/min_heap: introduce non-inline versions of min heap API functions").
This is part of a series of changes to address a performance regression caused by the use of the generic min_heap implementation.
As reported by Robert, bcache now suffers from latency spikes, with P100 (max) latency increasing from 600 ms to 2.4 seconds every 5 minutes. These regressions degrade bcache's effectiveness as a low-latency cache layer and lead to frequent timeouts and application stalls in production environments.
Link: https://lore.kernel.org/lkml/CAJhEC05+0S69z+3+FB2Cd0hD+pCRyWTKLEOsc8BOmH73p1... Link: https://lkml.kernel.org/r/20250614202353.1632957-4-visitorckw@gmail.com Fixes: 866898efbb25 ("bcache: remove heap-related macros and switch to generic min_heap") Fixes: 92a8b224b833 ("lib/min_heap: introduce non-inline versions of min heap API functions") Signed-off-by: Kuan-Wei Chiu visitorckw@gmail.com Reported-by: Robert Pang robertpang@google.com Closes: https://lore.kernel.org/linux-bcache/CAJhEC06F_AtrPgw2-7CvCqZgeStgCtitbD-ryu... Acked-by: Coly Li colyli@kernel.org Cc: Ching-Chun (Jim) Huang jserv@ccns.ncku.edu.tw Cc: Kent Overstreet kent.overstreet@linux.dev Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/Kconfig | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/md/bcache/Kconfig +++ b/drivers/md/bcache/Kconfig @@ -5,7 +5,6 @@ config BCACHE select BLOCK_HOLDER_DEPRECATED if SYSFS select CRC64 select CLOSURES - select MIN_HEAP help Allows a block device to be used as cache for other devices; uses a btree for indexing and the layout is optimized for SSDs.
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana fdmanana@suse.com
commit 3ca864de852bc91007b32d2a0d48993724f4abad upstream.
We have a race between a rename and directory inode logging that if it happens and we crash/power fail before the rename completes, the next time the filesystem is mounted, the log replay code will end up deleting the file that was being renamed.
This is best explained following a step by step analysis of an interleaving of steps that lead into this situation.
Consider the initial conditions:
1) We are at transaction N;
2) We have directories A and B created in a past transaction (< N);
3) We have inode X corresponding to a file that has 2 hardlinks, one in directory A and the other in directory B, so we'll name them as "A/foo_link1" and "B/foo_link2". Both hard links were persisted in a past transaction (< N);
4) We have inode Y corresponding to a file that as a single hard link and is located in directory A, we'll name it as "A/bar". This file was also persisted in a past transaction (< N).
The steps leading to a file loss are the following and for all of them we are under transaction N:
1) Link "A/foo_link1" is removed, so inode's X last_unlink_trans field is updated to N, through btrfs_unlink() -> btrfs_record_unlink_dir();
2) Task A starts a rename for inode Y, with the goal of renaming from "A/bar" to "A/baz", so we enter btrfs_rename();
3) Task A inserts the new BTRFS_INODE_REF_KEY for inode Y by calling btrfs_insert_inode_ref();
4) Because the rename happens in the same directory, we don't set the last_unlink_trans field of directoty A's inode to the current transaction id, that is, we don't cal btrfs_record_unlink_dir();
5) Task A then removes the entries from directory A (BTRFS_DIR_ITEM_KEY and BTRFS_DIR_INDEX_KEY items) when calling __btrfs_unlink_inode() (actually the dir index item is added as a delayed item, but the effect is the same);
6) Now before task A adds the new entry "A/baz" to directory A by calling btrfs_add_link(), another task, task B is logging inode X;
7) Task B starts a fsync of inode X and after logging inode X, at btrfs_log_inode_parent() it calls btrfs_log_all_parents(), since inode X has a last_unlink_trans value of N, set at in step 1;
8) At btrfs_log_all_parents() we search for all parent directories of inode X using the commit root, so we find directories A and B and log them. Bu when logging direct A, we don't have a dir index item for inode Y anymore, neither the old name "A/bar" nor for the new name "A/baz" since the rename has deleted the old name but has not yet inserted the new name - task A hasn't called yet btrfs_add_link() to do that.
Note that logging directory A doesn't fallback to a transaction commit because its last_unlink_trans has a lower value than the current transaction's id (see step 4);
9) Task B finishes logging directories A and B and gets back to btrfs_sync_file() where it calls btrfs_sync_log() to persist the log tree;
10) Task B successfully persisted the log tree, btrfs_sync_log() completed with success, and a power failure happened.
We have a log tree without any directory entry for inode Y, so the log replay code deletes the entry for inode Y, name "A/bar", from the subvolume tree since it doesn't exist in the log tree and the log tree is authorative for its index (we logged a BTRFS_DIR_LOG_INDEX_KEY item that covers the index range for the dentry that corresponds to "A/bar").
Since there's no other hard link for inode Y and the log replay code deletes the name "A/bar", the file is lost.
The issue wouldn't happen if task B synced the log only after task A called btrfs_log_new_name(), which would update the log with the new name for inode Y ("A/bar").
Fix this by pinning the log root during renames before removing the old directory entry, and unpinning after btrfs_log_new_name() is called.
Fixes: 259c4b96d78d ("btrfs: stop doing unnecessary log updates during a rename") CC: stable@vger.kernel.org # 5.18+ Reviewed-by: Boris Burkov boris@bur.io Signed-off-by: Filipe Manana fdmanana@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/inode.c | 81 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 64 insertions(+), 17 deletions(-)
--- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7979,6 +7979,7 @@ static int btrfs_rename_exchange(struct int ret; int ret2; bool need_abort = false; + bool logs_pinned = false; struct fscrypt_name old_fname, new_fname; struct fscrypt_str *old_name, *new_name;
@@ -8102,6 +8103,31 @@ static int btrfs_rename_exchange(struct inode_inc_iversion(new_inode); simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
+ if (old_ino != BTRFS_FIRST_FREE_OBJECTID && + new_ino != BTRFS_FIRST_FREE_OBJECTID) { + /* + * If we are renaming in the same directory (and it's not for + * root entries) pin the log early to prevent any concurrent + * task from logging the directory after we removed the old + * entries and before we add the new entries, otherwise that + * task can sync a log without any entry for the inodes we are + * renaming and therefore replaying that log, if a power failure + * happens after syncing the log, would result in deleting the + * inodes. + * + * If the rename affects two different directories, we want to + * make sure the that there's no log commit that contains + * updates for only one of the directories but not for the + * other. + * + * If we are renaming an entry for a root, we don't care about + * log updates since we called btrfs_set_log_full_commit(). + */ + btrfs_pin_log_trans(root); + btrfs_pin_log_trans(dest); + logs_pinned = true; + } + if (old_dentry->d_parent != new_dentry->d_parent) { btrfs_record_unlink_dir(trans, BTRFS_I(old_dir), BTRFS_I(old_inode), true); @@ -8173,30 +8199,23 @@ static int btrfs_rename_exchange(struct BTRFS_I(new_inode)->dir_index = new_idx;
/* - * Now pin the logs of the roots. We do it to ensure that no other task - * can sync the logs while we are in progress with the rename, because - * that could result in an inconsistency in case any of the inodes that - * are part of this rename operation were logged before. + * Do the log updates for all inodes. + * + * If either entry is for a root we don't need to update the logs since + * we've called btrfs_set_log_full_commit() before. */ - if (old_ino != BTRFS_FIRST_FREE_OBJECTID) - btrfs_pin_log_trans(root); - if (new_ino != BTRFS_FIRST_FREE_OBJECTID) - btrfs_pin_log_trans(dest); - - /* Do the log updates for all inodes. */ - if (old_ino != BTRFS_FIRST_FREE_OBJECTID) + if (logs_pinned) { btrfs_log_new_name(trans, old_dentry, BTRFS_I(old_dir), old_rename_ctx.index, new_dentry->d_parent); - if (new_ino != BTRFS_FIRST_FREE_OBJECTID) btrfs_log_new_name(trans, new_dentry, BTRFS_I(new_dir), new_rename_ctx.index, old_dentry->d_parent); + }
- /* Now unpin the logs. */ - if (old_ino != BTRFS_FIRST_FREE_OBJECTID) +out_fail: + if (logs_pinned) { btrfs_end_log_trans(root); - if (new_ino != BTRFS_FIRST_FREE_OBJECTID) btrfs_end_log_trans(dest); -out_fail: + } ret2 = btrfs_end_transaction(trans); ret = ret ? ret : ret2; out_notrans: @@ -8246,6 +8265,7 @@ static int btrfs_rename(struct mnt_idmap int ret2; u64 old_ino = btrfs_ino(BTRFS_I(old_inode)); struct fscrypt_name old_fname, new_fname; + bool logs_pinned = false;
if (btrfs_ino(BTRFS_I(new_dir)) == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) return -EPERM; @@ -8380,6 +8400,29 @@ static int btrfs_rename(struct mnt_idmap inode_inc_iversion(old_inode); simple_rename_timestamp(old_dir, old_dentry, new_dir, new_dentry);
+ if (old_ino != BTRFS_FIRST_FREE_OBJECTID) { + /* + * If we are renaming in the same directory (and it's not a + * root entry) pin the log to prevent any concurrent task from + * logging the directory after we removed the old entry and + * before we add the new entry, otherwise that task can sync + * a log without any entry for the inode we are renaming and + * therefore replaying that log, if a power failure happens + * after syncing the log, would result in deleting the inode. + * + * If the rename affects two different directories, we want to + * make sure the that there's no log commit that contains + * updates for only one of the directories but not for the + * other. + * + * If we are renaming an entry for a root, we don't care about + * log updates since we called btrfs_set_log_full_commit(). + */ + btrfs_pin_log_trans(root); + btrfs_pin_log_trans(dest); + logs_pinned = true; + } + if (old_dentry->d_parent != new_dentry->d_parent) btrfs_record_unlink_dir(trans, BTRFS_I(old_dir), BTRFS_I(old_inode), true); @@ -8444,7 +8487,7 @@ static int btrfs_rename(struct mnt_idmap if (old_inode->i_nlink == 1) BTRFS_I(old_inode)->dir_index = index;
- if (old_ino != BTRFS_FIRST_FREE_OBJECTID) + if (logs_pinned) btrfs_log_new_name(trans, old_dentry, BTRFS_I(old_dir), rename_ctx.index, new_dentry->d_parent);
@@ -8460,6 +8503,10 @@ static int btrfs_rename(struct mnt_idmap } } out_fail: + if (logs_pinned) { + btrfs_end_log_trans(root); + btrfs_end_log_trans(dest); + } ret2 = btrfs_end_transaction(trans); ret = ret ? ret : ret2; out_notrans:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Harmstone maharmstone@fb.com
commit ae4477f937569d097ca5dbce92a89ba384b49bc6 upstream.
Each superblock contains a copy of the device item for that device. In a transaction which drops a chunk but doesn't create any new ones, we were correctly updating the device item in the chunk tree but not copying over the new bytes_used value to the superblock.
This can be seen by doing the following:
# dd if=/dev/zero of=test bs=4096 count=2621440 # mkfs.btrfs test # mount test /root/temp
# cd /root/temp # for i in {00..10}; do dd if=/dev/zero of=$i bs=4096 count=32768; done # sync # rm * # sync # btrfs balance start -dusage=0 . # sync
# cd # umount /root/temp # btrfs check test
For btrfs-check to detect this, you will also need my patch at https://github.com/kdave/btrfs-progs/pull/991.
Change btrfs_remove_dev_extents() so that it adds the devices to the fs_info->post_commit_list if they're not there already. This causes btrfs_commit_device_sizes() to be called, which updates the bytes_used value in the superblock.
Fixes: bbbf7243d62d ("btrfs: combine device update operations during transaction commit") CC: stable@vger.kernel.org # 5.10+ Reviewed-by: Qu Wenruo wqu@suse.com Signed-off-by: Mark Harmstone maharmstone@fb.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/volumes.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -3281,6 +3281,12 @@ int btrfs_remove_chunk(struct btrfs_tran device->bytes_used - dev_extent_len); atomic64_add(dev_extent_len, &fs_info->free_chunk_space); btrfs_clear_space_info_full(fs_info); + + if (list_empty(&device->post_commit_list)) { + list_add_tail(&device->post_commit_list, + &trans->transaction->dev_update_list); + } + mutex_unlock(&fs_info->chunk_mutex); } }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana fdmanana@suse.com
commit 2dcf838cf5c2f0f4501edaa1680fcad03618d760 upstream.
In a few places where we call read_one_inode(), if we get a NULL pointer we end up jumping into an error path, or fallthrough in case of __add_inode_ref(), where we then do something like this:
iput(&inode->vfs_inode);
which results in an invalid inode pointer that triggers an invalid memory access, resulting in a crash.
Fix this by making sure we don't do such dereferences.
Fixes: b4c50cbb01a1 ("btrfs: return a btrfs_inode from read_one_inode()") CC: stable@vger.kernel.org # 6.15+ Signed-off-by: Filipe Manana fdmanana@suse.com Reviewed-by: David Sterba dsterba@suse.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/btrfs/tree-log.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 97e933113b82..21d2f3dded51 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c @@ -668,15 +668,12 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, extent_end = ALIGN(start + size, fs_info->sectorsize); } else { - ret = 0; - goto out; + return 0; }
inode = read_one_inode(root, key->objectid); - if (!inode) { - ret = -EIO; - goto out; - } + if (!inode) + return -EIO;
/* * first check to see if we already have this extent in the @@ -961,7 +958,8 @@ static noinline int drop_one_dir_item(struct btrfs_trans_handle *trans, ret = unlink_inode_for_log_replay(trans, dir, inode, &name); out: kfree(name.name); - iput(&inode->vfs_inode); + if (inode) + iput(&inode->vfs_inode); return ret; }
@@ -1176,8 +1174,8 @@ static inline int __add_inode_ref(struct btrfs_trans_handle *trans, ret = unlink_inode_for_log_replay(trans, victim_parent, inode, &victim_name); + iput(&victim_parent->vfs_inode); } - iput(&victim_parent->vfs_inode); kfree(victim_name.name); if (ret) return ret;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuan-Wei Chiu visitorckw@gmail.com
commit 845f1f2d69f3f49b3d8c142265952c8257e3368c upstream.
Patch series "bcache: Revert min_heap migration due to performance regression".
This patch series reverts the migration of bcache from its original heap implementation to the generic min_heap library. While the original change aimed to simplify the code and improve maintainability, it introduced a severe performance regression in real-world scenarios.
As reported by Robert, systems using bcache now suffer from periodic latency spikes, with P100 (max) latency increasing from 600 ms to 2.4 seconds every 5 minutes. This degrades bcache's value as a low-latency caching layer, and leads to frequent timeouts and application stalls in production environments.
The primary cause of this regression is the behavior of the generic min_heap implementation's bottom-up sift_down, which performs up to 2 * log2(n) comparisons when many elements are equal. The original top-down variant used by bcache only required O(1) comparisons in such cases. The issue was further exacerbated by commit 92a8b224b833 ("lib/min_heap: introduce non-inline versions of min heap API functions"), which introduced non-inlined versions of the min_heap API, adding function call overhead to a performance-critical hot path.
This patch (of 3):
This reverts commit 3d8a9a1c35227c3f1b0bd132c9f0a80dbda07b65.
Although removing the custom swap function simplified the code, this change is part of a broader migration to the generic min_heap API that introduced significant performance regressions in bcache.
As reported by Robert, bcache now suffers from latency spikes, with P100 (max) latency increasing from 600 ms to 2.4 seconds every 5 minutes. These regressions degrade bcache's effectiveness as a low-latency cache layer and lead to frequent timeouts and application stalls in production environments.
This revert is part of a series of changes to restore previous performance by undoing the min_heap transition.
Link: https://lkml.kernel.org/r/20250614202353.1632957-1-visitorckw@gmail.com Link: https://lore.kernel.org/lkml/CAJhEC05+0S69z+3+FB2Cd0hD+pCRyWTKLEOsc8BOmH73p1... Link: https://lkml.kernel.org/r/20250614202353.1632957-2-visitorckw@gmail.com Fixes: 866898efbb25 ("bcache: remove heap-related macros and switch to generic min_heap") Fixes: 92a8b224b833 ("lib/min_heap: introduce non-inline versions of min heap API functions") Signed-off-by: Kuan-Wei Chiu visitorckw@gmail.com Reported-by: Robert Pang robertpang@google.com Closes: https://lore.kernel.org/linux-bcache/CAJhEC06F_AtrPgw2-7CvCqZgeStgCtitbD-ryu... Acked-by: Coly Li colyli@kernel.org Cc: Ching-Chun (Jim) Huang jserv@ccns.ncku.edu.tw Cc: Kent Overstreet kent.overstreet@linux.dev Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/alloc.c | 11 +++++++++-- drivers/md/bcache/bset.c | 14 +++++++++++--- drivers/md/bcache/extents.c | 10 +++++++++- drivers/md/bcache/movinggc.c | 10 +++++++++- 4 files changed, 38 insertions(+), 7 deletions(-)
diff --git a/drivers/md/bcache/alloc.c b/drivers/md/bcache/alloc.c index 8998e61efa40..da50f6661bae 100644 --- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -189,16 +189,23 @@ static inline bool new_bucket_min_cmp(const void *l, const void *r, void *args) return new_bucket_prio(ca, *lhs) < new_bucket_prio(ca, *rhs); }
+static inline void new_bucket_swap(void *l, void *r, void __always_unused *args) +{ + struct bucket **lhs = l, **rhs = r; + + swap(*lhs, *rhs); +} + static void invalidate_buckets_lru(struct cache *ca) { struct bucket *b; const struct min_heap_callbacks bucket_max_cmp_callback = { .less = new_bucket_max_cmp, - .swp = NULL, + .swp = new_bucket_swap, }; const struct min_heap_callbacks bucket_min_cmp_callback = { .less = new_bucket_min_cmp, - .swp = NULL, + .swp = new_bucket_swap, };
ca->heap.nr = 0; diff --git a/drivers/md/bcache/bset.c b/drivers/md/bcache/bset.c index 68258a16e125..bd97d8626887 100644 --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c @@ -1093,6 +1093,14 @@ static inline bool new_btree_iter_cmp(const void *l, const void *r, void __alway return bkey_cmp(_l->k, _r->k) <= 0; }
+static inline void new_btree_iter_swap(void *iter1, void *iter2, void __always_unused *args) +{ + struct btree_iter_set *_iter1 = iter1; + struct btree_iter_set *_iter2 = iter2; + + swap(*_iter1, *_iter2); +} + static inline bool btree_iter_end(struct btree_iter *iter) { return !iter->heap.nr; @@ -1103,7 +1111,7 @@ void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k, { const struct min_heap_callbacks callbacks = { .less = new_btree_iter_cmp, - .swp = NULL, + .swp = new_btree_iter_swap, };
if (k != end) @@ -1149,7 +1157,7 @@ static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter, struct bkey *ret = NULL; const struct min_heap_callbacks callbacks = { .less = cmp, - .swp = NULL, + .swp = new_btree_iter_swap, };
if (!btree_iter_end(iter)) { @@ -1223,7 +1231,7 @@ static void btree_mergesort(struct btree_keys *b, struct bset *out, : bch_ptr_invalid; const struct min_heap_callbacks callbacks = { .less = b->ops->sort_cmp, - .swp = NULL, + .swp = new_btree_iter_swap, };
/* Heapify the iterator, using our comparison function */ diff --git a/drivers/md/bcache/extents.c b/drivers/md/bcache/extents.c index 4b84fda1530a..a7221e5dbe81 100644 --- a/drivers/md/bcache/extents.c +++ b/drivers/md/bcache/extents.c @@ -266,12 +266,20 @@ static bool new_bch_extent_sort_cmp(const void *l, const void *r, void __always_ return !(c ? c > 0 : _l->k < _r->k); }
+static inline void new_btree_iter_swap(void *iter1, void *iter2, void __always_unused *args) +{ + struct btree_iter_set *_iter1 = iter1; + struct btree_iter_set *_iter2 = iter2; + + swap(*_iter1, *_iter2); +} + static struct bkey *bch_extent_sort_fixup(struct btree_iter *iter, struct bkey *tmp) { const struct min_heap_callbacks callbacks = { .less = new_bch_extent_sort_cmp, - .swp = NULL, + .swp = new_btree_iter_swap, }; while (iter->heap.nr > 1) { struct btree_iter_set *top = iter->heap.data, *i = top + 1; diff --git a/drivers/md/bcache/movinggc.c b/drivers/md/bcache/movinggc.c index 45ca134cbf02..d6c73dd8eb2b 100644 --- a/drivers/md/bcache/movinggc.c +++ b/drivers/md/bcache/movinggc.c @@ -190,6 +190,14 @@ static bool new_bucket_cmp(const void *l, const void *r, void __always_unused *a return GC_SECTORS_USED(*_l) >= GC_SECTORS_USED(*_r); }
+static void new_bucket_swap(void *l, void *r, void __always_unused *args) +{ + struct bucket **_l = l; + struct bucket **_r = r; + + swap(*_l, *_r); +} + static unsigned int bucket_heap_top(struct cache *ca) { struct bucket *b; @@ -204,7 +212,7 @@ void bch_moving_gc(struct cache_set *c) unsigned long sectors_to_move, reserve_sectors; const struct min_heap_callbacks callbacks = { .less = new_bucket_cmp, - .swp = NULL, + .swp = new_bucket_swap, };
if (!c->copy_gc_enabled)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuan-Wei Chiu visitorckw@gmail.com
commit 48fd7ebe00c1cdc782b42576548b25185902f64c upstream.
This reverts commit 866898efbb25bb44fd42848318e46db9e785973a.
The generic bottom-up min_heap implementation causes performance regression in invalidate_buckets_lru(), a hot path in bcache. Before the cache is fully populated, new_bucket_prio() often returns zero, leading to many equal comparisons. In such cases, bottom-up sift_down performs up to 2 * log2(n) comparisons, while the original top-down approach completes with just O() comparisons, resulting in a measurable performance gap.
The performance degradation is further worsened by the non-inlined min_heap API functions introduced in commit 92a8b224b833 ("lib/min_heap: introduce non-inline versions of min heap API functions"), adding function call overhead to this critical path.
As reported by Robert, bcache now suffers from latency spikes, with P100 (max) latency increasing from 600 ms to 2.4 seconds every 5 minutes. These regressions degrade bcache's effectiveness as a low-latency cache layer and lead to frequent timeouts and application stalls in production environments.
This revert aims to restore bcache's original low-latency behavior.
Link: https://lore.kernel.org/lkml/CAJhEC05+0S69z+3+FB2Cd0hD+pCRyWTKLEOsc8BOmH73p1... Link: https://lkml.kernel.org/r/20250614202353.1632957-3-visitorckw@gmail.com Fixes: 866898efbb25 ("bcache: remove heap-related macros and switch to generic min_heap") Fixes: 92a8b224b833 ("lib/min_heap: introduce non-inline versions of min heap API functions") Signed-off-by: Kuan-Wei Chiu visitorckw@gmail.com Reported-by: Robert Pang robertpang@google.com Closes: https://lore.kernel.org/linux-bcache/CAJhEC06F_AtrPgw2-7CvCqZgeStgCtitbD-ryu... Acked-by: Coly Li colyli@kernel.org Cc: Ching-Chun (Jim) Huang jserv@ccns.ncku.edu.tw Cc: Kent Overstreet kent.overstreet@linux.dev Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/md/bcache/alloc.c | 64 +++++---------------- drivers/md/bcache/bcache.h | 2 drivers/md/bcache/bset.c | 124 +++++++++++++++--------------------------- drivers/md/bcache/bset.h | 42 ++++++++------ drivers/md/bcache/btree.c | 69 +++++++++-------------- drivers/md/bcache/extents.c | 51 ++++++----------- drivers/md/bcache/movinggc.c | 41 +++---------- drivers/md/bcache/super.c | 3 - drivers/md/bcache/sysfs.c | 4 - drivers/md/bcache/util.h | 67 ++++++++++++++++++++++ drivers/md/bcache/writeback.c | 13 +--- 11 files changed, 217 insertions(+), 263 deletions(-)
--- a/drivers/md/bcache/alloc.c +++ b/drivers/md/bcache/alloc.c @@ -164,68 +164,40 @@ static void bch_invalidate_one_bucket(st * prio is worth 1/8th of what INITIAL_PRIO is worth. */
-static inline unsigned int new_bucket_prio(struct cache *ca, struct bucket *b) -{ - unsigned int min_prio = (INITIAL_PRIO - ca->set->min_prio) / 8; - - return (b->prio - ca->set->min_prio + min_prio) * GC_SECTORS_USED(b); -} - -static inline bool new_bucket_max_cmp(const void *l, const void *r, void *args) -{ - struct bucket **lhs = (struct bucket **)l; - struct bucket **rhs = (struct bucket **)r; - struct cache *ca = args; - - return new_bucket_prio(ca, *lhs) > new_bucket_prio(ca, *rhs); -} - -static inline bool new_bucket_min_cmp(const void *l, const void *r, void *args) -{ - struct bucket **lhs = (struct bucket **)l; - struct bucket **rhs = (struct bucket **)r; - struct cache *ca = args; - - return new_bucket_prio(ca, *lhs) < new_bucket_prio(ca, *rhs); -} - -static inline void new_bucket_swap(void *l, void *r, void __always_unused *args) -{ - struct bucket **lhs = l, **rhs = r; +#define bucket_prio(b) \ +({ \ + unsigned int min_prio = (INITIAL_PRIO - ca->set->min_prio) / 8; \ + \ + (b->prio - ca->set->min_prio + min_prio) * GC_SECTORS_USED(b); \ +})
- swap(*lhs, *rhs); -} +#define bucket_max_cmp(l, r) (bucket_prio(l) < bucket_prio(r)) +#define bucket_min_cmp(l, r) (bucket_prio(l) > bucket_prio(r))
static void invalidate_buckets_lru(struct cache *ca) { struct bucket *b; - const struct min_heap_callbacks bucket_max_cmp_callback = { - .less = new_bucket_max_cmp, - .swp = new_bucket_swap, - }; - const struct min_heap_callbacks bucket_min_cmp_callback = { - .less = new_bucket_min_cmp, - .swp = new_bucket_swap, - }; + ssize_t i;
- ca->heap.nr = 0; + ca->heap.used = 0;
for_each_bucket(b, ca) { if (!bch_can_invalidate_bucket(ca, b)) continue;
- if (!min_heap_full(&ca->heap)) - min_heap_push(&ca->heap, &b, &bucket_max_cmp_callback, ca); - else if (!new_bucket_max_cmp(&b, min_heap_peek(&ca->heap), ca)) { + if (!heap_full(&ca->heap)) + heap_add(&ca->heap, b, bucket_max_cmp); + else if (bucket_max_cmp(b, heap_peek(&ca->heap))) { ca->heap.data[0] = b; - min_heap_sift_down(&ca->heap, 0, &bucket_max_cmp_callback, ca); + heap_sift(&ca->heap, 0, bucket_max_cmp); } }
- min_heapify_all(&ca->heap, &bucket_min_cmp_callback, ca); + for (i = ca->heap.used / 2 - 1; i >= 0; --i) + heap_sift(&ca->heap, i, bucket_min_cmp);
while (!fifo_full(&ca->free_inc)) { - if (!ca->heap.nr) { + if (!heap_pop(&ca->heap, b, bucket_min_cmp)) { /* * We don't want to be calling invalidate_buckets() * multiple times when it can't do anything @@ -234,8 +206,6 @@ static void invalidate_buckets_lru(struc wake_up_gc(ca->set); return; } - b = min_heap_peek(&ca->heap)[0]; - min_heap_pop(&ca->heap, &bucket_min_cmp_callback, ca);
bch_invalidate_one_bucket(ca, b); } --- a/drivers/md/bcache/bcache.h +++ b/drivers/md/bcache/bcache.h @@ -458,7 +458,7 @@ struct cache { /* Allocation stuff: */ struct bucket *buckets;
- DEFINE_MIN_HEAP(struct bucket *, cache_heap) heap; + DECLARE_HEAP(struct bucket *, heap);
/* * If nonzero, we know we aren't going to find any buckets to invalidate --- a/drivers/md/bcache/bset.c +++ b/drivers/md/bcache/bset.c @@ -54,11 +54,9 @@ void bch_dump_bucket(struct btree_keys * int __bch_count_data(struct btree_keys *b) { unsigned int ret = 0; - struct btree_iter iter; + struct btree_iter_stack iter; struct bkey *k;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - if (b->ops->is_extents) for_each_key(b, k, &iter) ret += KEY_SIZE(k); @@ -69,11 +67,9 @@ void __bch_check_keys(struct btree_keys { va_list args; struct bkey *k, *p = NULL; - struct btree_iter iter; + struct btree_iter_stack iter; const char *err;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - for_each_key(b, k, &iter) { if (b->ops->is_extents) { err = "Keys out of order"; @@ -114,9 +110,9 @@ bug:
static void bch_btree_iter_next_check(struct btree_iter *iter) { - struct bkey *k = iter->heap.data->k, *next = bkey_next(k); + struct bkey *k = iter->data->k, *next = bkey_next(k);
- if (next < iter->heap.data->end && + if (next < iter->data->end && bkey_cmp(k, iter->b->ops->is_extents ? &START_KEY(next) : next) > 0) { bch_dump_bucket(iter->b); @@ -883,14 +879,12 @@ unsigned int bch_btree_insert_key(struct unsigned int status = BTREE_INSERT_STATUS_NO_INSERT; struct bset *i = bset_tree_last(b)->data; struct bkey *m, *prev = NULL; - struct btree_iter iter; + struct btree_iter_stack iter; struct bkey preceding_key_on_stack = ZERO_KEY; struct bkey *preceding_key_p = &preceding_key_on_stack;
BUG_ON(b->ops->is_extents && !KEY_SIZE(k));
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - /* * If k has preceding key, preceding_key_p will be set to address * of k's preceding key; otherwise preceding_key_p will be set @@ -901,9 +895,9 @@ unsigned int bch_btree_insert_key(struct else preceding_key(k, &preceding_key_p);
- m = bch_btree_iter_init(b, &iter, preceding_key_p); + m = bch_btree_iter_stack_init(b, &iter, preceding_key_p);
- if (b->ops->insert_fixup(b, k, &iter, replace_key)) + if (b->ops->insert_fixup(b, k, &iter.iter, replace_key)) return status;
status = BTREE_INSERT_STATUS_INSERT; @@ -1083,102 +1077,79 @@ struct bkey *__bch_bset_search(struct bt
/* Btree iterator */
-typedef bool (new_btree_iter_cmp_fn)(const void *, const void *, void *); - -static inline bool new_btree_iter_cmp(const void *l, const void *r, void __always_unused *args) -{ - const struct btree_iter_set *_l = l; - const struct btree_iter_set *_r = r; - - return bkey_cmp(_l->k, _r->k) <= 0; -} +typedef bool (btree_iter_cmp_fn)(struct btree_iter_set, + struct btree_iter_set);
-static inline void new_btree_iter_swap(void *iter1, void *iter2, void __always_unused *args) +static inline bool btree_iter_cmp(struct btree_iter_set l, + struct btree_iter_set r) { - struct btree_iter_set *_iter1 = iter1; - struct btree_iter_set *_iter2 = iter2; - - swap(*_iter1, *_iter2); + return bkey_cmp(l.k, r.k) > 0; }
static inline bool btree_iter_end(struct btree_iter *iter) { - return !iter->heap.nr; + return !iter->used; }
void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k, struct bkey *end) { - const struct min_heap_callbacks callbacks = { - .less = new_btree_iter_cmp, - .swp = new_btree_iter_swap, - }; - if (k != end) - BUG_ON(!min_heap_push(&iter->heap, - &((struct btree_iter_set) { k, end }), - &callbacks, - NULL)); + BUG_ON(!heap_add(iter, + ((struct btree_iter_set) { k, end }), + btree_iter_cmp)); }
-static struct bkey *__bch_btree_iter_init(struct btree_keys *b, - struct btree_iter *iter, - struct bkey *search, - struct bset_tree *start) +static struct bkey *__bch_btree_iter_stack_init(struct btree_keys *b, + struct btree_iter_stack *iter, + struct bkey *search, + struct bset_tree *start) { struct bkey *ret = NULL;
- iter->heap.size = ARRAY_SIZE(iter->heap.preallocated); - iter->heap.nr = 0; + iter->iter.size = ARRAY_SIZE(iter->stack_data); + iter->iter.used = 0;
#ifdef CONFIG_BCACHE_DEBUG - iter->b = b; + iter->iter.b = b; #endif
for (; start <= bset_tree_last(b); start++) { ret = bch_bset_search(b, start, search); - bch_btree_iter_push(iter, ret, bset_bkey_last(start->data)); + bch_btree_iter_push(&iter->iter, ret, bset_bkey_last(start->data)); }
return ret; }
-struct bkey *bch_btree_iter_init(struct btree_keys *b, - struct btree_iter *iter, +struct bkey *bch_btree_iter_stack_init(struct btree_keys *b, + struct btree_iter_stack *iter, struct bkey *search) { - return __bch_btree_iter_init(b, iter, search, b->set); + return __bch_btree_iter_stack_init(b, iter, search, b->set); }
static inline struct bkey *__bch_btree_iter_next(struct btree_iter *iter, - new_btree_iter_cmp_fn *cmp) + btree_iter_cmp_fn *cmp) { struct btree_iter_set b __maybe_unused; struct bkey *ret = NULL; - const struct min_heap_callbacks callbacks = { - .less = cmp, - .swp = new_btree_iter_swap, - };
if (!btree_iter_end(iter)) { bch_btree_iter_next_check(iter);
- ret = iter->heap.data->k; - iter->heap.data->k = bkey_next(iter->heap.data->k); + ret = iter->data->k; + iter->data->k = bkey_next(iter->data->k);
- if (iter->heap.data->k > iter->heap.data->end) { + if (iter->data->k > iter->data->end) { WARN_ONCE(1, "bset was corrupt!\n"); - iter->heap.data->k = iter->heap.data->end; + iter->data->k = iter->data->end; }
- if (iter->heap.data->k == iter->heap.data->end) { - if (iter->heap.nr) { - b = min_heap_peek(&iter->heap)[0]; - min_heap_pop(&iter->heap, &callbacks, NULL); - } - } + if (iter->data->k == iter->data->end) + heap_pop(iter, b, cmp); else - min_heap_sift_down(&iter->heap, 0, &callbacks, NULL); + heap_sift(iter, 0, cmp); }
return ret; @@ -1186,7 +1157,7 @@ static inline struct bkey *__bch_btree_i
struct bkey *bch_btree_iter_next(struct btree_iter *iter) { - return __bch_btree_iter_next(iter, new_btree_iter_cmp); + return __bch_btree_iter_next(iter, btree_iter_cmp);
}
@@ -1224,18 +1195,16 @@ static void btree_mergesort(struct btree struct btree_iter *iter, bool fixup, bool remove_stale) { + int i; struct bkey *k, *last = NULL; BKEY_PADDED(k) tmp; bool (*bad)(struct btree_keys *, const struct bkey *) = remove_stale ? bch_ptr_bad : bch_ptr_invalid; - const struct min_heap_callbacks callbacks = { - .less = b->ops->sort_cmp, - .swp = new_btree_iter_swap, - };
/* Heapify the iterator, using our comparison function */ - min_heapify_all(&iter->heap, &callbacks, NULL); + for (i = iter->used / 2 - 1; i >= 0; --i) + heap_sift(iter, i, b->ops->sort_cmp);
while (!btree_iter_end(iter)) { if (b->ops->sort_fixup && fixup) @@ -1324,11 +1293,10 @@ void bch_btree_sort_partial(struct btree struct bset_sort_state *state) { size_t order = b->page_order, keys = 0; - struct btree_iter iter; + struct btree_iter_stack iter; int oldsize = bch_count_data(b);
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - __bch_btree_iter_init(b, &iter, NULL, &b->set[start]); + __bch_btree_iter_stack_init(b, &iter, NULL, &b->set[start]);
if (start) { unsigned int i; @@ -1339,7 +1307,7 @@ void bch_btree_sort_partial(struct btree order = get_order(__set_bytes(b->set->data, keys)); }
- __btree_sort(b, &iter, start, order, false, state); + __btree_sort(b, &iter.iter, start, order, false, state);
EBUG_ON(oldsize >= 0 && bch_count_data(b) != oldsize); } @@ -1355,13 +1323,11 @@ void bch_btree_sort_into(struct btree_ke struct bset_sort_state *state) { uint64_t start_time = local_clock(); - struct btree_iter iter; - - min_heap_init(&iter.heap, NULL, MAX_BSETS); + struct btree_iter_stack iter;
- bch_btree_iter_init(b, &iter, NULL); + bch_btree_iter_stack_init(b, &iter, NULL);
- btree_mergesort(b, new->set->data, &iter, false, true); + btree_mergesort(b, new->set->data, &iter.iter, false, true);
bch_time_stats_update(&state->time, start_time);
--- a/drivers/md/bcache/bset.h +++ b/drivers/md/bcache/bset.h @@ -187,9 +187,8 @@ struct bset_tree { };
struct btree_keys_ops { - bool (*sort_cmp)(const void *l, - const void *r, - void *args); + bool (*sort_cmp)(struct btree_iter_set l, + struct btree_iter_set r); struct bkey *(*sort_fixup)(struct btree_iter *iter, struct bkey *tmp); bool (*insert_fixup)(struct btree_keys *b, @@ -313,17 +312,23 @@ enum { BTREE_INSERT_STATUS_FRONT_MERGE, };
-struct btree_iter_set { - struct bkey *k, *end; -}; - /* Btree key iteration */
struct btree_iter { + size_t size, used; #ifdef CONFIG_BCACHE_DEBUG struct btree_keys *b; #endif - MIN_HEAP_PREALLOCATED(struct btree_iter_set, btree_iter_heap, MAX_BSETS) heap; + struct btree_iter_set { + struct bkey *k, *end; + } data[]; +}; + +/* Fixed-size btree_iter that can be allocated on the stack */ + +struct btree_iter_stack { + struct btree_iter iter; + struct btree_iter_set stack_data[MAX_BSETS]; };
typedef bool (*ptr_filter_fn)(struct btree_keys *b, const struct bkey *k); @@ -335,9 +340,9 @@ struct bkey *bch_btree_iter_next_filter(
void bch_btree_iter_push(struct btree_iter *iter, struct bkey *k, struct bkey *end); -struct bkey *bch_btree_iter_init(struct btree_keys *b, - struct btree_iter *iter, - struct bkey *search); +struct bkey *bch_btree_iter_stack_init(struct btree_keys *b, + struct btree_iter_stack *iter, + struct bkey *search);
struct bkey *__bch_bset_search(struct btree_keys *b, struct bset_tree *t, const struct bkey *search); @@ -352,13 +357,14 @@ static inline struct bkey *bch_bset_sear return search ? __bch_bset_search(b, t, search) : t->data->start; }
-#define for_each_key_filter(b, k, iter, filter) \ - for (bch_btree_iter_init((b), (iter), NULL); \ - ((k) = bch_btree_iter_next_filter((iter), (b), filter));) - -#define for_each_key(b, k, iter) \ - for (bch_btree_iter_init((b), (iter), NULL); \ - ((k) = bch_btree_iter_next(iter));) +#define for_each_key_filter(b, k, stack_iter, filter) \ + for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \ + ((k) = bch_btree_iter_next_filter(&((stack_iter)->iter), (b), \ + filter));) + +#define for_each_key(b, k, stack_iter) \ + for (bch_btree_iter_stack_init((b), (stack_iter), NULL); \ + ((k) = bch_btree_iter_next(&((stack_iter)->iter)));)
/* Sorting */
--- a/drivers/md/bcache/btree.c +++ b/drivers/md/bcache/btree.c @@ -149,19 +149,19 @@ void bch_btree_node_read_done(struct btr { const char *err = "bad btree header"; struct bset *i = btree_bset_first(b); - struct btree_iter iter; + struct btree_iter *iter;
/* * c->fill_iter can allocate an iterator with more memory space * than static MAX_BSETS. * See the comment arount cache_set->fill_iter. */ - iter.heap.data = mempool_alloc(&b->c->fill_iter, GFP_NOIO); - iter.heap.size = b->c->cache->sb.bucket_size / b->c->cache->sb.block_size; - iter.heap.nr = 0; + iter = mempool_alloc(&b->c->fill_iter, GFP_NOIO); + iter->size = b->c->cache->sb.bucket_size / b->c->cache->sb.block_size; + iter->used = 0;
#ifdef CONFIG_BCACHE_DEBUG - iter.b = &b->keys; + iter->b = &b->keys; #endif
if (!i->seq) @@ -199,7 +199,7 @@ void bch_btree_node_read_done(struct btr if (i != b->keys.set[0].data && !i->keys) goto err;
- bch_btree_iter_push(&iter, i->start, bset_bkey_last(i)); + bch_btree_iter_push(iter, i->start, bset_bkey_last(i));
b->written += set_blocks(i, block_bytes(b->c->cache)); } @@ -211,7 +211,7 @@ void bch_btree_node_read_done(struct btr if (i->seq == b->keys.set[0].data->seq) goto err;
- bch_btree_sort_and_fix_extents(&b->keys, &iter, &b->c->sort); + bch_btree_sort_and_fix_extents(&b->keys, iter, &b->c->sort);
i = b->keys.set[0].data; err = "short btree key"; @@ -223,7 +223,7 @@ void bch_btree_node_read_done(struct btr bch_bset_init_next(&b->keys, write_block(b), bset_magic(&b->c->cache->sb)); out: - mempool_free(iter.heap.data, &b->c->fill_iter); + mempool_free(iter, &b->c->fill_iter); return; err: set_btree_node_io_error(b); @@ -1309,11 +1309,9 @@ static bool btree_gc_mark_node(struct bt uint8_t stale = 0; unsigned int keys = 0, good_keys = 0; struct bkey *k; - struct btree_iter iter; + struct btree_iter_stack iter; struct bset_tree *t;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - gc->nodes++;
for_each_key_filter(&b->keys, k, &iter, bch_ptr_invalid) { @@ -1572,11 +1570,9 @@ static int btree_gc_rewrite_node(struct static unsigned int btree_gc_count_keys(struct btree *b) { struct bkey *k; - struct btree_iter iter; + struct btree_iter_stack iter; unsigned int ret = 0;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - for_each_key_filter(&b->keys, k, &iter, bch_ptr_bad) ret += bkey_u64s(k);
@@ -1615,18 +1611,18 @@ static int btree_gc_recurse(struct btree int ret = 0; bool should_rewrite; struct bkey *k; - struct btree_iter iter; + struct btree_iter_stack iter; struct gc_merge_info r[GC_MERGE_NODES]; struct gc_merge_info *i, *last = r + ARRAY_SIZE(r) - 1;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - bch_btree_iter_init(&b->keys, &iter, &b->c->gc_done); + bch_btree_iter_stack_init(&b->keys, &iter, &b->c->gc_done);
for (i = r; i < r + ARRAY_SIZE(r); i++) i->b = ERR_PTR(-EINTR);
while (1) { - k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad); + k = bch_btree_iter_next_filter(&iter.iter, &b->keys, + bch_ptr_bad); if (k) { r->b = bch_btree_node_get(b->c, op, k, b->level - 1, true, b); @@ -1921,9 +1917,7 @@ static int bch_btree_check_recurse(struc { int ret = 0; struct bkey *k, *p = NULL; - struct btree_iter iter; - - min_heap_init(&iter.heap, NULL, MAX_BSETS); + struct btree_iter_stack iter;
for_each_key_filter(&b->keys, k, &iter, bch_ptr_invalid) bch_initial_mark_key(b->c, b->level, k); @@ -1931,10 +1925,10 @@ static int bch_btree_check_recurse(struc bch_initial_mark_key(b->c, b->level + 1, &b->key);
if (b->level) { - bch_btree_iter_init(&b->keys, &iter, NULL); + bch_btree_iter_stack_init(&b->keys, &iter, NULL);
do { - k = bch_btree_iter_next_filter(&iter, &b->keys, + k = bch_btree_iter_next_filter(&iter.iter, &b->keys, bch_ptr_bad); if (k) { btree_node_prefetch(b, k); @@ -1962,7 +1956,7 @@ static int bch_btree_check_thread(void * struct btree_check_info *info = arg; struct btree_check_state *check_state = info->state; struct cache_set *c = check_state->c; - struct btree_iter iter; + struct btree_iter_stack iter; struct bkey *k, *p; int cur_idx, prev_idx, skip_nr;
@@ -1970,11 +1964,9 @@ static int bch_btree_check_thread(void * cur_idx = prev_idx = 0; ret = 0;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - /* root node keys are checked before thread created */ - bch_btree_iter_init(&c->root->keys, &iter, NULL); - k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); + bch_btree_iter_stack_init(&c->root->keys, &iter, NULL); + k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); BUG_ON(!k);
p = k; @@ -1992,7 +1984,7 @@ static int bch_btree_check_thread(void * skip_nr = cur_idx - prev_idx;
while (skip_nr) { - k = bch_btree_iter_next_filter(&iter, + k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); if (k) @@ -2065,11 +2057,9 @@ int bch_btree_check(struct cache_set *c) int ret = 0; int i; struct bkey *k = NULL; - struct btree_iter iter; + struct btree_iter_stack iter; struct btree_check_state check_state;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - /* check and mark root node keys */ for_each_key_filter(&c->root->keys, k, &iter, bch_ptr_invalid) bch_initial_mark_key(c, c->root->level, k); @@ -2563,12 +2553,11 @@ static int bch_btree_map_nodes_recurse(s
if (b->level) { struct bkey *k; - struct btree_iter iter; + struct btree_iter_stack iter;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - bch_btree_iter_init(&b->keys, &iter, from); + bch_btree_iter_stack_init(&b->keys, &iter, from);
- while ((k = bch_btree_iter_next_filter(&iter, &b->keys, + while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys, bch_ptr_bad))) { ret = bcache_btree(map_nodes_recurse, k, b, op, from, fn, flags); @@ -2597,12 +2586,12 @@ int bch_btree_map_keys_recurse(struct bt { int ret = MAP_CONTINUE; struct bkey *k; - struct btree_iter iter; + struct btree_iter_stack iter;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - bch_btree_iter_init(&b->keys, &iter, from); + bch_btree_iter_stack_init(&b->keys, &iter, from);
- while ((k = bch_btree_iter_next_filter(&iter, &b->keys, bch_ptr_bad))) { + while ((k = bch_btree_iter_next_filter(&iter.iter, &b->keys, + bch_ptr_bad))) { ret = !b->level ? fn(op, b, k) : bcache_btree(map_keys_recurse, k, --- a/drivers/md/bcache/extents.c +++ b/drivers/md/bcache/extents.c @@ -33,16 +33,15 @@ static void sort_key_next(struct btree_i i->k = bkey_next(i->k);
if (i->k == i->end) - *i = iter->heap.data[--iter->heap.nr]; + *i = iter->data[--iter->used]; }
-static bool new_bch_key_sort_cmp(const void *l, const void *r, void *args) +static bool bch_key_sort_cmp(struct btree_iter_set l, + struct btree_iter_set r) { - struct btree_iter_set *_l = (struct btree_iter_set *)l; - struct btree_iter_set *_r = (struct btree_iter_set *)r; - int64_t c = bkey_cmp(_l->k, _r->k); + int64_t c = bkey_cmp(l.k, r.k);
- return !(c ? c > 0 : _l->k < _r->k); + return c ? c > 0 : l.k < r.k; }
static bool __ptr_invalid(struct cache_set *c, const struct bkey *k) @@ -239,7 +238,7 @@ static bool bch_btree_ptr_insert_fixup(s }
const struct btree_keys_ops bch_btree_keys_ops = { - .sort_cmp = new_bch_key_sort_cmp, + .sort_cmp = bch_key_sort_cmp, .insert_fixup = bch_btree_ptr_insert_fixup, .key_invalid = bch_btree_ptr_invalid, .key_bad = bch_btree_ptr_bad, @@ -256,36 +255,22 @@ const struct btree_keys_ops bch_btree_ke * Necessary for btree_sort_fixup() - if there are multiple keys that compare * equal in different sets, we have to process them newest to oldest. */ - -static bool new_bch_extent_sort_cmp(const void *l, const void *r, void __always_unused *args) -{ - struct btree_iter_set *_l = (struct btree_iter_set *)l; - struct btree_iter_set *_r = (struct btree_iter_set *)r; - int64_t c = bkey_cmp(&START_KEY(_l->k), &START_KEY(_r->k)); - - return !(c ? c > 0 : _l->k < _r->k); -} - -static inline void new_btree_iter_swap(void *iter1, void *iter2, void __always_unused *args) +static bool bch_extent_sort_cmp(struct btree_iter_set l, + struct btree_iter_set r) { - struct btree_iter_set *_iter1 = iter1; - struct btree_iter_set *_iter2 = iter2; + int64_t c = bkey_cmp(&START_KEY(l.k), &START_KEY(r.k));
- swap(*_iter1, *_iter2); + return c ? c > 0 : l.k < r.k; }
static struct bkey *bch_extent_sort_fixup(struct btree_iter *iter, struct bkey *tmp) { - const struct min_heap_callbacks callbacks = { - .less = new_bch_extent_sort_cmp, - .swp = new_btree_iter_swap, - }; - while (iter->heap.nr > 1) { - struct btree_iter_set *top = iter->heap.data, *i = top + 1; + while (iter->used > 1) { + struct btree_iter_set *top = iter->data, *i = top + 1;
- if (iter->heap.nr > 2 && - !new_bch_extent_sort_cmp(&i[0], &i[1], NULL)) + if (iter->used > 2 && + bch_extent_sort_cmp(i[0], i[1])) i++;
if (bkey_cmp(top->k, &START_KEY(i->k)) <= 0) @@ -293,7 +278,7 @@ static struct bkey *bch_extent_sort_fixu
if (!KEY_SIZE(i->k)) { sort_key_next(iter, i); - min_heap_sift_down(&iter->heap, i - top, &callbacks, NULL); + heap_sift(iter, i - top, bch_extent_sort_cmp); continue; }
@@ -303,7 +288,7 @@ static struct bkey *bch_extent_sort_fixu else bch_cut_front(top->k, i->k);
- min_heap_sift_down(&iter->heap, i - top, &callbacks, NULL); + heap_sift(iter, i - top, bch_extent_sort_cmp); } else { /* can't happen because of comparison func */ BUG_ON(!bkey_cmp(&START_KEY(top->k), &START_KEY(i->k))); @@ -313,7 +298,7 @@ static struct bkey *bch_extent_sort_fixu
bch_cut_back(&START_KEY(i->k), tmp); bch_cut_front(i->k, top->k); - min_heap_sift_down(&iter->heap, 0, &callbacks, NULL); + heap_sift(iter, 0, bch_extent_sort_cmp);
return tmp; } else { @@ -633,7 +618,7 @@ static bool bch_extent_merge(struct btre }
const struct btree_keys_ops bch_extent_keys_ops = { - .sort_cmp = new_bch_extent_sort_cmp, + .sort_cmp = bch_extent_sort_cmp, .sort_fixup = bch_extent_sort_fixup, .insert_fixup = bch_extent_insert_fixup, .key_invalid = bch_extent_invalid, --- a/drivers/md/bcache/movinggc.c +++ b/drivers/md/bcache/movinggc.c @@ -182,27 +182,16 @@ err: if (!IS_ERR_OR_NULL(w->private)) closure_sync(&cl); }
-static bool new_bucket_cmp(const void *l, const void *r, void __always_unused *args) +static bool bucket_cmp(struct bucket *l, struct bucket *r) { - struct bucket **_l = (struct bucket **)l; - struct bucket **_r = (struct bucket **)r; - - return GC_SECTORS_USED(*_l) >= GC_SECTORS_USED(*_r); -} - -static void new_bucket_swap(void *l, void *r, void __always_unused *args) -{ - struct bucket **_l = l; - struct bucket **_r = r; - - swap(*_l, *_r); + return GC_SECTORS_USED(l) < GC_SECTORS_USED(r); }
static unsigned int bucket_heap_top(struct cache *ca) { struct bucket *b;
- return (b = min_heap_peek(&ca->heap)[0]) ? GC_SECTORS_USED(b) : 0; + return (b = heap_peek(&ca->heap)) ? GC_SECTORS_USED(b) : 0; }
void bch_moving_gc(struct cache_set *c) @@ -210,10 +199,6 @@ void bch_moving_gc(struct cache_set *c) struct cache *ca = c->cache; struct bucket *b; unsigned long sectors_to_move, reserve_sectors; - const struct min_heap_callbacks callbacks = { - .less = new_bucket_cmp, - .swp = new_bucket_swap, - };
if (!c->copy_gc_enabled) return; @@ -224,7 +209,7 @@ void bch_moving_gc(struct cache_set *c) reserve_sectors = ca->sb.bucket_size * fifo_used(&ca->free[RESERVE_MOVINGGC]);
- ca->heap.nr = 0; + ca->heap.used = 0;
for_each_bucket(b, ca) { if (GC_MARK(b) == GC_MARK_METADATA || @@ -233,31 +218,25 @@ void bch_moving_gc(struct cache_set *c) atomic_read(&b->pin)) continue;
- if (!min_heap_full(&ca->heap)) { + if (!heap_full(&ca->heap)) { sectors_to_move += GC_SECTORS_USED(b); - min_heap_push(&ca->heap, &b, &callbacks, NULL); - } else if (!new_bucket_cmp(&b, min_heap_peek(&ca->heap), ca)) { + heap_add(&ca->heap, b, bucket_cmp); + } else if (bucket_cmp(b, heap_peek(&ca->heap))) { sectors_to_move -= bucket_heap_top(ca); sectors_to_move += GC_SECTORS_USED(b);
ca->heap.data[0] = b; - min_heap_sift_down(&ca->heap, 0, &callbacks, NULL); + heap_sift(&ca->heap, 0, bucket_cmp); } }
while (sectors_to_move > reserve_sectors) { - if (ca->heap.nr) { - b = min_heap_peek(&ca->heap)[0]; - min_heap_pop(&ca->heap, &callbacks, NULL); - } + heap_pop(&ca->heap, b, bucket_cmp); sectors_to_move -= GC_SECTORS_USED(b); }
- while (ca->heap.nr) { - b = min_heap_peek(&ca->heap)[0]; - min_heap_pop(&ca->heap, &callbacks, NULL); + while (heap_pop(&ca->heap, b, bucket_cmp)) SET_GC_MOVE(b, 1); - }
mutex_unlock(&c->bucket_lock);
--- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -1912,7 +1912,8 @@ struct cache_set *bch_cache_set_alloc(st INIT_LIST_HEAD(&c->btree_cache_freed); INIT_LIST_HEAD(&c->data_buckets);
- iter_size = ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size) * + iter_size = sizeof(struct btree_iter) + + ((meta_bucket_pages(sb) * PAGE_SECTORS) / sb->block_size) * sizeof(struct btree_iter_set);
c->devices = kcalloc(c->nr_uuids, sizeof(void *), GFP_KERNEL); --- a/drivers/md/bcache/sysfs.c +++ b/drivers/md/bcache/sysfs.c @@ -660,9 +660,7 @@ static unsigned int bch_root_usage(struc unsigned int bytes = 0; struct bkey *k; struct btree *b; - struct btree_iter iter; - - min_heap_init(&iter.heap, NULL, MAX_BSETS); + struct btree_iter_stack iter;
goto lock_root;
--- a/drivers/md/bcache/util.h +++ b/drivers/md/bcache/util.h @@ -9,7 +9,6 @@ #include <linux/kernel.h> #include <linux/sched/clock.h> #include <linux/llist.h> -#include <linux/min_heap.h> #include <linux/ratelimit.h> #include <linux/vmalloc.h> #include <linux/workqueue.h> @@ -31,10 +30,16 @@ struct closure;
#endif
+#define DECLARE_HEAP(type, name) \ + struct { \ + size_t size, used; \ + type *data; \ + } name + #define init_heap(heap, _size, gfp) \ ({ \ size_t _bytes; \ - (heap)->nr = 0; \ + (heap)->used = 0; \ (heap)->size = (_size); \ _bytes = (heap)->size * sizeof(*(heap)->data); \ (heap)->data = kvmalloc(_bytes, (gfp) & GFP_KERNEL); \ @@ -47,6 +52,64 @@ do { \ (heap)->data = NULL; \ } while (0)
+#define heap_swap(h, i, j) swap((h)->data[i], (h)->data[j]) + +#define heap_sift(h, i, cmp) \ +do { \ + size_t _r, _j = i; \ + \ + for (; _j * 2 + 1 < (h)->used; _j = _r) { \ + _r = _j * 2 + 1; \ + if (_r + 1 < (h)->used && \ + cmp((h)->data[_r], (h)->data[_r + 1])) \ + _r++; \ + \ + if (cmp((h)->data[_r], (h)->data[_j])) \ + break; \ + heap_swap(h, _r, _j); \ + } \ +} while (0) + +#define heap_sift_down(h, i, cmp) \ +do { \ + while (i) { \ + size_t p = (i - 1) / 2; \ + if (cmp((h)->data[i], (h)->data[p])) \ + break; \ + heap_swap(h, i, p); \ + i = p; \ + } \ +} while (0) + +#define heap_add(h, d, cmp) \ +({ \ + bool _r = !heap_full(h); \ + if (_r) { \ + size_t _i = (h)->used++; \ + (h)->data[_i] = d; \ + \ + heap_sift_down(h, _i, cmp); \ + heap_sift(h, _i, cmp); \ + } \ + _r; \ +}) + +#define heap_pop(h, d, cmp) \ +({ \ + bool _r = (h)->used; \ + if (_r) { \ + (d) = (h)->data[0]; \ + (h)->used--; \ + heap_swap(h, 0, (h)->used); \ + heap_sift(h, 0, cmp); \ + } \ + _r; \ +}) + +#define heap_peek(h) ((h)->used ? (h)->data[0] : NULL) + +#define heap_full(h) ((h)->used == (h)->size) + #define DECLARE_FIFO(type, name) \ struct { \ size_t front, back, size, mask; \ --- a/drivers/md/bcache/writeback.c +++ b/drivers/md/bcache/writeback.c @@ -908,16 +908,15 @@ static int bch_dirty_init_thread(void *a struct dirty_init_thrd_info *info = arg; struct bch_dirty_init_state *state = info->state; struct cache_set *c = state->c; - struct btree_iter iter; + struct btree_iter_stack iter; struct bkey *k, *p; int cur_idx, prev_idx, skip_nr;
k = p = NULL; prev_idx = 0;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - bch_btree_iter_init(&c->root->keys, &iter, NULL); - k = bch_btree_iter_next_filter(&iter, &c->root->keys, bch_ptr_bad); + bch_btree_iter_stack_init(&c->root->keys, &iter, NULL); + k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); BUG_ON(!k);
p = k; @@ -931,7 +930,7 @@ static int bch_dirty_init_thread(void *a skip_nr = cur_idx - prev_idx;
while (skip_nr) { - k = bch_btree_iter_next_filter(&iter, + k = bch_btree_iter_next_filter(&iter.iter, &c->root->keys, bch_ptr_bad); if (k) @@ -980,13 +979,11 @@ void bch_sectors_dirty_init(struct bcach int i; struct btree *b = NULL; struct bkey *k = NULL; - struct btree_iter iter; + struct btree_iter_stack iter; struct sectors_dirty_init op; struct cache_set *c = d->c; struct bch_dirty_init_state state;
- min_heap_init(&iter.heap, NULL, MAX_BSETS); - retry_lock: b = c->root; rw_lock(0, b, b->level);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephen Smalley stephen.smalley.work@gmail.com
commit fde46f60f6c5138ee422087addbc5bf5b4968bf1 upstream.
If the end result of a security_compute_sid() computation matches the ssid or tsid, return that SID rather than looking it up again. This avoids the problem of multiple initial SIDs that map to the same context.
Cc: stable@vger.kernel.org Reported-by: Guido Trentalancia guido@trentalancia.com Fixes: ae254858ce07 ("selinux: introduce an initial SID for early boot processes") Signed-off-by: Stephen Smalley stephen.smalley.work@gmail.com Tested-by: Guido Trentalancia guido@trentalancia.com Signed-off-by: Paul Moore paul@paul-moore.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- security/selinux/ss/services.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
--- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -1909,11 +1909,17 @@ retry: goto out_unlock; } /* Obtain the sid for the context. */ - rc = sidtab_context_to_sid(sidtab, &newcontext, out_sid); - if (rc == -ESTALE) { - rcu_read_unlock(); - context_destroy(&newcontext); - goto retry; + if (context_equal(scontext, &newcontext)) + *out_sid = ssid; + else if (context_equal(tcontext, &newcontext)) + *out_sid = tsid; + else { + rc = sidtab_context_to_sid(sidtab, &newcontext, out_sid); + if (rc == -ESTALE) { + rcu_read_unlock(); + context_destroy(&newcontext); + goto retry; + } } out_unlock: rcu_read_unlock();
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Khairul Anuar Romli khairul.anuar.romli@altera.com
commit b07f349d1864abe29436f45e3047da2bdd476462 upstream.
Having PM put sync in remove function is causing PM underflow during remove operation. This is caused by the function, runtime_pm_get_sync, not being called anywhere during the op. Ensure that calls to pm_runtime_enable()/pm_runtime_disable() and pm_runtime_get_sync()/pm_runtime_put_sync() match.
echo 108d2000.spi > /sys/bus/platform/drivers/cadence-qspi/unbind [ 49.644256] Deleting MTD partitions on "108d2000.spi.0": [ 49.649575] Deleting u-boot MTD partition [ 49.684087] Deleting root MTD partition [ 49.724188] cadence-qspi 108d2000.spi: Runtime PM usage count underflow!
Continuous bind/unbind will result in an "Unbalanced pm_runtime_enable" error. Subsequent unbind attempts will return a "No such device" error, while bind attempts will return a "Resource temporarily unavailable" error.
[ 47.592434] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 49.592233] cadence-qspi 108d2000.spi: detected FIFO depth (1024) different from config (128) [ 53.232309] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 55.828550] cadence-qspi 108d2000.spi: detected FIFO depth (1024) different from config (128) [ 57.940627] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 59.912490] cadence-qspi 108d2000.spi: detected FIFO depth (1024) different from config (128) [ 61.876243] cadence-qspi 108d2000.spi: Runtime PM usage count underflow! [ 61.883000] platform 108d2000.spi: Unbalanced pm_runtime_enable! [ 532.012270] cadence-qspi 108d2000.spi: probe with driver cadence-qspi failed1
Also, change clk_disable_unprepare() to clk_disable() since continuous bind and unbind operations will trigger a warning indicating that the clock is already unprepared.
Fixes: 4892b374c9b7 ("mtd: spi-nor: cadence-quadspi: Add runtime PM support") cc: stable@vger.kernel.org # 6.6+ Signed-off-by: Khairul Anuar Romli khairul.anuar.romli@altera.com Reviewed-by: Matthew Gerlach matthew.gerlach@altera.com Link: https://patch.msgid.link/4e7a4b8aba300e629b45a04f90bddf665fbdb335.1749601877... Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/spi/spi-cadence-quadspi.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
--- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c @@ -1958,10 +1958,10 @@ static int cqspi_probe(struct platform_d goto probe_setup_failed; }
- ret = devm_pm_runtime_enable(dev); - if (ret) { - if (cqspi->rx_chan) - dma_release_channel(cqspi->rx_chan); + pm_runtime_enable(dev); + + if (cqspi->rx_chan) { + dma_release_channel(cqspi->rx_chan); goto probe_setup_failed; }
@@ -1981,6 +1981,7 @@ static int cqspi_probe(struct platform_d return 0; probe_setup_failed: cqspi_controller_enable(cqspi, 0); + pm_runtime_disable(dev); probe_reset_failed: if (cqspi->is_jh7110) cqspi_jh7110_disable_clk(pdev, cqspi); @@ -1999,7 +2000,8 @@ static void cqspi_remove(struct platform if (cqspi->rx_chan) dma_release_channel(cqspi->rx_chan);
- clk_disable_unprepare(cqspi->clk); + if (pm_runtime_get_sync(&pdev->dev) >= 0) + clk_disable(cqspi->clk);
if (cqspi->is_jh7110) cqspi_jh7110_disable_clk(pdev, cqspi);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiawen Wu jiawenwu@trustnetic.com
commit 85720e04d9af0b77f8092b12a06661a8d459d4a0 upstream.
'rx_ring->size' means the count of ring descriptors multiplied by the size of one descriptor. When increasing the count of ring descriptors, it may exceed the limit of pool size.
[ 864.209610] page_pool_create_percpu() gave up with errno -7 [ 864.209613] txgbe 0000:11:00.0: Page pool creation failed: -7
Fix to set the pool_size to the count of ring descriptors.
Fixes: 850b971110b2 ("net: libwx: Allocate Rx and Tx resources") Cc: stable@vger.kernel.org Signed-off-by: Jiawen Wu jiawenwu@trustnetic.com Reviewed-by: Simon Horman horms@kernel.org Reviewed-by: Mina Almasry almasrymina@google.com Link: https://patch.msgid.link/434C72BFB40E350A+20250625023924.21821-1-jiawenwu@tr... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/wangxun/libwx/wx_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/ethernet/wangxun/libwx/wx_lib.c +++ b/drivers/net/ethernet/wangxun/libwx/wx_lib.c @@ -2496,7 +2496,7 @@ static int wx_alloc_page_pool(struct wx_ struct page_pool_params pp_params = { .flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV, .order = 0, - .pool_size = rx_ring->size, + .pool_size = rx_ring->count, .nid = dev_to_node(rx_ring->dev), .dev = rx_ring->dev, .dma_dir = DMA_FROM_DEVICE,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liam R. Howlett Liam.Howlett@oracle.com
commit fba46a5d83ca8decb338722fb4899026d8d9ead2 upstream.
Temporarily clear the preallocation flag when explicitly requesting allocations. Pre-existing allocations are already counted against the request through mas_node_count_gfp(), but the allocations will not happen if the MA_STATE_PREALLOC flag is set. This flag is meant to avoid re-allocating in bulk allocation mode, and to detect issues with preallocation calculations.
The MA_STATE_PREALLOC flag should also always be set on zero allocations so that detection of underflow allocations will print a WARN_ON() during consumption.
User visible effect of this flaw is a WARN_ON() followed by a null pointer dereference when subsequent requests for larger number of nodes is ignored, such as the vma merge retry in mmap_region() caused by drivers altering the vma flags (which happens in v6.6, at least)
Link: https://lkml.kernel.org/r/20250616184521.3382795-3-Liam.Howlett@oracle.com Fixes: 54a611b60590 ("Maple Tree: add new data structure") Signed-off-by: Liam R. Howlett Liam.Howlett@oracle.com Reported-by: Zhaoyang Huang zhaoyang.huang@unisoc.com Reported-by: Hailong Liu hailong.liu@oppo.com Link: https://lore.kernel.org/all/1652f7eb-a51b-4fee-8058-c73af63bacd1@oppo.com/ Link: https://lore.kernel.org/all/20250428184058.1416274-1-Liam.Howlett@oracle.com... Link: https://lore.kernel.org/all/20250429014754.1479118-1-Liam.Howlett@oracle.com... Cc: Lorenzo Stoakes lorenzo.stoakes@oracle.com Cc: Suren Baghdasaryan surenb@google.com Cc: Hailong Liu hailong.liu@oppo.com Cc: zhangpeng.00@bytedance.com zhangpeng.00@bytedance.com Cc: Steve Kang Steve.Kang@unisoc.com Cc: Matthew Wilcox willy@infradead.org Cc: Sidhartha Kumar sidhartha.kumar@oracle.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- lib/maple_tree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/lib/maple_tree.c +++ b/lib/maple_tree.c @@ -5496,8 +5496,9 @@ int mas_preallocate(struct ma_state *mas mas->store_type = mas_wr_store_type(&wr_mas); request = mas_prealloc_calc(mas, entry); if (!request) - return ret; + goto set_flag;
+ mas->mas_flags &= ~MA_STATE_PREALLOC; mas_node_count_gfp(mas, request, gfp); if (mas_is_err(mas)) { mas_set_alloc_req(mas, 0); @@ -5507,6 +5508,7 @@ int mas_preallocate(struct ma_state *mas return ret; }
+set_flag: mas->mas_flags |= MA_STATE_PREALLOC; return ret; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kairui Song kasong@tencent.com
commit 0ea148a799198518d8ebab63ddd0bb6114a103bc upstream.
This commit fixes two kinds of races, they may have different results:
Barry reported a BUG_ON in commit c50f8e6053b0, we may see the same BUG_ON if the filemap lookup returned NULL and folio is added to swap cache after that.
If another kind of race is triggered (folio changed after lookup) we may see RSS counter is corrupted:
[ 406.893936] BUG: Bad rss-counter state mm:ffff0000c5a9ddc0 type:MM_ANONPAGES val:-1 [ 406.894071] BUG: Bad rss-counter state mm:ffff0000c5a9ddc0 type:MM_SHMEMPAGES val:1
Because the folio is being accounted to the wrong VMA.
I'm not sure if there will be any data corruption though, seems no. The issues above are critical already.
On seeing a swap entry PTE, userfaultfd_move does a lockless swap cache lookup, and tries to move the found folio to the faulting vma. Currently, it relies on checking the PTE value to ensure that the moved folio still belongs to the src swap entry and that no new folio has been added to the swap cache, which turns out to be unreliable.
While working and reviewing the swap table series with Barry, following existing races are observed and reproduced [1]:
In the example below, move_pages_pte is moving src_pte to dst_pte, where src_pte is a swap entry PTE holding swap entry S1, and S1 is not in the swap cache:
CPU1 CPU2 userfaultfd_move move_pages_pte() entry = pte_to_swp_entry(orig_src_pte); // Here it got entry = S1 ... < interrupted> ... <swapin src_pte, alloc and use folio A> // folio A is a new allocated folio // and get installed into src_pte <frees swap entry S1> // src_pte now points to folio A, S1 // has swap count == 0, it can be freed // by folio_swap_swap or swap // allocator's reclaim. <try to swap out another folio B> // folio B is a folio in another VMA. <put folio B to swap cache using S1 > // S1 is freed, folio B can use it // for swap out with no problem. ... folio = filemap_get_folio(S1) // Got folio B here !!! ... < interrupted again> ... <swapin folio B and free S1> // Now S1 is free to be used again. <swapout src_pte & folio A using S1> // Now src_pte is a swap entry PTE // holding S1 again. folio_trylock(folio) move_swap_pte double_pt_lock is_pte_pages_stable // Check passed because src_pte == S1 folio_move_anon_rmap(...) // Moved invalid folio B here !!!
The race window is very short and requires multiple collisions of multiple rare events, so it's very unlikely to happen, but with a deliberately constructed reproducer and increased time window, it can be reproduced easily.
This can be fixed by checking if the folio returned by filemap is the valid swap cache folio after acquiring the folio lock.
Another similar race is possible: filemap_get_folio may return NULL, but folio (A) could be swapped in and then swapped out again using the same swap entry after the lookup. In such a case, folio (A) may remain in the swap cache, so it must be moved too:
CPU1 CPU2 userfaultfd_move move_pages_pte() entry = pte_to_swp_entry(orig_src_pte); // Here it got entry = S1, and S1 is not in swap cache folio = filemap_get_folio(S1) // Got NULL ... < interrupted again> ... <swapin folio A and free S1> <swapout folio A re-using S1> move_swap_pte double_pt_lock is_pte_pages_stable // Check passed because src_pte == S1 folio_move_anon_rmap(...) // folio A is ignored !!!
Fix this by checking the swap cache again after acquiring the src_pte lock. And to avoid the filemap overhead, we check swap_map directly [2].
The SWP_SYNCHRONOUS_IO path does make the problem more complex, but so far we don't need to worry about that, since folios can only be exposed to the swap cache in the swap out path, and this is covered in this patch by checking the swap cache again after acquiring the src_pte lock.
Testing with a simple C program that allocates and moves several GB of memory did not show any observable performance change.
Link: https://lkml.kernel.org/r/20250604151038.21968-1-ryncsn@gmail.com Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI") Signed-off-by: Kairui Song kasong@tencent.com Closes: https://lore.kernel.org/linux-mm/CAMgjq7B1K=6OOrK2OUZ0-tqCzi+EJt+2_K97TPGoSt... [1] Link: https://lore.kernel.org/all/CAGsJ_4yJhJBo16XhiC-nUzSheyX-V3-nFE+tAi=8Y560K8e... [2] Reviewed-by: Lokesh Gidra lokeshgidra@google.com Acked-by: Peter Xu peterx@redhat.com Reviewed-by: Suren Baghdasaryan surenb@google.com Reviewed-by: Barry Song baohua@kernel.org Reviewed-by: Chris Li chrisl@kernel.org Cc: Andrea Arcangeli aarcange@redhat.com Cc: David Hildenbrand david@redhat.com Cc: Kairui Song kasong@tencent.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/userfaultfd.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-)
--- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -1084,8 +1084,18 @@ static int move_swap_pte(struct mm_struc pte_t orig_dst_pte, pte_t orig_src_pte, pmd_t *dst_pmd, pmd_t dst_pmdval, spinlock_t *dst_ptl, spinlock_t *src_ptl, - struct folio *src_folio) + struct folio *src_folio, + struct swap_info_struct *si, swp_entry_t entry) { + /* + * Check if the folio still belongs to the target swap entry after + * acquiring the lock. Folio can be freed in the swap cache while + * not locked. + */ + if (src_folio && unlikely(!folio_test_swapcache(src_folio) || + entry.val != src_folio->swap.val)) + return -EAGAIN; + double_pt_lock(dst_ptl, src_ptl);
if (!is_pte_pages_stable(dst_pte, src_pte, orig_dst_pte, orig_src_pte, @@ -1102,6 +1112,25 @@ static int move_swap_pte(struct mm_struc if (src_folio) { folio_move_anon_rmap(src_folio, dst_vma); src_folio->index = linear_page_index(dst_vma, dst_addr); + } else { + /* + * Check if the swap entry is cached after acquiring the src_pte + * lock. Otherwise, we might miss a newly loaded swap cache folio. + * + * Check swap_map directly to minimize overhead, READ_ONCE is sufficient. + * We are trying to catch newly added swap cache, the only possible case is + * when a folio is swapped in and out again staying in swap cache, using the + * same entry before the PTE check above. The PTL is acquired and released + * twice, each time after updating the swap_map's flag. So holding + * the PTL here ensures we see the updated value. False positive is possible, + * e.g. SWP_SYNCHRONOUS_IO swapin may set the flag without touching the + * cache, or during the tiny synchronization window between swap cache and + * swap_map, but it will be gone very quickly, worst result is retry jitters. + */ + if (READ_ONCE(si->swap_map[swp_offset(entry)]) & SWAP_HAS_CACHE) { + double_pt_unlock(dst_ptl, src_ptl); + return -EAGAIN; + } }
orig_src_pte = ptep_get_and_clear(mm, src_addr, src_pte); @@ -1412,7 +1441,7 @@ retry: } err = move_swap_pte(mm, dst_vma, dst_addr, src_addr, dst_pte, src_pte, orig_dst_pte, orig_src_pte, dst_pmd, dst_pmdval, - dst_ptl, src_ptl, src_folio); + dst_ptl, src_ptl, src_folio, si, entry); }
out:
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kairui Song kasong@tencent.com
commit a05dd8ae5cbb1cb45f349922cfea4f548a5e5d6f upstream.
Following softlockup can be easily reproduced on my test machine with:
echo always > /sys/kernel/mm/transparent_hugepage/hugepages-64kB/enabled swapon /dev/zram0 # zram0 is a 48G swap device mkdir -p /sys/fs/cgroup/memory/test echo 1G > /sys/fs/cgroup/test/memory.max echo $BASHPID > /sys/fs/cgroup/test/cgroup.procs while true; do dd if=/dev/zero of=/tmp/test.img bs=1M count=5120 cat /tmp/test.img > /dev/null rm /tmp/test.img done
Then after a while: watchdog: BUG: soft lockup - CPU#0 stuck for 763s! [cat:5787] Modules linked in: zram virtiofs CPU: 0 UID: 0 PID: 5787 Comm: cat Kdump: loaded Tainted: G L 6.15.0.orig-gf3021d9246bc-dirty #118 PREEMPT(voluntary)· Tainted: [L]=SOFTLOCKUP Hardware name: Red Hat KVM/RHEL-AV, BIOS 0.0.0 02/06/2015 RIP: 0010:mpol_shared_policy_lookup+0xd/0x70 Code: e9 b8 b4 ff ff 31 c0 c3 cc cc cc cc 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 66 0f 1f 00 0f 1f 44 00 00 41 54 55 53 <48> 8b 1f 48 85 db 74 41 4c 8d 67 08 48 89 fb 48 89 f5 4c 89 e7 e8 RSP: 0018:ffffc90002b1fc28 EFLAGS: 00000202 RAX: 00000000001c20ca RBX: 0000000000724e1e RCX: 0000000000000001 RDX: ffff888118e214c8 RSI: 0000000000057d42 RDI: ffff888118e21518 RBP: 000000000002bec8 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000bf4 R11: 0000000000000000 R12: 0000000000000001 R13: 00000000001c20ca R14: 00000000001c20ca R15: 0000000000000000 FS: 00007f03f995c740(0000) GS:ffff88a07ad9a000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f03f98f1000 CR3: 0000000144626004 CR4: 0000000000770eb0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: <TASK> shmem_alloc_folio+0x31/0xc0 shmem_swapin_folio+0x309/0xcf0 ? filemap_get_entry+0x117/0x1e0 ? xas_load+0xd/0xb0 ? filemap_get_entry+0x101/0x1e0 shmem_get_folio_gfp+0x2ed/0x5b0 shmem_file_read_iter+0x7f/0x2e0 vfs_read+0x252/0x330 ksys_read+0x68/0xf0 do_syscall_64+0x4c/0x1c0 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7f03f9a46991 Code: 00 48 8b 15 81 14 10 00 f7 d8 64 89 02 b8 ff ff ff ff eb bd e8 20 ad 01 00 f3 0f 1e fa 80 3d 35 97 10 00 00 74 13 31 c0 0f 05 <48> 3d 00 f0 ff ff 77 4f c3 66 0f 1f 44 00 00 55 48 89 e5 48 83 ec RSP: 002b:00007fff3c52bd28 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 RAX: ffffffffffffffda RBX: 0000000000040000 RCX: 00007f03f9a46991 RDX: 0000000000040000 RSI: 00007f03f98ba000 RDI: 0000000000000003 RBP: 00007fff3c52bd50 R08: 0000000000000000 R09: 00007f03f9b9a380 R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000040000 R13: 00007f03f98ba000 R14: 0000000000000003 R15: 0000000000000000 </TASK>
The reason is simple, readahead brought some order 0 folio in swap cache, and the swapin mTHP folio being allocated is in conflict with it, so swapcache_prepare fails and causes shmem_swap_alloc_folio to return -EEXIST, and shmem simply retries again and again causing this loop.
Fix it by applying a similar fix for anon mTHP swapin.
The performance change is very slight, time of swapin 10g zero folios with shmem (test for 12 times): Before: 2.47s After: 2.48s
[kasong@tencent.com: add comment] Link: https://lkml.kernel.org/r/20250610181645.45922-1-ryncsn@gmail.com Link: https://lkml.kernel.org/r/20250610181645.45922-1-ryncsn@gmail.com Link: https://lkml.kernel.org/r/20250609171751.36305-1-ryncsn@gmail.com Fixes: 1dd44c0af4fa ("mm: shmem: skip swapcache for swapin of synchronous swap device") Signed-off-by: Kairui Song kasong@tencent.com Reviewed-by: Barry Song baohua@kernel.org Acked-by: Nhat Pham nphamcs@gmail.com Reviewed-by: Baolin Wang baolin.wang@linux.alibaba.com Cc: Baoquan He bhe@redhat.com Cc: Chris Li chrisl@kernel.org Cc: Hugh Dickins hughd@google.com Cc: Kemeng Shi shikemeng@huaweicloud.com Cc: Usama Arif usamaarif642@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/memory.c | 20 -------------------- mm/shmem.c | 6 +++++- mm/swap.h | 23 +++++++++++++++++++++++ 3 files changed, 28 insertions(+), 21 deletions(-)
--- a/mm/memory.c +++ b/mm/memory.c @@ -4224,26 +4224,6 @@ static struct folio *__alloc_swap_folio( }
#ifdef CONFIG_TRANSPARENT_HUGEPAGE -static inline int non_swapcache_batch(swp_entry_t entry, int max_nr) -{ - struct swap_info_struct *si = swp_swap_info(entry); - pgoff_t offset = swp_offset(entry); - int i; - - /* - * While allocating a large folio and doing swap_read_folio, which is - * the case the being faulted pte doesn't have swapcache. We need to - * ensure all PTEs have no cache as well, otherwise, we might go to - * swap devices while the content is in swapcache. - */ - for (i = 0; i < max_nr; i++) { - if ((si->swap_map[offset + i] & SWAP_HAS_CACHE)) - return i; - } - - return i; -} - /* * Check if the PTEs within a range are contiguous swap entries * and have consistent swapcache, zeromap. --- a/mm/shmem.c +++ b/mm/shmem.c @@ -2262,6 +2262,7 @@ static int shmem_swapin_folio(struct ino folio = swap_cache_get_folio(swap, NULL, 0); order = xa_get_order(&mapping->i_pages, index); if (!folio) { + int nr_pages = 1 << order; bool fallback_order0 = false;
/* Or update major stats only when swapin succeeds?? */ @@ -2275,9 +2276,12 @@ static int shmem_swapin_folio(struct ino * If uffd is active for the vma, we need per-page fault * fidelity to maintain the uffd semantics, then fallback * to swapin order-0 folio, as well as for zswap case. + * Any existing sub folio in the swap cache also blocks + * mTHP swapin. */ if (order > 0 && ((vma && unlikely(userfaultfd_armed(vma))) || - !zswap_never_enabled())) + !zswap_never_enabled() || + non_swapcache_batch(swap, nr_pages) != nr_pages)) fallback_order0 = true;
/* Skip swapcache for synchronous device. */ --- a/mm/swap.h +++ b/mm/swap.h @@ -106,6 +106,25 @@ static inline int swap_zeromap_batch(swp return find_next_bit(sis->zeromap, end, start) - start; }
+static inline int non_swapcache_batch(swp_entry_t entry, int max_nr) +{ + struct swap_info_struct *si = swp_swap_info(entry); + pgoff_t offset = swp_offset(entry); + int i; + + /* + * While allocating a large folio and doing mTHP swapin, we need to + * ensure all entries are not cached, otherwise, the mTHP folio will + * be in conflict with the folio in swap cache. + */ + for (i = 0; i < max_nr; i++) { + if ((si->swap_map[offset + i] & SWAP_HAS_CACHE)) + return i; + } + + return i; +} + #else /* CONFIG_SWAP */ struct swap_iocb; static inline void swap_read_folio(struct folio *folio, struct swap_iocb **plug) @@ -199,6 +218,10 @@ static inline int swap_zeromap_batch(swp return 0; }
+static inline int non_swapcache_batch(swp_entry_t entry, int max_nr) +{ + return 0; +} #endif /* CONFIG_SWAP */
#endif /* _MM_SWAP_H */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Hildenbrand david@redhat.com
commit 517f496e1e61bd169d585dab4dd77e7147506322 upstream.
After commit 1aaf8c122918 ("mm: gup: fix infinite loop within __get_longterm_locked") we are able to longterm pin folios that are not supposed to get longterm pinned, simply because they temporarily have the LRU flag cleared (esp. temporarily isolated).
For example, two __get_longterm_locked() callers can race, or __get_longterm_locked() can race with anything else that temporarily isolates folios.
The introducing commit mentions the use case of a driver that uses vm_ops->fault to insert pages allocated through cma_alloc() into the page tables, assuming they can later get longterm pinned. These pages/ folios would never have the LRU flag set and consequently cannot get isolated. There is no known in-tree user making use of that so far, fortunately.
To handle that in the future -- and avoid retrying forever to isolate/migrate them -- we will need a different mechanism for the CMA area *owner* to indicate that it actually already allocated the page and is fine with longterm pinning it. The LRU flag is not suitable for that.
Probably we can lookup the relevant CMA area and query the bitmap; we only have have to care about some races, probably. If already allocated, we could just allow longterm pinning)
Anyhow, let's fix the "must not be longterm pinned" problem first by reverting the original commit.
Link: https://lkml.kernel.org/r/20250611131314.594529-1-david@redhat.com Fixes: 1aaf8c122918 ("mm: gup: fix infinite loop within __get_longterm_locked") Signed-off-by: David Hildenbrand david@redhat.com Closes: https://lore.kernel.org/all/20250522092755.GA3277597@tiffany/ Reported-by: Hyesoo Yu hyesoo.yu@samsung.com Reviewed-by: John Hubbard jhubbard@nvidia.com Cc: Jason Gunthorpe jgg@ziepe.ca Cc: Peter Xu peterx@redhat.com Cc: Zhaoyang Huang zhaoyang.huang@unisoc.com Cc: Aijun Sun aijun.sun@unisoc.com Cc: Alistair Popple apopple@nvidia.com Cc: stable@vger.kernel.org Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- mm/gup.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
--- a/mm/gup.c +++ b/mm/gup.c @@ -2320,13 +2320,13 @@ static void pofs_unpin(struct pages_or_f /* * Returns the number of collected folios. Return value is always >= 0. */ -static void collect_longterm_unpinnable_folios( +static unsigned long collect_longterm_unpinnable_folios( struct list_head *movable_folio_list, struct pages_or_folios *pofs) { + unsigned long i, collected = 0; struct folio *prev_folio = NULL; bool drain_allow = true; - unsigned long i;
for (i = 0; i < pofs->nr_entries; i++) { struct folio *folio = pofs_get_folio(pofs, i); @@ -2338,6 +2338,8 @@ static void collect_longterm_unpinnable_ if (folio_is_longterm_pinnable(folio)) continue;
+ collected++; + if (folio_is_device_coherent(folio)) continue;
@@ -2359,6 +2361,8 @@ static void collect_longterm_unpinnable_ NR_ISOLATED_ANON + folio_is_file_lru(folio), folio_nr_pages(folio)); } + + return collected; }
/* @@ -2435,9 +2439,11 @@ static long check_and_migrate_movable_pages_or_folios(struct pages_or_folios *pofs) { LIST_HEAD(movable_folio_list); + unsigned long collected;
- collect_longterm_unpinnable_folios(&movable_folio_list, pofs); - if (list_empty(&movable_folio_list)) + collected = collect_longterm_unpinnable_folios(&movable_folio_list, + pofs); + if (!collected) return 0;
return migrate_longterm_unpinnable_folios(&movable_folio_list, pofs);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu chao@kernel.org
commit ba8dac350faf16afc129ce6303ca4feaf083ccb1 upstream.
fstest reports a f2fs bug:
#generic/363 42s ... [failed, exit status 1]- output mismatch (see /share/git/fstests/results//generic/363.out.bad) # --- tests/generic/363.out 2025-01-12 21:57:40.271440542 +0800 # +++ /share/git/fstests/results//generic/363.out.bad 2025-05-19 19:55:58.000000000 +0800 # @@ -1,2 +1,78 @@ # QA output created by 363 # fsx -q -S 0 -e 1 -N 100000 # +READ BAD DATA: offset = 0xd6fb, size = 0xf044, fname = /mnt/f2fs/junk # +OFFSET GOOD BAD RANGE # +0x1540d 0x0000 0x2a25 0x0 # +operation# (mod 256) for the bad data may be 37 # +0x1540e 0x0000 0x2527 0x1 # ... # (Run 'diff -u /share/git/fstests/tests/generic/363.out /share/git/fstests/results//generic/363.out.bad' to see the entire diff) Ran: generic/363 Failures: generic/363 Failed 1 of 1 tests
The root cause is user can update post-eof page via mmap [1], however, f2fs missed to zero post-eof page in below operations, so, once it expands i_size, then it will include dummy data locates previous post-eof page, so during below operations, we need to zero post-eof page.
Operations which can include dummy data after previous i_size after expanding i_size: - write - mapwrite [1] - truncate - fallocate * preallocate * zero_range * insert_range * collapse_range - clone_range (doesn’t support in f2fs) - copy_range (doesn’t support in f2fs)
[1] https://man7.org/linux/man-pages/man2/mmap.2.html 'BUG section'
Cc: stable@kernel.org Signed-off-by: Chao Yu chao@kernel.org Reviewed-by: Zhiguo Niu zhiguo.niu@unisoc.com Signed-off-by: Jaegeuk Kim jaegeuk@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/f2fs/file.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
--- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -35,6 +35,17 @@ #include <trace/events/f2fs.h> #include <uapi/linux/f2fs.h>
+static void f2fs_zero_post_eof_page(struct inode *inode, loff_t new_size) +{ + loff_t old_size = i_size_read(inode); + + if (old_size >= new_size) + return; + + /* zero or drop pages only in range of [old_size, new_size] */ + truncate_pagecache(inode, old_size); +} + static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf) { struct inode *inode = file_inode(vmf->vma->vm_file); @@ -103,8 +114,13 @@ static vm_fault_t f2fs_vm_page_mkwrite(s
f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
+ filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT); + filemap_invalidate_unlock(inode->i_mapping); + file_update_time(vmf->vma->vm_file); filemap_invalidate_lock_shared(inode->i_mapping); + folio_lock(folio); if (unlikely(folio->mapping != inode->i_mapping || folio_pos(folio) > i_size_read(inode) || @@ -1106,6 +1122,8 @@ int f2fs_setattr(struct mnt_idmap *idmap f2fs_down_write(&fi->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping);
+ if (attr->ia_size > old_size) + f2fs_zero_post_eof_page(inode, attr->ia_size); truncate_setsize(inode, attr->ia_size);
if (attr->ia_size <= old_size) @@ -1224,6 +1242,10 @@ static int f2fs_punch_hole(struct inode if (ret) return ret;
+ filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, offset + len); + filemap_invalidate_unlock(inode->i_mapping); + pg_start = ((unsigned long long) offset) >> PAGE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1507,6 +1529,8 @@ static int f2fs_do_collapse(struct inode f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(inode->i_mapping);
+ f2fs_zero_post_eof_page(inode, offset + len); + f2fs_lock_op(sbi); f2fs_drop_extent_tree(inode); truncate_pagecache(inode, offset); @@ -1628,6 +1652,10 @@ static int f2fs_zero_range(struct inode if (ret) return ret;
+ filemap_invalidate_lock(mapping); + f2fs_zero_post_eof_page(inode, offset + len); + filemap_invalidate_unlock(mapping); + pg_start = ((unsigned long long) offset) >> PAGE_SHIFT; pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1759,6 +1787,8 @@ static int f2fs_insert_range(struct inod /* avoid gc operation during block exchange */ f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]); filemap_invalidate_lock(mapping); + + f2fs_zero_post_eof_page(inode, offset + len); truncate_pagecache(inode, offset);
while (!ret && idx > pg_start) { @@ -1816,6 +1846,10 @@ static int f2fs_expand_inode_data(struct if (err) return err;
+ filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, offset + len); + filemap_invalidate_unlock(inode->i_mapping); + f2fs_balance_fs(sbi, true);
pg_start = ((unsigned long long)offset) >> PAGE_SHIFT; @@ -4846,6 +4880,10 @@ static ssize_t f2fs_write_checks(struct err = file_modified(file); if (err) return err; + + filemap_invalidate_lock(inode->i_mapping); + f2fs_zero_post_eof_page(inode, iocb->ki_pos + iov_iter_count(from)); + filemap_invalidate_unlock(inode->i_mapping); return count; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qasim Ijaz qasdev00@gmail.com
commit 4540e41e753a7d69ecd3f5bad51fe620205c3a18 upstream.
During appletb_kbd_probe, probe attempts to get the backlight device by name. When this happens backlight_device_get_by_name looks for a device in the backlight class which has name "appletb_backlight" and upon finding a match it increments the reference count for the device and returns it to the caller. However this reference is never released leading to a reference leak.
Fix this by decrementing the backlight device reference count on removal via put_device and on probe failure.
Fixes: 93a0fc489481 ("HID: hid-appletb-kbd: add support for automatic brightness control while using the touchbar") Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz qasdev00@gmail.com Reviewed-by: Aditya Garg gargaditya08@live.com Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/hid-appletb-kbd.c | 5 +++++ 1 file changed, 5 insertions(+)
--- a/drivers/hid/hid-appletb-kbd.c +++ b/drivers/hid/hid-appletb-kbd.c @@ -435,6 +435,8 @@ static int appletb_kbd_probe(struct hid_ return 0;
close_hw: + if (kbd->backlight_dev) + put_device(&kbd->backlight_dev->dev); hid_hw_close(hdev); stop_hw: hid_hw_stop(hdev); @@ -450,6 +452,9 @@ static void appletb_kbd_remove(struct hi input_unregister_handler(&kbd->inp_handler); timer_delete_sync(&kbd->inactivity_timer);
+ if (kbd->backlight_dev) + put_device(&kbd->backlight_dev->dev); + hid_hw_close(hdev); hid_hw_stop(hdev); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Iusico Maxim iusico.maxim@libero.it
commit 9327e3ee5b077c4ab4495a09b67624f670ed88b6 upstream.
Commit 2f2bd7cbd1d1 ("hid: lenovo: Resend all settings on reset_resume for compact keyboards") introduced a regression for ThinkPad TrackPoint Keyboard II by removing the conditional check for enabling F7/9/11 mode needed for compact keyboards only. As a result, the non-compact keyboards can no longer toggle Fn-lock via Fn+Esc, although it can be controlled via sysfs knob that directly sends raw commands.
This patch restores the previous conditional check without any additions.
Cc: stable@vger.kernel.org Fixes: 2f2bd7cbd1d1 ("hid: lenovo: Resend all settings on reset_resume for compact keyboards") Signed-off-by: Iusico Maxim iusico.maxim@libero.it Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/hid-lenovo.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c @@ -548,11 +548,14 @@ static void lenovo_features_set_cptkbd(s
/* * Tell the keyboard a driver understands it, and turn F7, F9, F11 into - * regular keys + * regular keys (Compact only) */ - ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); - if (ret) - hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); + if (hdev->product == USB_DEVICE_ID_LENOVO_CUSBKBD || + hdev->product == USB_DEVICE_ID_LENOVO_CBTKBD) { + ret = lenovo_send_cmd_cptkbd(hdev, 0x01, 0x03); + if (ret) + hid_warn(hdev, "Failed to switch F7/9/11 mode: %d\n", ret); + }
/* Switch middle button to native mode */ ret = lenovo_send_cmd_cptkbd(hdev, 0x09, 0x01);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qasim Ijaz qasdev00@gmail.com
commit 5ae416c5b1e2e816aee7b3fc8347adf70afabb4c upstream.
During wacom_initialize_remotes() a fifo buffer is allocated with kfifo_alloc() and later a cleanup action is registered during devm_add_action_or_reset() to clean it up.
However if the code fails to create a kobject and register it with sysfs the code simply returns -ENOMEM before the cleanup action is registered leading to a memory leak.
Fix this by ensuring the fifo is freed when the kobject creation and registration process fails.
Fixes: 83e6b40e2de6 ("HID: wacom: EKR: have the wacom resources dynamically allocated") Reviewed-by: Ping Cheng ping.cheng@wacom.com Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz qasdev00@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/wacom_sys.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2048,8 +2048,10 @@ static int wacom_initialize_remotes(stru
remote->remote_dir = kobject_create_and_add("wacom_remote", &wacom->hdev->dev.kobj); - if (!remote->remote_dir) + if (!remote->remote_dir) { + kfifo_free(&remote->remote_fifo); return -ENOMEM; + }
error = sysfs_create_files(remote->remote_dir, remote_unpair_attrs);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qasim Ijaz qasdev00@gmail.com
commit 1a19ae437ca5d5c7d9ec2678946fb339b1c706bf upstream.
When sysfs_create_files() fails during wacom_initialize_remotes() the fifo buffer is not freed leading to a memory leak.
Fix this by calling kfifo_free() before returning.
Fixes: 83e6b40e2de6 ("HID: wacom: EKR: have the wacom resources dynamically allocated") Reviewed-by: Ping Cheng ping.cheng@wacom.com Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz qasdev00@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/wacom_sys.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2058,6 +2058,7 @@ static int wacom_initialize_remotes(stru if (error) { hid_err(wacom->hdev, "cannot create sysfs group err: %d\n", error); + kfifo_free(&remote->remote_fifo); return error; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qasim Ijaz qasdev00@gmail.com
commit 85a720f4337f0ddf1603c8b75a8f1ffbbe022ef9 upstream.
When sysfs_create_files() fails in wacom_initialize_remotes() the error is returned and the cleanup action will not have been registered yet.
As a result the kobject???s refcount is never dropped, so the kobject can never be freed leading to a reference leak.
Fix this by calling kobject_put() before returning.
Fixes: 83e6b40e2de6 ("HID: wacom: EKR: have the wacom resources dynamically allocated") Acked-by: Ping Cheng ping.cheng@wacom.com Cc: stable@vger.kernel.org Signed-off-by: Qasim Ijaz qasdev00@gmail.com Signed-off-by: Jiri Kosina jkosina@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/hid/wacom_sys.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c @@ -2059,6 +2059,7 @@ static int wacom_initialize_remotes(stru hid_err(wacom->hdev, "cannot create sysfs group err: %d\n", error); kfifo_free(&remote->remote_fifo); + kobject_put(remote->remote_dir); return error; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Yu yu.c.chen@intel.com
commit 752eb816b55adb0673727ba0ed96609a17895654 upstream.
On a system with DRAM interleave enabled, out-of-bound access is detected:
megaraid_sas 0000:3f:00.0: requested/available msix 128/128 poll_queue 0 ------------[ cut here ]------------ UBSAN: array-index-out-of-bounds in ./arch/x86/include/asm/topology.h:72:28 index -1 is out of range for type 'cpumask *[1024]' dump_stack_lvl+0x5d/0x80 ubsan_epilogue+0x5/0x2b __ubsan_handle_out_of_bounds.cold+0x46/0x4b megasas_alloc_irq_vectors+0x149/0x190 [megaraid_sas] megasas_probe_one.cold+0xa4d/0x189c [megaraid_sas] local_pci_probe+0x42/0x90 pci_device_probe+0xdc/0x290 really_probe+0xdb/0x340 __driver_probe_device+0x78/0x110 driver_probe_device+0x1f/0xa0 __driver_attach+0xba/0x1c0 bus_for_each_dev+0x8b/0xe0 bus_add_driver+0x142/0x220 driver_register+0x72/0xd0 megasas_init+0xdf/0xff0 [megaraid_sas] do_one_initcall+0x57/0x310 do_init_module+0x90/0x250 init_module_from_file+0x85/0xc0 idempotent_init_module+0x114/0x310 __x64_sys_finit_module+0x65/0xc0 do_syscall_64+0x82/0x170 entry_SYSCALL_64_after_hwframe+0x76/0x7e
Fix it accordingly.
Signed-off-by: Chen Yu yu.c.chen@intel.com Link: https://lore.kernel.org/r/20250604042556.3731059-1-yu.c.chen@intel.com Fixes: 8049da6f3943 ("scsi: megaraid_sas: Use irq_set_affinity_and_hint()") Cc: stable@vger.kernel.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/megaraid/megaraid_sas_base.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5910,7 +5910,11 @@ megasas_set_high_iops_queue_affinity_and const struct cpumask *mask;
if (instance->perf_mode == MR_BALANCED_PERF_MODE) { - mask = cpumask_of_node(dev_to_node(&instance->pdev->dev)); + int nid = dev_to_node(&instance->pdev->dev); + + if (nid == NUMA_NO_NODE) + nid = 0; + mask = cpumask_of_node(nid);
for (i = 0; i < instance->low_latency_index_start; i++) { irq = pci_irq_vector(instance->pdev, i);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: anvithdosapati anvithdosapati@google.com
commit 2e083cd802294693a5414e4557a183dd7e442e71 upstream.
In ufshcd_host_reset_and_restore(), scale up clocks only when clock scaling is supported. Without this change CPU latency is voted for 0 (ufshcd_pm_qos_update) during resume unconditionally.
Signed-off-by: anvithdosapati anvithdosapati@google.com Link: https://lore.kernel.org/r/20250616085734.2133581-1-anvithdosapati@google.com Fixes: a3cd5ec55f6c ("scsi: ufs: add load based scaling of UFS gear") Cc: stable@vger.kernel.org Reviewed-by: Bart Van Assche bvanassche@acm.org Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ufs/core/ufshcd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -7753,7 +7753,8 @@ static int ufshcd_host_reset_and_restore hba->silence_err_logs = false;
/* scale up clocks to max frequency before full reinitialization */ - ufshcd_scale_clks(hba, ULONG_MAX, true); + if (ufshcd_is_clkscaling_supported(hba)) + ufshcd_scale_clks(hba, ULONG_MAX, true);
err = ufshcd_hba_enable(hba);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karan Tilak Kumar kartilak@cisco.com
commit a35b29bdedb4d2ae3160d4d6684a6f1ecd9ca7c2 upstream.
When both the RHBA and RPA FDMI requests time out, fnic reuses a frame to send ABTS for each of them. On send completion, this causes an attempt to free the same frame twice that leads to a crash.
Fix crash by allocating separate frames for RHBA and RPA, and modify ABTS logic accordingly.
Tested by checking MDS for FDMI information.
Tested by using instrumented driver to:
- Drop PLOGI response - Drop RHBA response - Drop RPA response - Drop RHBA and RPA response - Drop PLOGI response + ABTS response - Drop RHBA response + ABTS response - Drop RPA response + ABTS response - Drop RHBA and RPA response + ABTS response for both of them
Fixes: 09c1e6ab4ab2 ("scsi: fnic: Add and integrate support for FDMI") Reviewed-by: Sesidhar Baddela sebaddel@cisco.com Reviewed-by: Arulprabhu Ponnusamy arulponn@cisco.com Reviewed-by: Gian Carlo Boffa gcboffa@cisco.com Tested-by: Arun Easi aeasi@cisco.com Co-developed-by: Arun Easi aeasi@cisco.com Signed-off-by: Arun Easi aeasi@cisco.com Tested-by: Karan Tilak Kumar kartilak@cisco.com Cc: stable@vger.kernel.org Signed-off-by: Karan Tilak Kumar kartilak@cisco.com Link: https://lore.kernel.org/r/20250618003431.6314-1-kartilak@cisco.com Reviewed-by: John Meneghini jmeneghi@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/fnic/fdls_disc.c | 113 +++++++++++++++++++++++++++++++----------- drivers/scsi/fnic/fnic.h | 2 drivers/scsi/fnic/fnic_fdls.h | 1 3 files changed, 87 insertions(+), 29 deletions(-)
--- a/drivers/scsi/fnic/fdls_disc.c +++ b/drivers/scsi/fnic/fdls_disc.c @@ -763,47 +763,69 @@ static void fdls_send_fabric_abts(struct iport->fabric.timer_pending = 1; }
-static void fdls_send_fdmi_abts(struct fnic_iport_s *iport) +static uint8_t *fdls_alloc_init_fdmi_abts_frame(struct fnic_iport_s *iport, + uint16_t oxid) { - uint8_t *frame; + struct fc_frame_header *pfdmi_abts; uint8_t d_id[3]; + uint8_t *frame; struct fnic *fnic = iport->fnic; - struct fc_frame_header *pfabric_abts; - unsigned long fdmi_tov; - uint16_t oxid; - uint16_t frame_size = FNIC_ETH_FCOE_HDRS_OFFSET + - sizeof(struct fc_frame_header);
frame = fdls_alloc_frame(iport); if (frame == NULL) { FNIC_FCS_DBG(KERN_ERR, fnic->host, fnic->fnic_num, "Failed to allocate frame to send FDMI ABTS"); - return; + return NULL; }
- pfabric_abts = (struct fc_frame_header *) (frame + FNIC_ETH_FCOE_HDRS_OFFSET); + pfdmi_abts = (struct fc_frame_header *) (frame + FNIC_ETH_FCOE_HDRS_OFFSET); fdls_init_fabric_abts_frame(frame, iport);
hton24(d_id, FC_FID_MGMT_SERV); - FNIC_STD_SET_D_ID(*pfabric_abts, d_id); + FNIC_STD_SET_D_ID(*pfdmi_abts, d_id); + FNIC_STD_SET_OX_ID(*pfdmi_abts, oxid); + + return frame; +} + +static void fdls_send_fdmi_abts(struct fnic_iport_s *iport) +{ + uint8_t *frame; + unsigned long fdmi_tov; + uint16_t frame_size = FNIC_ETH_FCOE_HDRS_OFFSET + + sizeof(struct fc_frame_header);
if (iport->fabric.fdmi_pending & FDLS_FDMI_PLOGI_PENDING) { - oxid = iport->active_oxid_fdmi_plogi; - FNIC_STD_SET_OX_ID(*pfabric_abts, oxid); + frame = fdls_alloc_init_fdmi_abts_frame(iport, + iport->active_oxid_fdmi_plogi); + if (frame == NULL) + return; + fnic_send_fcoe_frame(iport, frame, frame_size); } else { if (iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING) { - oxid = iport->active_oxid_fdmi_rhba; - FNIC_STD_SET_OX_ID(*pfabric_abts, oxid); + frame = fdls_alloc_init_fdmi_abts_frame(iport, + iport->active_oxid_fdmi_rhba); + if (frame == NULL) + return; + fnic_send_fcoe_frame(iport, frame, frame_size); } if (iport->fabric.fdmi_pending & FDLS_FDMI_RPA_PENDING) { - oxid = iport->active_oxid_fdmi_rpa; - FNIC_STD_SET_OX_ID(*pfabric_abts, oxid); + frame = fdls_alloc_init_fdmi_abts_frame(iport, + iport->active_oxid_fdmi_rpa); + if (frame == NULL) { + if (iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING) + goto arm_timer; + else + return; + } + fnic_send_fcoe_frame(iport, frame, frame_size); } }
+arm_timer: fdmi_tov = jiffies + msecs_to_jiffies(2 * iport->e_d_tov); mod_timer(&iport->fabric.fdmi_timer, round_jiffies(fdmi_tov)); iport->fabric.fdmi_pending |= FDLS_FDMI_ABORT_PENDING; @@ -2244,6 +2266,21 @@ void fdls_fabric_timer_callback(struct t spin_unlock_irqrestore(&fnic->fnic_lock, flags); }
+void fdls_fdmi_retry_plogi(struct fnic_iport_s *iport) +{ + struct fnic *fnic = iport->fnic; + + iport->fabric.fdmi_pending = 0; + /* If max retries not exhausted, start over from fdmi plogi */ + if (iport->fabric.fdmi_retry < FDLS_FDMI_MAX_RETRY) { + iport->fabric.fdmi_retry++; + FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, + "Retry FDMI PLOGI. FDMI retry: %d", + iport->fabric.fdmi_retry); + fdls_send_fdmi_plogi(iport); + } +} + void fdls_fdmi_timer_callback(struct timer_list *t) { struct fnic_fdls_fabric_s *fabric = from_timer(fabric, t, fdmi_timer); @@ -2289,14 +2326,7 @@ void fdls_fdmi_timer_callback(struct tim FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "fdmi timer callback : 0x%x\n", iport->fabric.fdmi_pending);
- iport->fabric.fdmi_pending = 0; - /* If max retries not exhaused, start over from fdmi plogi */ - if (iport->fabric.fdmi_retry < FDLS_FDMI_MAX_RETRY) { - iport->fabric.fdmi_retry++; - FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, - "retry fdmi timer %d", iport->fabric.fdmi_retry); - fdls_send_fdmi_plogi(iport); - } + fdls_fdmi_retry_plogi(iport); FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, "fdmi timer callback : 0x%x\n", iport->fabric.fdmi_pending); spin_unlock_irqrestore(&fnic->fnic_lock, flags); @@ -3714,11 +3744,32 @@ static void fdls_process_fdmi_abts_rsp(s switch (FNIC_FRAME_TYPE(oxid)) { case FNIC_FRAME_TYPE_FDMI_PLOGI: fdls_free_oxid(iport, oxid, &iport->active_oxid_fdmi_plogi); + + iport->fabric.fdmi_pending &= ~FDLS_FDMI_PLOGI_PENDING; + iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING; break; case FNIC_FRAME_TYPE_FDMI_RHBA: + iport->fabric.fdmi_pending &= ~FDLS_FDMI_REG_HBA_PENDING; + + /* If RPA is still pending, don't turn off ABORT PENDING. + * We count on the timer to detect the ABTS timeout and take + * corrective action. + */ + if (!(iport->fabric.fdmi_pending & FDLS_FDMI_RPA_PENDING)) + iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING; + fdls_free_oxid(iport, oxid, &iport->active_oxid_fdmi_rhba); break; case FNIC_FRAME_TYPE_FDMI_RPA: + iport->fabric.fdmi_pending &= ~FDLS_FDMI_RPA_PENDING; + + /* If RHBA is still pending, don't turn off ABORT PENDING. + * We count on the timer to detect the ABTS timeout and take + * corrective action. + */ + if (!(iport->fabric.fdmi_pending & FDLS_FDMI_REG_HBA_PENDING)) + iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING; + fdls_free_oxid(iport, oxid, &iport->active_oxid_fdmi_rpa); break; default: @@ -3728,10 +3779,16 @@ static void fdls_process_fdmi_abts_rsp(s break; }
- timer_delete_sync(&iport->fabric.fdmi_timer); - iport->fabric.fdmi_pending &= ~FDLS_FDMI_ABORT_PENDING; - - fdls_send_fdmi_plogi(iport); + /* + * Only if ABORT PENDING is off, delete the timer, and if no other + * operations are pending, retry FDMI. + * Otherwise, let the timer pop and take the appropriate action. + */ + if (!(iport->fabric.fdmi_pending & FDLS_FDMI_ABORT_PENDING)) { + timer_delete_sync(&iport->fabric.fdmi_timer); + if (!iport->fabric.fdmi_pending) + fdls_fdmi_retry_plogi(iport); + } }
static void --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -30,7 +30,7 @@
#define DRV_NAME "fnic" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" -#define DRV_VERSION "1.8.0.0" +#define DRV_VERSION "1.8.0.1" #define PFX DRV_NAME ": " #define DFX DRV_NAME "%d: "
--- a/drivers/scsi/fnic/fnic_fdls.h +++ b/drivers/scsi/fnic/fnic_fdls.h @@ -394,6 +394,7 @@ void fdls_send_tport_abts(struct fnic_ip bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport); void fdls_fdmi_timer_callback(struct timer_list *t); +void fdls_fdmi_retry_plogi(struct fnic_iport_s *iport);
/* fnic_fcs.c */ void fnic_fdls_init(struct fnic *fnic, int usefip);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karan Tilak Kumar kartilak@cisco.com
commit 74f46a0524f8d2f01dc7ca95bb5fc463a8603e72 upstream.
When the link goes down and comes up, FDMI requests are not sent out anymore.
Fix bug by turning off FNIC_FDMI_ACTIVE when the link goes down.
Fixes: 09c1e6ab4ab2 ("scsi: fnic: Add and integrate support for FDMI") Reviewed-by: Sesidhar Baddela sebaddel@cisco.com Reviewed-by: Arulprabhu Ponnusamy arulponn@cisco.com Reviewed-by: Gian Carlo Boffa gcboffa@cisco.com Reviewed-by: Arun Easi aeasi@cisco.com Tested-by: Karan Tilak Kumar kartilak@cisco.com Cc: stable@vger.kernel.org Signed-off-by: Karan Tilak Kumar kartilak@cisco.com Link: https://lore.kernel.org/r/20250618003431.6314-2-kartilak@cisco.com Reviewed-by: John Meneghini jmeneghi@redhat.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/fnic/fdls_disc.c | 9 ++++++--- drivers/scsi/fnic/fnic.h | 2 +- 2 files changed, 7 insertions(+), 4 deletions(-)
--- a/drivers/scsi/fnic/fdls_disc.c +++ b/drivers/scsi/fnic/fdls_disc.c @@ -5027,9 +5027,12 @@ void fnic_fdls_link_down(struct fnic_ipo fdls_delete_tport(iport, tport); }
- if ((fnic_fdmi_support == 1) && (iport->fabric.fdmi_pending > 0)) { - timer_delete_sync(&iport->fabric.fdmi_timer); - iport->fabric.fdmi_pending = 0; + if (fnic_fdmi_support == 1) { + if (iport->fabric.fdmi_pending > 0) { + timer_delete_sync(&iport->fabric.fdmi_timer); + iport->fabric.fdmi_pending = 0; + } + iport->flags &= ~FNIC_FDMI_ACTIVE; }
FNIC_FCS_DBG(KERN_INFO, fnic->host, fnic->fnic_num, --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -30,7 +30,7 @@
#define DRV_NAME "fnic" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" -#define DRV_VERSION "1.8.0.1" +#define DRV_VERSION "1.8.0.2" #define PFX DRV_NAME ": " #define DFX DRV_NAME "%d: "
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann tzimmermann@suse.de
commit 7cce65f3789e04c0f7668a66563e680d81d54493 upstream.
The ast driver protects the commit tail against concurrent reads of the display modes by acquiring a lock. The comment is misleading as the lock is not released in atomic_flush, but at the end of the commit-tail helper. Rewrite the comment.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: 1fe182154984 ("drm/ast: Acquire I/O-register lock in atomic_commit_tail function") Cc: Thomas Zimmermann tzimmermann@suse.de Cc: Jocelyn Falempe jfalempe@redhat.com Cc: Dave Airlie airlied@redhat.com Cc: dri-devel@lists.freedesktop.org Cc: stable@vger.kernel.org # v6.2+ Reviewed-by: Jocelyn Falempe jfalempe@redhat.com Link: https://lore.kernel.org/r/20250324094520.192974-2-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/ast/ast_mode.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/ast/ast_mode.c +++ b/drivers/gpu/drm/ast/ast_mode.c @@ -922,9 +922,9 @@ static void ast_mode_config_helper_atomi
/* * Concurrent operations could possibly trigger a call to - * drm_connector_helper_funcs.get_modes by trying to read the - * display modes. Protect access to I/O registers by acquiring - * the I/O-register lock. Released in atomic_flush(). + * drm_connector_helper_funcs.get_modes by reading the display + * modes. Protect access to registers by acquiring the modeset + * lock. */ mutex_lock(&ast->modeset_lock); drm_atomic_helper_commit_tail(state);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann tzimmermann@suse.de
commit 4bfb389a0136a13f0802eeb5e97a0e76d88f77ae upstream.
Do not set CR1B[6] when programming the pitch. The bit effects VGA text mode and is not interpreted by qemu. [1] It has no affect on the scanline pitch.
The scanline bit that is set into CR1B[6] belongs into CR13[7], which the driver sets up correctly.
This bug goes back to the driver's initial commit.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Acked-by: Gerd Hoffmann kraxel@redhat.com Link: https://gitlab.com/qemu-project/qemu/-/blob/stable-9.2/hw/display/cirrus_vga... # 1 Fixes: f9aa76a85248 ("drm/kms: driver for virtual cirrus under qemu") Cc: Adam Jackson ajax@redhat.com Cc: Dave Airlie airlied@redhat.com Cc: Maarten Lankhorst maarten.lankhorst@linux.intel.com Cc: Maxime Ripard mripard@kernel.org Cc: Thomas Zimmermann tzimmermann@suse.de Cc: stable@vger.kernel.org # v3.5+ Link: https://lore.kernel.org/r/20250328091821.195061-2-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/tiny/cirrus-qemu.c | 1 - 1 file changed, 1 deletion(-)
--- a/drivers/gpu/drm/tiny/cirrus-qemu.c +++ b/drivers/gpu/drm/tiny/cirrus-qemu.c @@ -318,7 +318,6 @@ static void cirrus_pitch_set(struct cirr /* Enable extended blanking and pitch bits, and enable full memory */ cr1b = 0x22; cr1b |= (pitch >> 7) & 0x10; - cr1b |= (pitch >> 6) & 0x40; wreg_crt(cirrus, 0x1b, cr1b);
cirrus_set_start_address(cirrus, 0);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maíra Canal mcanal@igalia.com
commit 61ee19dedb8d753249e20308782bf4e9e2fb7344 upstream.
Commit 704d3d60fec4 ("drm/etnaviv: don't block scheduler when GPU is still active") ensured that active jobs are returned to the pending list when extending the timeout. However, it didn't use the pending list's lock to manipulate the list, which causes a race condition as the scheduler's workqueues are running.
Hold the lock while manipulating the scheduler's pending list to prevent a race.
Cc: stable@vger.kernel.org Fixes: 704d3d60fec4 ("drm/etnaviv: don't block scheduler when GPU is still active") Reported-by: Philipp Stanner phasta@kernel.org Closes: https://lore.kernel.org/dri-devel/964e59ba1539083ef29b06d3c78f5e2e9b138ab8.c... Reviewed-by: Lucas Stach l.stach@pengutronix.de Reviewed-by: Philipp Stanner phasta@kernel.org Link: https://lore.kernel.org/r/20250602132240.93314-1-mcanal@igalia.com Signed-off-by: Maíra Canal mcanal@igalia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c @@ -35,6 +35,7 @@ static enum drm_gpu_sched_stat etnaviv_s *sched_job) { struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job); + struct drm_gpu_scheduler *sched = sched_job->sched; struct etnaviv_gpu *gpu = submit->gpu; u32 dma_addr, primid = 0; int change; @@ -89,7 +90,9 @@ static enum drm_gpu_sched_stat etnaviv_s return DRM_GPU_SCHED_STAT_NOMINAL;
out_no_timeout: - list_add(&sched_job->list, &sched_job->sched->pending_list); + spin_lock(&sched->job_list_lock); + list_add(&sched_job->list, &sched->pending_list); + spin_unlock(&sched->job_list_lock); return DRM_GPU_SCHED_STAT_NOMINAL; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luca Ceresoli luca.ceresoli@bootlin.com
commit 716c75afd83c837f14042309126e838de040658b upstream.
Add power on/off delays for the Tianma TM070JDHG34-00.
Fixes: bf6daaa281f7 ("drm/panel: simple: Add Tianma TM070JDHG34-00 panel support") Cc: stable@vger.kernel.org Signed-off-by: Luca Ceresoli luca.ceresoli@bootlin.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250411-tianma-p0700wxf1mbaa-v3-2-acbefe9ea669@bo... Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250411-tianma-p0700wxf1mbaa-v3-2-acbefe9ea669@bo... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/panel/panel-simple.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/gpu/drm/panel/panel-simple.c +++ b/drivers/gpu/drm/panel/panel-simple.c @@ -4455,6 +4455,12 @@ static const struct panel_desc tianma_tm .width = 150, /* 149.76 */ .height = 94, /* 93.60 */ }, + .delay = { + .prepare = 15, /* Tp1 */ + .enable = 150, /* Tp2 */ + .disable = 150, /* Tp4 */ + .unprepare = 120, /* Tp3 */ + }, .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG, .connector_type = DRM_MODE_CONNECTOR_LVDS, };
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann tzimmermann@suse.de
commit d231cde7c84359fb18fb268cf6cff03b5bce48ff upstream.
The res pointer passed to simpledrm_device_release_clocks() and simpledrm_device_release_regulators() points to an instance of struct simpledrm_device. No need to upcast from struct drm_device. The upcast is harmless, as DRM device is the first field in struct simpledrm_device.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: 11e8f5fd223b ("drm: Add simpledrm driver") Cc: stable@vger.kernel.org # v5.14+ Reviewed-by: Javier Martinez Canillas javierm@redhat.com Reviewed-by: Jocelyn Falempe jfalempe@redhat.com Link: https://lore.kernel.org/r/20250407134753.985925-2-tzimmermann@suse.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/tiny/simpledrm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/tiny/simpledrm.c +++ b/drivers/gpu/drm/tiny/simpledrm.c @@ -284,7 +284,7 @@ static struct simpledrm_device *simpledr
static void simpledrm_device_release_clocks(void *res) { - struct simpledrm_device *sdev = simpledrm_device_of_dev(res); + struct simpledrm_device *sdev = res; unsigned int i;
for (i = 0; i < sdev->clk_count; ++i) { @@ -382,7 +382,7 @@ static int simpledrm_device_init_clocks(
static void simpledrm_device_release_regulators(void *res) { - struct simpledrm_device *sdev = simpledrm_device_of_dev(res); + struct simpledrm_device *sdev = res; unsigned int i;
for (i = 0; i < sdev->regulator_count; ++i) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thierry Reding treding@nvidia.com
commit 9ff4fdf4f44b69237c0afc1d3a8dac916ce66f3e upstream.
Changes to a plane's type after it has been registered aren't propagated to userspace automatically. This could possibly be achieved by updating the property, but since we can already determine which type this should be before the registration, passing in the right type from the start is a much better solution.
Suggested-by: Aaron Kling webgeek1234@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Cc: stable@vger.kernel.org Fixes: 473079549f27 ("drm/tegra: dc: Add Tegra186 support") Signed-off-by: Aaron Kling webgeek1234@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20250421-tegra-drm-primary-v2-1-7f740c4c2121@gmail... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/tegra/dc.c | 12 ++++++++---- drivers/gpu/drm/tegra/hub.c | 4 ++-- drivers/gpu/drm/tegra/hub.h | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-)
--- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1321,10 +1321,16 @@ static struct drm_plane *tegra_dc_add_sh if (wgrp->dc == dc->pipe) { for (j = 0; j < wgrp->num_windows; j++) { unsigned int index = wgrp->windows[j]; + enum drm_plane_type type; + + if (primary) + type = DRM_PLANE_TYPE_OVERLAY; + else + type = DRM_PLANE_TYPE_PRIMARY;
plane = tegra_shared_plane_create(drm, dc, wgrp->index, - index); + index, type); if (IS_ERR(plane)) return plane;
@@ -1332,10 +1338,8 @@ static struct drm_plane *tegra_dc_add_sh * Choose the first shared plane owned by this * head as the primary plane. */ - if (!primary) { - plane->type = DRM_PLANE_TYPE_PRIMARY; + if (!primary) primary = plane; - } } } } --- a/drivers/gpu/drm/tegra/hub.c +++ b/drivers/gpu/drm/tegra/hub.c @@ -755,9 +755,9 @@ static const struct drm_plane_helper_fun struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, struct tegra_dc *dc, unsigned int wgrp, - unsigned int index) + unsigned int index, + enum drm_plane_type type) { - enum drm_plane_type type = DRM_PLANE_TYPE_OVERLAY; struct tegra_drm *tegra = drm->dev_private; struct tegra_display_hub *hub = tegra->hub; struct tegra_shared_plane *plane; --- a/drivers/gpu/drm/tegra/hub.h +++ b/drivers/gpu/drm/tegra/hub.h @@ -80,7 +80,8 @@ void tegra_display_hub_cleanup(struct te struct drm_plane *tegra_shared_plane_create(struct drm_device *drm, struct tegra_dc *dc, unsigned int wgrp, - unsigned int index); + unsigned int index, + enum drm_plane_type type);
int tegra_display_hub_atomic_check(struct drm_device *drm, struct drm_atomic_state *state);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiu-ji Chen chenqiuji666@gmail.com
commit 780351a5f61416ed2ba1199cc57e4a076fca644d upstream.
In tegra_crtc_reset(), new memory is allocated with kzalloc(), but no check is performed. Before calling __drm_atomic_helper_crtc_reset, state should be checked to prevent possible null pointer dereference.
Fixes: b7e0b04ae450 ("drm/tegra: Convert to using __drm_atomic_helper_crtc_reset() for reset.") Cc: stable@vger.kernel.org Signed-off-by: Qiu-ji Chen chenqiuji666@gmail.com Signed-off-by: Thierry Reding treding@nvidia.com Link: https://lore.kernel.org/r/20241106095906.15247-1-chenqiuji666@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/tegra/dc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c @@ -1393,7 +1393,10 @@ static void tegra_crtc_reset(struct drm_ if (crtc->state) tegra_crtc_atomic_destroy_state(crtc, crtc->state);
- __drm_atomic_helper_crtc_reset(crtc, &state->base); + if (state) + __drm_atomic_helper_crtc_reset(crtc, &state->base); + else + __drm_atomic_helper_crtc_reset(crtc, NULL); }
static struct drm_crtc_state *
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann tzimmermann@suse.de
commit ff9cb6d2035c586ea7c8f1754d4409eec7a2d26d upstream.
Disconnecting a DisplayLink device results in the following kernel error messages
[ 93.041748] [drm:udl_urb_completion [udl]] *ERROR* udl_urb_completion - nonzero write bulk status received: -115 [ 93.055299] [drm:udl_submit_urb [udl]] *ERROR* usb_submit_urb error fffffffe [ 93.065363] [drm:udl_urb_completion [udl]] *ERROR* udl_urb_completion - nonzero write bulk status received: -115 [ 93.078207] [drm:udl_submit_urb [udl]] *ERROR* usb_submit_urb error fffffffe
coming from KMS poll helpers. Shutting down poll helpers runs them one final time when the USB device is already gone.
Run drm_dev_unplug() first in udl's USB disconnect handler. Udl's polling code already handles disconnects gracefully if the device has been marked as unplugged.
Signed-off-by: Thomas Zimmermann tzimmermann@suse.de Fixes: b1a981bd5576 ("drm/udl: drop drm_driver.release hook") Cc: dri-devel@lists.freedesktop.org Cc: stable@vger.kernel.org # v5.8+ Reviewed-by: Patrik Jakobsson patrik.r.jakobsson@gmail.com Link: https://patchwork.freedesktop.org/patch/msgid/20250303145604.62962-2-tzimmer... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/udl/udl_drv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/udl/udl_drv.c +++ b/drivers/gpu/drm/udl/udl_drv.c @@ -127,9 +127,9 @@ static void udl_usb_disconnect(struct us { struct drm_device *dev = usb_get_intfdata(interface);
+ drm_dev_unplug(dev); drm_kms_helper_poll_fini(dev); udl_drop_usb(dev); - drm_dev_unplug(dev); }
/*
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold stephan.gerhold@linaro.org
commit b71717735be48d7743a34897e9e44a0b53e30c0e upstream.
There is a small chance that the GPU is already hot during boot. In that case, the call to of_devfreq_cooling_register() will immediately try to apply devfreq cooling, as seen in the following crash:
Unable to handle kernel paging request at virtual address 0000000000014110 pc : a6xx_gpu_busy+0x1c/0x58 [msm] lr : msm_devfreq_get_dev_status+0xbc/0x140 [msm] Call trace: a6xx_gpu_busy+0x1c/0x58 [msm] (P) devfreq_simple_ondemand_func+0x3c/0x150 devfreq_update_target+0x44/0xd8 qos_max_notifier_call+0x30/0x84 blocking_notifier_call_chain+0x6c/0xa0 pm_qos_update_target+0xd0/0x110 freq_qos_apply+0x3c/0x74 apply_constraint+0x88/0x148 __dev_pm_qos_update_request+0x7c/0xcc dev_pm_qos_update_request+0x38/0x5c devfreq_cooling_set_cur_state+0x98/0xf0 __thermal_cdev_update+0x64/0xb4 thermal_cdev_update+0x4c/0x58 step_wise_manage+0x1f0/0x318 __thermal_zone_device_update+0x278/0x424 __thermal_cooling_device_register+0x2bc/0x308 thermal_of_cooling_device_register+0x10/0x1c of_devfreq_cooling_register_power+0x240/0x2bc of_devfreq_cooling_register+0x14/0x20 msm_devfreq_init+0xc4/0x1a0 [msm] msm_gpu_init+0x304/0x574 [msm] adreno_gpu_init+0x1c4/0x2e0 [msm] a6xx_gpu_init+0x5c8/0x9c8 [msm] adreno_bind+0x2a8/0x33c [msm] ...
At this point we haven't initialized the GMU at all yet, so we cannot read the GMU registers inside a6xx_gpu_busy(). A similar issue was fixed before in commit 6694482a70e9 ("drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy"): msm_devfreq_init() does call devfreq_suspend_device(), but unlike msm_devfreq_suspend(), it doesn't set the df->suspended flag accordingly. This means the df->suspended flag does not match the actual devfreq state after initialization and msm_devfreq_get_dev_status() will end up accessing GMU registers, causing the crash.
Fix this by setting df->suspended correctly during initialization.
Cc: stable@vger.kernel.org Fixes: 6694482a70e9 ("drm/msm: Avoid unclocked GMU register access in 6xx gpu_busy") Signed-off-by: Stephan Gerhold stephan.gerhold@linaro.org Reviewed-by: Douglas Anderson dianders@chromium.org Reviewed-by: Konrad Dybcio konrad.dybcio@oss.qualcomm.com Patchwork: https://patchwork.freedesktop.org/patch/650772/ Signed-off-by: Rob Clark robdclark@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/msm/msm_gpu_devfreq.c +++ b/drivers/gpu/drm/msm/msm_gpu_devfreq.c @@ -156,6 +156,7 @@ void msm_devfreq_init(struct msm_gpu *gp priv->gpu_devfreq_config.downdifferential = 10;
mutex_init(&df->lock); + df->suspended = true;
ret = dev_pm_qos_add_request(&gpu->pdev->dev, &df->boost_freq, DEV_PM_QOS_MIN_FREQUENCY, 0);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jay Cornwall jay.cornwall@amd.com
commit cfb05257ae168a0496c7637e1d9e3ab8a25cbffe upstream.
q->gws is not updated atomically with qpd->mapped_gws_queue. If a runlist is created between pqm_set_gws and update_queue it will contain a queue which uses GWS in a process with no GWS allocated. This will result in a scheduler hang.
Use q->properties.is_gws which is changed while holding the DQM lock.
Signed-off-by: Jay Cornwall jay.cornwall@amd.com Reviewed-by: Harish Kasiviswanathan Harish.Kasiviswanathan@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit b98370220eb3110e82248e3354e16a489a492cfb) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c @@ -237,7 +237,7 @@ static int pm_map_queues_v9(struct packe
packet->bitfields2.engine_sel = engine_sel__mes_map_queues__compute_vi; - packet->bitfields2.gws_control_queue = q->gws ? 1 : 0; + packet->bitfields2.gws_control_queue = q->properties.is_gws ? 1 : 0; packet->bitfields2.extended_engine_sel = extended_engine_sel__mes_map_queues__legacy_engine_sel; packet->bitfields2.queue_type =
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak imre.deak@intel.com
commit a38b3232d618653155032a51208e974511c151e4 upstream.
The PTL XELPDP_PORT_CLOCK_CTL register XELPDP_DDI_CLOCK_SELECT field's size is 5 bits vs. the earlier platforms where its size is 4 bits. Make sure the field is read-out/programmed everywhere correctly, according to the above.
Cc: Mika Kahola mika.kahola@intel.com Cc: stable@vger.kernel.org # v6.13+ Tested-by: Mika Kahola mika.kahola@intel.com Reviewed-by: Mika Kahola mika.kahola@intel.com Signed-off-by: Imre Deak imre.deak@intel.com Link: https://lore.kernel.org/r/20250512142600.824347-1-imre.deak@intel.com (cherry picked from commit d0bf684bd42db22e7d131a038f8f78927fa6a72a) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 27 ++++++++-------------- drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h | 15 ++++++++---- 2 files changed, 21 insertions(+), 21 deletions(-)
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -2761,9 +2761,9 @@ static void intel_program_port_clock_ctl val |= XELPDP_FORWARD_CLOCK_UNGATE;
if (!is_dp && is_hdmi_frl(port_clock)) - val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK); else - val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
/* TODO: HDMI FRL */ /* DP2.0 10G and 20G rates enable MPLLA*/ @@ -2774,7 +2774,7 @@ static void intel_program_port_clock_ctl
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE | - XELPDP_DDI_CLOCK_SELECT_MASK | XELPDP_SSC_ENABLE_PLLA | + XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_SSC_ENABLE_PLLA | XELPDP_SSC_ENABLE_PLLB, val); }
@@ -3097,10 +3097,7 @@ int intel_mtl_tbt_calc_port_clock(struct
val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port));
- if (DISPLAY_VER(display) >= 30) - clock = REG_FIELD_GET(XE3_DDI_CLOCK_SELECT_MASK, val); - else - clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val); + clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val);
drm_WARN_ON(display->drm, !(val & XELPDP_FORWARD_CLOCK_UNGATE)); drm_WARN_ON(display->drm, !(val & XELPDP_TBT_CLOCK_REQUEST)); @@ -3168,13 +3165,9 @@ static void intel_mtl_tbt_pll_enable(str * clock muxes, gating and SSC */
- if (DISPLAY_VER(display) >= 30) { - mask = XE3_DDI_CLOCK_SELECT_MASK; - val |= XE3_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); - } else { - mask = XELPDP_DDI_CLOCK_SELECT_MASK; - val |= XELPDP_DDI_CLOCK_SELECT(intel_mtl_tbt_clock_select(display, crtc_state->port_clock)); - } + mask = XELPDP_DDI_CLOCK_SELECT_MASK(display); + val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, + intel_mtl_tbt_clock_select(display, crtc_state->port_clock));
mask |= XELPDP_FORWARD_CLOCK_UNGATE; val |= XELPDP_FORWARD_CLOCK_UNGATE; @@ -3287,7 +3280,7 @@ static void intel_cx0pll_disable(struct
/* 7. Program PORT_CLOCK_CTL register to disable and gate clocks. */ intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), - XELPDP_DDI_CLOCK_SELECT_MASK, 0); + XELPDP_DDI_CLOCK_SELECT_MASK(display), 0); intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), XELPDP_FORWARD_CLOCK_UNGATE, 0);
@@ -3336,7 +3329,7 @@ static void intel_mtl_tbt_pll_disable(st * 5. Program PORT CLOCK CTRL register to disable and gate clocks */ intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port), - XELPDP_DDI_CLOCK_SELECT_MASK | + XELPDP_DDI_CLOCK_SELECT_MASK(display) | XELPDP_FORWARD_CLOCK_UNGATE, 0);
/* 6. Program DDI_CLK_VALFREQ to 0. */ @@ -3365,7 +3358,7 @@ intel_mtl_port_pll_type(struct intel_enc * handling is done via the standard shared DPLL framework. */ val = intel_de_read(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port)); - clock = REG_FIELD_GET(XELPDP_DDI_CLOCK_SELECT_MASK, val); + clock = XELPDP_DDI_CLOCK_SELECT_GET(display, val);
if (clock == XELPDP_DDI_CLOCK_SELECT_MAXPCLK || clock == XELPDP_DDI_CLOCK_SELECT_DIV18CLK) --- a/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h @@ -192,10 +192,17 @@
#define XELPDP_TBT_CLOCK_REQUEST REG_BIT(19) #define XELPDP_TBT_CLOCK_ACK REG_BIT(18) -#define XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12) -#define XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12) -#define XELPDP_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XELPDP_DDI_CLOCK_SELECT_MASK, val) -#define XE3_DDI_CLOCK_SELECT(val) REG_FIELD_PREP(XE3_DDI_CLOCK_SELECT_MASK, val) +#define _XELPDP_DDI_CLOCK_SELECT_MASK REG_GENMASK(15, 12) +#define _XE3_DDI_CLOCK_SELECT_MASK REG_GENMASK(16, 12) +#define XELPDP_DDI_CLOCK_SELECT_MASK(display) (DISPLAY_VER(display) >= 30 ? \ + _XE3_DDI_CLOCK_SELECT_MASK : _XELPDP_DDI_CLOCK_SELECT_MASK) +#define XELPDP_DDI_CLOCK_SELECT_PREP(display, val) (DISPLAY_VER(display) >= 30 ? \ + REG_FIELD_PREP(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \ + REG_FIELD_PREP(_XELPDP_DDI_CLOCK_SELECT_MASK, (val))) +#define XELPDP_DDI_CLOCK_SELECT_GET(display, val) (DISPLAY_VER(display) >= 30 ? \ + REG_FIELD_GET(_XE3_DDI_CLOCK_SELECT_MASK, (val)) : \ + REG_FIELD_GET(_XELPDP_DDI_CLOCK_SELECT_MASK, (val))) + #define XELPDP_DDI_CLOCK_SELECT_NONE 0x0 #define XELPDP_DDI_CLOCK_SELECT_MAXPCLK 0x8 #define XELPDP_DDI_CLOCK_SELECT_DIV18CLK 0x9
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak imre.deak@intel.com
commit 9cb15478916e849d62a6ec44b10c593b9663328c upstream.
Due to a problem in the iTBT DP-in adapter's firmware the sink on a TBT link may get disconnected inadvertently if the SINK_COUNT_ESI and the DP_LINK_SERVICE_IRQ_VECTOR_ESI0 registers are read in a single AUX transaction. Work around the issue by reading these registers in separate transactions.
The issue affects MTL+ platforms and will be fixed in the DP-in adapter firmware, however releasing that firmware fix may take some time and is not guaranteed to be available for all systems. Based on this apply the workaround on affected platforms.
See HSD #13013007775.
v2: Cc'ing Mika Westerberg.
Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/13760 Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/14147 Cc: Mika Westerberg mika.westerberg@linux.intel.com Cc: stable@vger.kernel.org Reviewed-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Imre Deak imre.deak@intel.com Link: https://lore.kernel.org/r/20250519133417.1469181-1-imre.deak@intel.com (cherry picked from commit c3a48363cf1f76147088b1adb518136ac5df86a0) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_dp.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
--- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -4457,6 +4457,23 @@ intel_dp_mst_disconnect(struct intel_dp static bool intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi) { + struct intel_display *display = to_intel_display(intel_dp); + + /* + * Display WA for HSD #13013007775: mtl/arl/lnl + * Read the sink count and link service IRQ registers in separate + * transactions to prevent disconnecting the sink on a TBT link + * inadvertently. + */ + if (IS_DISPLAY_VER(display, 14, 20) && !display->platform.battlemage) { + if (drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 3) != 3) + return false; + + /* DP_SINK_COUNT_ESI + 3 == DP_LINK_SERVICE_IRQ_VECTOR_ESI0 */ + return drm_dp_dpcd_readb(&intel_dp->aux, DP_LINK_SERVICE_IRQ_VECTOR_ESI0, + &esi[3]) == 1; + } + return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aradhya Bhatia a-bhatia1@ti.com
commit 132bdcec399be6ae947582249a134b38cf56731c upstream.
The crtc_* mode parameters do not get generated (duplicated in this case) from the regular parameters before the mode validation phase begins.
The rest of the code conditionally uses the crtc_* parameters only during the bridge enable phase, but sticks to the regular parameters for mode validation. In this singular instance, however, the driver tries to use the crtc_clock parameter even during the mode validation, causing the validation to fail.
Allow the D-Phy config checks to use mode->clock instead of mode->crtc_clock during mode_valid checks, like everywhere else in the driver.
Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Cc: stable@vger.kernel.org Reviewed-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Tested-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Aradhya Bhatia a-bhatia1@ti.com Signed-off-by: Aradhya Bhatia aradhya.bhatia@linux.dev Link: https://lore.kernel.org/r/20250329113925.68204-4-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -568,13 +568,14 @@ static int cdns_dsi_check_conf(struct cd struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; unsigned long dsi_hss_hsa_hse_hbp; unsigned int nlanes = output->dev->lanes; + int mode_clock = (mode_valid_check ? mode->clock : mode->crtc_clock); int ret;
ret = cdns_dsi_mode2cfg(dsi, mode, dsi_cfg, mode_valid_check); if (ret) return ret;
- phy_mipi_dphy_get_default_config(mode->crtc_clock * 1000, + phy_mipi_dphy_get_default_config(mode_clock * 1000, mipi_dsi_pixel_format_to_bpp(output->dev->format), nlanes, phy_cfg);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aradhya Bhatia a-bhatia1@ti.com
commit fd2611c13f69cbbc6b81d9fc7502abf4f7031d21 upstream.
The driver code doesn't have a Phy de-initialization path as yet, and so it does not clear the phy_initialized flag while suspending. This is a problem because after resume the driver looks at this flag to determine if a Phy re-initialization is required or not. It is in fact required because the hardware is resuming from a suspend, but the driver does not carry out any re-initialization causing the D-Phy to not work at all.
Call the counterparts of phy_init() and phy_power_on(), that are phy_exit() and phy_power_off(), from _bridge_post_disable(), and clear the flags so that the Phy can be initialized again when required.
Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Cc: stable@vger.kernel.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Tested-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Aradhya Bhatia a-bhatia1@ti.com Signed-off-by: Aradhya Bhatia aradhya.bhatia@linux.dev Link: https://lore.kernel.org/r/20250329113925.68204-3-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -681,6 +681,11 @@ static void cdns_dsi_bridge_post_disable struct cdns_dsi_input *input = bridge_to_cdns_dsi_input(bridge); struct cdns_dsi *dsi = input_to_dsi(input);
+ dsi->phy_initialized = false; + dsi->link_initialized = false; + phy_power_off(dsi->dphy); + phy_exit(dsi->dphy); + pm_runtime_put(dsi->base.dev); }
@@ -1153,7 +1158,6 @@ static int __maybe_unused cdns_dsi_suspe clk_disable_unprepare(dsi->dsi_sys_clk); clk_disable_unprepare(dsi->dsi_p_clk); reset_control_assert(dsi->dsi_p_rst); - dsi->link_initialized = false; return 0; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aradhya Bhatia a-bhatia1@ti.com
commit 688eb4d465484bc2a3471a6a6f06f833b58c7867 upstream.
Fix the OF node pointer passed to the of_drm_find_bridge() call to find the next bridge in the display chain.
The code to find the next panel (and create its panel-bridge) works fine, but to find the next (non-panel) bridge does not.
To find the next bridge in the pipeline, we need to pass "np" - the OF node pointer of the next entity in the devicetree chain. Passing "of_node" to of_drm_find_bridge (which is what the code does currently) will fetch the bridge for the cdns-dsi which is not what's required.
Fix that.
Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver") Cc: stable@vger.kernel.org Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Tested-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Aradhya Bhatia a-bhatia1@ti.com Signed-off-by: Aradhya Bhatia aradhya.bhatia@linux.dev Link: https://lore.kernel.org/r/20250329113925.68204-2-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -958,7 +958,7 @@ static int cdns_dsi_attach(struct mipi_d bridge = drm_panel_bridge_add_typed(panel, DRM_MODE_CONNECTOR_DSI); } else { - bridge = of_drm_find_bridge(dev->dev.of_node); + bridge = of_drm_find_bridge(np); if (!bridge) bridge = ERR_PTR(-EINVAL); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aradhya Bhatia a-bhatia1@ti.com
commit c6a7ef0d4856b9629df390e9935d7fd67fe39f81 upstream.
Check for the return value of the phy_mipi_dphy_get_default_config() call, and in case of an error, return back the same.
Fixes: fced5a364dee ("drm/bridge: cdns: Convert to phy framework") Cc: stable@vger.kernel.org Reviewed-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Reviewed-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Tested-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Aradhya Bhatia a-bhatia1@ti.com Signed-off-by: Aradhya Bhatia aradhya.bhatia@linux.dev Link: https://lore.kernel.org/r/20250329113925.68204-5-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -575,9 +575,11 @@ static int cdns_dsi_check_conf(struct cd if (ret) return ret;
- phy_mipi_dphy_get_default_config(mode_clock * 1000, - mipi_dsi_pixel_format_to_bpp(output->dev->format), - nlanes, phy_cfg); + ret = phy_mipi_dphy_get_default_config(mode_clock * 1000, + mipi_dsi_pixel_format_to_bpp(output->dev->format), + nlanes, phy_cfg); + if (ret) + return ret;
ret = cdns_dsi_adjust_phy_config(dsi, dsi_cfg, phy_cfg, mode, mode_valid_check); if (ret)
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aradhya Bhatia a-bhatia1@ti.com
commit 47c03e6660e96cbba0239125b1d4a9db3c724b1d upstream.
Once the DSI Link and DSI Phy are initialized, the code needs to wait for Clk and Data Lanes to be ready, before continuing configuration. This is in accordance with the DSI Start-up procedure, found in the Technical Reference Manual of Texas Instrument's J721E SoC[0] which houses this DSI TX controller.
If the previous bridge (or crtc/encoder) are configured pre-maturely, the input signal FIFO gets corrupt. This introduces a color-shift on the display.
Allow the driver to wait for the clk and data lanes to get ready during DSI enable.
[0]: See section 12.6.5.7.3 "Start-up Procedure" in J721E SoC TRM TRM Link: http://www.ti.com/lit/pdf/spruil1
Fixes: e19233955d9e ("drm/bridge: Add Cadence DSI driver") Cc: stable@vger.kernel.org Tested-by: Dominik Haller d.haller@phytec.de Reviewed-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Tested-by: Tomi Valkeinen tomi.valkeinen@ideasonboard.com Signed-off-by: Aradhya Bhatia a-bhatia1@ti.com Signed-off-by: Aradhya Bhatia aradhya.bhatia@linux.dev Link: https://lore.kernel.org/r/20250329113925.68204-6-aradhya.bhatia@linux.dev Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@oss.qualcomm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c +++ b/drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c @@ -769,7 +769,7 @@ static void cdns_dsi_bridge_enable(struc struct phy_configure_opts_mipi_dphy *phy_cfg = &output->phy_opts.mipi_dphy; unsigned long tx_byte_period; struct cdns_dsi_cfg dsi_cfg; - u32 tmp, reg_wakeup, div; + u32 tmp, reg_wakeup, div, status; int nlanes;
if (WARN_ON(pm_runtime_get_sync(dsi->base.dev) < 0)) @@ -786,6 +786,19 @@ static void cdns_dsi_bridge_enable(struc cdns_dsi_hs_init(dsi); cdns_dsi_init_link(dsi);
+ /* + * Now that the DSI Link and DSI Phy are initialized, + * wait for the CLK and Data Lanes to be ready. + */ + tmp = CLK_LANE_RDY; + for (int i = 0; i < nlanes; i++) + tmp |= DATA_LANE_RDY(i); + + if (readl_poll_timeout(dsi->regs + MCTL_MAIN_STS, status, + (tmp == (status & tmp)), 100, 500000)) + dev_err(dsi->base.dev, + "Timed Out: DSI-DPhy Clock and Data Lanes not ready.\n"); + writel(HBP_LEN(dsi_cfg.hbp) | HSA_LEN(dsi_cfg.hsa), dsi->regs + VID_HSIZE1); writel(HFP_LEN(dsi_cfg.hfp) | HACT_LEN(dsi_cfg.hact),
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang vulab@iscas.ac.cn
commit c3e9826a22027a21d998d3e64882fa377b613006 upstream.
The function mod_hdcp_hdcp1_enable_encryption() calls the function get_first_active_display(), but does not check its return value. The return value is a null pointer if the display list is empty. This will lead to a null pointer dereference in mod_hdcp_hdcp2_enable_encryption().
Add a null pointer check for get_first_active_display() and return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND if the function return null.
Fixes: 2deade5ede56 ("drm/amd/display: Remove hdcp display state with mst fix") Signed-off-by: Wentao Liang vulab@iscas.ac.cn Reviewed-by: Alex Hung alex.hung@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org # v5.8 Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c @@ -368,6 +368,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_enab struct mod_hdcp_display *display = get_first_active_display(hdcp); enum mod_hdcp_status status = MOD_HDCP_STATUS_SUCCESS;
+ if (!display) + return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND; + mutex_lock(&psp->hdcp_context.mutex); hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf; memset(hdcp_cmd, 0, sizeof(struct ta_hdcp_shared_memory));
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Olender john.olender@gmail.com
commit 4d2f6b4e4c7ed32e7fa39fcea37344a9eab99094 upstream.
The drm_mm allocator tolerated being passed end > mm->size, but the drm_buddy allocator does not.
Restore the pre-buddy-allocator behavior of allowing such placements.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3448 Signed-off-by: John Olender john.olender@gmail.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Reviewed-by: Arunpravin Paneer Selvam Arunpravin.PaneerSelvam@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -463,7 +463,7 @@ static int amdgpu_vram_mgr_new(struct tt int r;
lpfn = (u64)place->lpfn << PAGE_SHIFT; - if (!lpfn) + if (!lpfn || lpfn > man->size) lpfn = man->size;
fpfn = (u64)place->fpfn << PAGE_SHIFT;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher alexander.deucher@amd.com
commit 5cccf10f652122a17b40df9d672ccf2ed69cd82f upstream.
Users have reported that they have to reduce the level of undervolting to acheive stability when dynamic workload profiles are enabled on GC 10.3.x. Disable dynamic workload profiles if the user has enabled OD.
Fixes: b9467983b774 ("drm/amdgpu: add dynamic workload profile switching for gfx10") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4262 Reviewed-by: Kenneth Feng kenneth.feng@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org # 6.15.x Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 8 ++++++++ drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 1 + 3 files changed, 31 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -2192,6 +2192,9 @@ void amdgpu_gfx_profile_ring_begin_use(s enum PP_SMC_POWER_PROFILE profile; int r;
+ if (amdgpu_dpm_is_overdrive_enabled(adev)) + return; + if (adev->gfx.num_gfx_rings) profile = PP_SMC_POWER_PROFILE_FULLSCREEN3D; else @@ -2222,6 +2225,11 @@ void amdgpu_gfx_profile_ring_begin_use(s
void amdgpu_gfx_profile_ring_end_use(struct amdgpu_ring *ring) { + struct amdgpu_device *adev = ring->adev; + + if (amdgpu_dpm_is_overdrive_enabled(adev)) + return; + atomic_dec(&ring->adev->gfx.total_submission_cnt);
schedule_delayed_work(&ring->adev->gfx.idle_work, GFX_PROFILE_IDLE_TIMEOUT); --- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c +++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c @@ -1654,6 +1654,28 @@ int amdgpu_dpm_is_overdrive_supported(st } }
+int amdgpu_dpm_is_overdrive_enabled(struct amdgpu_device *adev) +{ + if (is_support_sw_smu(adev)) { + struct smu_context *smu = adev->powerplay.pp_handle; + + return smu->od_enabled; + } else { + struct pp_hwmgr *hwmgr; + + /* + * dpm on some legacy asics don't carry od_enabled member + * as its pp_handle is casted directly from adev. + */ + if (amdgpu_dpm_is_legacy_dpm(adev)) + return false; + + hwmgr = (struct pp_hwmgr *)adev->powerplay.pp_handle; + + return hwmgr->od_enabled; + } +} + int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev, const char *buf, size_t size) --- a/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h +++ b/drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h @@ -559,6 +559,7 @@ int amdgpu_dpm_get_smu_prv_buf_details(s void **addr, size_t *size); int amdgpu_dpm_is_overdrive_supported(struct amdgpu_device *adev); +int amdgpu_dpm_is_overdrive_enabled(struct amdgpu_device *adev); int amdgpu_dpm_set_pp_table(struct amdgpu_device *adev, const char *buf, size_t size);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhongwei Zhang Zhongwei.Zhang@amd.com
commit 893f07452bca56ff146a6be02b3294a9ea23d18a upstream.
[Why] Only OLED panels require non-zero pre_T11_delay defaultly. Others should be controlled by power sequence.
[How] For non OLED, pre_T11_delay delay in code should be zero. Also post_T7_delay.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Reviewed-by: Charlene Liu charlene.liu@amd.com Signed-off-by: Zhongwei Zhang Zhongwei.Zhang@amd.com Signed-off-by: Wayne Lin wayne.lin@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c @@ -952,8 +952,8 @@ void dce110_edp_backlight_control( struct dc_context *ctx = link->ctx; struct bp_transmitter_control cntl = { 0 }; uint8_t pwrseq_instance = 0; - unsigned int pre_T11_delay = OLED_PRE_T11_DELAY; - unsigned int post_T7_delay = OLED_POST_T7_DELAY; + unsigned int pre_T11_delay = (link->dpcd_sink_ext_caps.bits.oled ? OLED_PRE_T11_DELAY : 0); + unsigned int post_T7_delay = (link->dpcd_sink_ext_caps.bits.oled ? OLED_POST_T7_DELAY : 0);
if (dal_graphics_object_id_get_connector_id(link->link_enc->connector) != CONNECTOR_ID_EDP) { @@ -1069,7 +1069,8 @@ void dce110_edp_backlight_control( if (!enable) { /*follow oem panel config's requirement*/ pre_T11_delay += link->panel_config.pps.extra_pre_t11_ms; - msleep(pre_T11_delay); + if (pre_T11_delay) + msleep(pre_T11_delay); } }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Auld matthew.auld@intel.com
commit a63e99b4d6d3a0353ef47146dd5bd562f08e1786 upstream.
In xe_vm_close_and_put() we need to be able to call flush_work(rebind_work), however during vm creation we can call this on the error path, before having actually set up the worker, leading to a splat from flush_work().
It looks like we can simply move the worker init step earlier to fix this.
Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld matthew.auld@intel.com Cc: Matthew Brost matthew.brost@intel.com Cc: stable@vger.kernel.org # v6.8+ Reviewed-by: Matthew Brost matthew.brost@intel.com Link: https://lore.kernel.org/r/20250514152424.149591-3-matthew.auld@intel.com (cherry picked from commit 96af397aa1a2d1032a6e28ff3f4bc0ab4be40e1d) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/xe_vm.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/xe/xe_vm.c +++ b/drivers/gpu/drm/xe/xe_vm.c @@ -1678,8 +1678,10 @@ struct xe_vm *xe_vm_create(struct xe_dev * scheduler drops all the references of it, hence protecting the VM * for this case is necessary. */ - if (flags & XE_VM_FLAG_LR_MODE) + if (flags & XE_VM_FLAG_LR_MODE) { + INIT_WORK(&vm->preempt.rebind_work, preempt_rebind_work_func); xe_pm_runtime_get_noresume(xe); + }
if (flags & XE_VM_FLAG_FAULT_MODE) { err = xe_svm_init(vm); @@ -1730,10 +1732,8 @@ struct xe_vm *xe_vm_create(struct xe_dev vm->batch_invalidate_tlb = true; }
- if (vm->flags & XE_VM_FLAG_LR_MODE) { - INIT_WORK(&vm->preempt.rebind_work, preempt_rebind_work_func); + if (vm->flags & XE_VM_FLAG_LR_MODE) vm->batch_invalidate_tlb = false; - }
/* Fill pt_root after allocating scratch tables */ for_each_tile(tile, xe, id) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Auld matthew.auld@intel.com
commit 0ee54d5cacc0276ec631ac149825a24b59c51c38 upstream.
Customer is reporting a really subtle issue where we get random DMAR faults, hangs and other nasties for kernel migration jobs when stressing stuff like s2idle/s3/s4. The explosions seems to happen somewhere after resuming the system with splats looking something like:
PM: suspend exit rfkill: input handler disabled xe 0000:00:02.0: [drm] GT0: Engine reset: engine_class=bcs, logical_mask: 0x2, guc_id=0 xe 0000:00:02.0: [drm] GT0: Timedout job: seqno=24496, lrc_seqno=24496, guc_id=0, flags=0x13 in no process [-1] xe 0000:00:02.0: [drm] GT0: Kernel-submitted job timed out
The likely cause appears to be a race between suspend cancelling the worker that processes the free_job()'s, such that we still have pending jobs to be freed after the cancel. Following from this, on resume the pending_list will now contain at least one already complete job, but it looks like we call drm_sched_resubmit_jobs(), which will then call run_job() on everything still on the pending_list. But if the job was already complete, then all the resources tied to the job, like the bb itself, any memory that is being accessed, the iommu mappings etc. might be long gone since those are usually tied to the fence signalling.
This scenario can be seen in ftrace when running a slightly modified xe_pm IGT (kernel was only modified to inject artificial latency into free_job to make the race easier to hit):
xe_sched_job_run: dev=0000:00:02.0, fence=0xffff888276cc8540, seqno=0, lrc_seqno=0, gt=0, guc_id=0, batch_addr=0x000000146910 ... xe_exec_queue_stop: dev=0000:00:02.0, 3:0x2, gt=0, width=1, guc_id=0, guc_state=0x0, flags=0x13 xe_exec_queue_stop: dev=0000:00:02.0, 3:0x2, gt=0, width=1, guc_id=1, guc_state=0x0, flags=0x4 xe_exec_queue_stop: dev=0000:00:02.0, 4:0x1, gt=1, width=1, guc_id=0, guc_state=0x0, flags=0x3 xe_exec_queue_stop: dev=0000:00:02.0, 1:0x1, gt=1, width=1, guc_id=1, guc_state=0x0, flags=0x3 xe_exec_queue_stop: dev=0000:00:02.0, 4:0x1, gt=1, width=1, guc_id=2, guc_state=0x0, flags=0x3 xe_exec_queue_resubmit: dev=0000:00:02.0, 3:0x2, gt=0, width=1, guc_id=0, guc_state=0x0, flags=0x13 xe_sched_job_run: dev=0000:00:02.0, fence=0xffff888276cc8540, seqno=0, lrc_seqno=0, gt=0, guc_id=0, batch_addr=0x000000146910 ... ..... xe_exec_queue_memory_cat_error: dev=0000:00:02.0, 3:0x2, gt=0, width=1, guc_id=0, guc_state=0x3, flags=0x13
So the job_run() is clearly triggered twice for the same job, even though the first must have already signalled to completion during suspend. We can also see a CAT error after the re-submit.
To prevent this only resubmit jobs on the pending_list that have not yet signalled.
v2: - Make sure to re-arm the fence callbacks with sched_start(). v3 (Matt B): - Stop using drm_sched_resubmit_jobs(), which appears to be deprecated and just open-code a simple loop such that we skip calling run_job() on anything already signalled.
Link: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/4856 Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Signed-off-by: Matthew Auld matthew.auld@intel.com Cc: Thomas Hellström thomas.hellstrom@linux.intel.com Cc: Matthew Brost matthew.brost@intel.com Cc: William Tseng william.tseng@intel.com Cc: stable@vger.kernel.org # v6.8+ Reviewed-by: Matthew Brost matthew.brost@intel.com Reviewed-by: Tejas Upadhyay tejas.upadhyay@intel.com Link: https://lore.kernel.org/r/20250528113328.289392-2-matthew.auld@intel.com (cherry picked from commit 38fafa9f392f3110d2de431432d43f4eef99cd1b) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/xe_gpu_scheduler.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/xe/xe_gpu_scheduler.h +++ b/drivers/gpu/drm/xe/xe_gpu_scheduler.h @@ -51,7 +51,15 @@ static inline void xe_sched_tdr_queue_im
static inline void xe_sched_resubmit_jobs(struct xe_gpu_scheduler *sched) { - drm_sched_resubmit_jobs(&sched->base); + struct drm_sched_job *s_job; + + list_for_each_entry(s_job, &sched->base.pending_list, list) { + struct drm_sched_fence *s_fence = s_job->s_fence; + struct dma_fence *hw_fence = s_fence->parent; + + if (hw_fence && !dma_fence_is_signaled(hw_fence)) + sched->base.ops->run_job(s_job); + } }
static inline bool
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Auld matthew.auld@intel.com
commit 2e824747cfbdf1fba88df5e5800d284b2602ae8f upstream.
Daniele noticed that the fix in commit 2d2be279f1ca ("drm/xe: fix UAF around queue destruction") looks to have been unintentionally removed as part of handling a conflict in some past merge commit. Add it back.
Fixes: ac44ff7cec33 ("Merge tag 'drm-xe-fixes-2024-10-10' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes") Reported-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Signed-off-by: Matthew Auld matthew.auld@intel.com Cc: Matthew Brost matthew.brost@intel.com Cc: stable@vger.kernel.org # v6.12+ Reviewed-by: Matthew Brost matthew.brost@intel.com Link: https://lore.kernel.org/r/20250603174213.1543579-2-matthew.auld@intel.com (cherry picked from commit 9d9fca62dc49d96f97045b6d8e7402a95f8cf92a) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/xe_guc_submit.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
--- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -229,6 +229,17 @@ static bool exec_queue_killed_or_banned_ static void guc_submit_fini(struct drm_device *drm, void *arg) { struct xe_guc *guc = arg; + struct xe_device *xe = guc_to_xe(guc); + struct xe_gt *gt = guc_to_gt(guc); + int ret; + + ret = wait_event_timeout(guc->submission_state.fini_wq, + xa_empty(&guc->submission_state.exec_queue_lookup), + HZ * 5); + + drain_workqueue(xe->destroy_wq); + + xe_gt_assert(gt, ret);
xa_destroy(&guc->submission_state.exec_queue_lookup); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yihan Zhu Yihan.Zhu@amd.com
commit 158f9944ac05dafd2d3a23d0688e6cf40ef68b90 upstream.
[WHY & HOW] Fix RMCM programming sequence errors and mapping issues to pass the RMCM test.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Reviewed-by: Dmytro Laktyushkin dmytro.laktyushkin@amd.com Signed-off-by: Yihan Zhu Yihan.Zhu@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 11baa4975025033547f45f5894087a0dda6efbb8) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/src/dml2_core/dml2_core_dcn4_calcs.c @@ -4750,7 +4750,10 @@ static void calculate_tdlut_setting( //the tdlut is fetched during the 2 row times of prefetch. if (p->setup_for_tdlut) { *p->tdlut_groups_per_2row_ub = (unsigned int)math_ceil2((double) *p->tdlut_bytes_per_frame / *p->tdlut_bytes_per_group, 1); - *p->tdlut_opt_time = (*p->tdlut_bytes_per_frame - p->cursor_buffer_size * 1024) / tdlut_drain_rate; + if (*p->tdlut_bytes_per_frame > p->cursor_buffer_size * 1024) + *p->tdlut_opt_time = (*p->tdlut_bytes_per_frame - p->cursor_buffer_size * 1024) / tdlut_drain_rate; + else + *p->tdlut_opt_time = 0; *p->tdlut_drain_time = p->cursor_buffer_size * 1024 / tdlut_drain_rate; *p->tdlut_bytes_to_deliver = (unsigned int) (p->cursor_buffer_size * 1024.0); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sonny Jiang sonny.jiang@amd.com
commit 46e15197b513e60786a44107759d6ca293d6288c upstream.
Add a protection to ensure programming are all complete prior VCPU starting. This is a WA for an unintended VCPU running.
Signed-off-by: Sonny Jiang sonny.jiang@amd.com Acked-by: Leo Liu leo.liu@amd.com Reviewed-by: Ruijing Dong ruijing.dong@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit c29521b529fa5e225feaf709d863a636ca0cbbfa) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c @@ -629,6 +629,9 @@ static int vcn_v5_0_1_start_dpg_mode(str if (indirect) amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM);
+ /* resetting ring, fw should not check RB ring */ + fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; + /* Pause dpg */ vcn_v5_0_1_pause_dpg_mode(vinst, &state);
@@ -641,7 +644,7 @@ static int vcn_v5_0_1_start_dpg_mode(str tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK); WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); - fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET; + WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0); WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0);
@@ -652,6 +655,7 @@ static int vcn_v5_0_1_start_dpg_mode(str tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE); tmp |= VCN_RB_ENABLE__RB1_EN_MASK; WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp); + /* resetting done, fw can check RB ring */ fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
WREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Min Frank.Min@amd.com
commit 0bbf5fd86c585d437b75003f11365b324360a5d6 upstream.
1. add kicker device list 2. add kicker device checking helper function
Signed-off-by: Frank Min Frank.Min@amd.com Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 09aa2b408f4ab689c3541d22b0968de0392ee406) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 17 +++++++++++++++++ drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 6 ++++++ 2 files changed, 23 insertions(+)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c @@ -30,6 +30,10 @@
#define AMDGPU_UCODE_NAME_MAX (128)
+static const struct kicker_device kicker_device_list[] = { + {0x744B, 0x00}, +}; + static void amdgpu_ucode_print_common_hdr(const struct common_firmware_header *hdr) { DRM_DEBUG("size_bytes: %u\n", le32_to_cpu(hdr->size_bytes)); @@ -1384,6 +1388,19 @@ static const char *amdgpu_ucode_legacy_n return NULL; }
+bool amdgpu_is_kicker_fw(struct amdgpu_device *adev) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(kicker_device_list); i++) { + if (adev->pdev->device == kicker_device_list[i].device && + adev->pdev->revision == kicker_device_list[i].revision) + return true; + } + + return false; +} + void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len) { int maj, min, rev; --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h @@ -602,6 +602,11 @@ struct amdgpu_firmware { uint64_t fw_buf_mc; };
+struct kicker_device{ + unsigned short device; + u8 revision; +}; + void amdgpu_ucode_print_mc_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_smc_hdr(const struct common_firmware_header *hdr); void amdgpu_ucode_print_imu_hdr(const struct common_firmware_header *hdr); @@ -629,5 +634,6 @@ amdgpu_ucode_get_load_type(struct amdgpu const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id);
void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len); +bool amdgpu_is_kicker_fw(struct amdgpu_device *adev);
#endif
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung alex.hung@amd.com
commit b669507b637eb6b1aaecf347f193efccc65d756e upstream.
[WHAT]
hws was checked for null earlier in dce110_blank_stream, indicating hws can be null, and should be checked whenever it is used.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Reviewed-by: Aurabindo Pillai aurabindo.pillai@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Signed-off-by: Aurabindo Pillai aurabindo.pillai@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 79db43611ff61280b6de58ce1305e0b2ecf675ad) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c @@ -1222,7 +1222,7 @@ void dce110_blank_stream(struct pipe_ctx struct dce_hwseq *hws = link->dc->hwseq;
if (link->local_sink && link->local_sink->sink_signal == SIGNAL_TYPE_EDP) { - if (!link->skip_implict_edp_power_control) + if (!link->skip_implict_edp_power_control && hws) hws->funcs.edp_backlight_control(link, false); link->dc->hwss.set_abm_immediate_disable(pipe_ctx); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas De Marchi lucas.demarchi@intel.com
commit 87a15c89d8c7b00b0fc94e0d4f554f7ee2fe6961 upstream.
It should rather use xe_map_memset() as the BO is created with XE_BO_FLAG_VRAM_IF_DGFX in xe_guc_pc_init().
Fixes: dd08ebf6c352 ("drm/xe: Introduce a new DRM driver for Intel GPUs") Cc: stable@vger.kernel.org Reviewed-by: Matthew Brost matthew.brost@intel.com Link: https://lore.kernel.org/r/20250612-vmap-vaddr-v1-1-26238ed443eb@intel.com Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com (cherry picked from commit 21cf47d89fba353b2d5915ba4718040c4cb955d3) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/xe_guc_pc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/xe/xe_guc_pc.c +++ b/drivers/gpu/drm/xe/xe_guc_pc.c @@ -1053,7 +1053,7 @@ int xe_guc_pc_start(struct xe_guc_pc *pc goto out; }
- memset(pc->bo->vmap.vaddr, 0, size); + xe_map_memset(xe, &pc->bo->vmap, 0, 0, size); slpc_shared_data_write(pc, header.size, size);
earlier = ktime_get();
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas De Marchi lucas.demarchi@intel.com
commit 1e1981b16bb1bbe2fafa57ed439b45cb5b34e32d upstream.
If device wedges on e.g. GuC upload, the submission is not yet enabled and the state is not even initialized. Protect the wedge call so it does nothing in this case. It fixes the following splat:
[] xe 0000:bf:00.0: [drm] device wedged, needs recovery [] ------------[ cut here ]------------ [] DEBUG_LOCKS_WARN_ON(lock->magic != lock) [] WARNING: CPU: 48 PID: 312 at kernel/locking/mutex.c:564 __mutex_lock+0x8a1/0xe60 ... [] RIP: 0010:__mutex_lock+0x8a1/0xe60 [] mutex_lock_nested+0x1b/0x30 [] xe_guc_submit_wedge+0x80/0x2b0 [xe]
Reviewed-by: Balasubramani Vivekanandan balasubramani.vivekanandan@intel.com Link: https://lore.kernel.org/r/20250402-warn-after-wedge-v1-1-93e971511fa5@intel.... Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/xe_guc_submit.c | 9 +++++++++ drivers/gpu/drm/xe/xe_guc_types.h | 5 +++++ 2 files changed, 14 insertions(+)
--- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -311,6 +311,8 @@ int xe_guc_submit_init(struct xe_guc *gu
primelockdep(guc);
+ guc->submission_state.initialized = true; + return drmm_add_action_or_reset(&xe->drm, guc_submit_fini, guc); }
@@ -845,6 +847,13 @@ void xe_guc_submit_wedge(struct xe_guc *
xe_gt_assert(guc_to_gt(guc), guc_to_xe(guc)->wedged.mode);
+ /* + * If device is being wedged even before submission_state is + * initialized, there's nothing to do here. + */ + if (!guc->submission_state.initialized) + return; + err = devm_add_action_or_reset(guc_to_xe(guc)->drm.dev, guc_submit_wedged_fini, guc); if (err) { --- a/drivers/gpu/drm/xe/xe_guc_types.h +++ b/drivers/gpu/drm/xe/xe_guc_types.h @@ -89,6 +89,11 @@ struct xe_guc { struct mutex lock; /** @submission_state.enabled: submission is enabled */ bool enabled; + /** + * @submission_state.initialized: mark when submission state is + * even initialized - before that not even the lock is valid + */ + bool initialized; /** @submission_state.fini_wq: submit fini wait queue */ wait_queue_head_t fini_wq; } submission_state;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com
commit a39d082c3553d35b4fe5585e1e2fb221c130cae8 upstream.
When the GuC fails to load we declare the device wedged. However, the very first GuC load attempt on GT0 (from xe_gt_init_hwconfig) is done before the GT1 GuC objects are initialized, so things go bad when the wedge code attempts to cleanup GT1. To fix this, check the initialization status in the functions called during wedge.
Fixes: 7dbe8af13c18 ("drm/xe: Wedge the entire device") Signed-off-by: Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com Cc: Rodrigo Vivi rodrigo.vivi@intel.com Cc: Matthew Brost matthew.brost@intel.com Cc: Jonathan Cavitt jonathan.cavitt@intel.com Cc: Lucas De Marchi lucas.demarchi@intel.com Cc: Zhanjun Dong zhanjun.dong@intel.com Cc: stable@vger.kernel.org # v6.12+: 1e1981b16bb1: drm/xe: Fix taking invalid lock on wedge Cc: stable@vger.kernel.org # v6.12+ Reviewed-by: Jonathan Cavitt jonathan.cavitt@intel.com Reviewed-by: Lucas De Marchi lucas.demarchi@intel.com Link: https://lore.kernel.org/r/20250611214453.1159846-2-daniele.ceraolospurio@int... Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com (cherry picked from commit 0b93b7dcd9eb888a6ac7546560877705d4ad61bf) Signed-off-by: Thomas Hellström thomas.hellstrom@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 8 ++++++++ drivers/gpu/drm/xe/xe_guc_ct.c | 7 +++++-- drivers/gpu/drm/xe/xe_guc_ct.h | 5 +++++ drivers/gpu/drm/xe/xe_guc_submit.c | 3 +++ 4 files changed, 21 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c +++ b/drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c @@ -138,6 +138,14 @@ void xe_gt_tlb_invalidation_reset(struct int pending_seqno;
/* + * we can get here before the CTs are even initialized if we're wedging + * very early, in which case there are not going to be any pending + * fences so we can bail immediately. + */ + if (!xe_guc_ct_initialized(>->uc.guc.ct)) + return; + + /* * CT channel is already disabled at this point. No new TLB requests can * appear. */ --- a/drivers/gpu/drm/xe/xe_guc_ct.c +++ b/drivers/gpu/drm/xe/xe_guc_ct.c @@ -515,6 +515,9 @@ void xe_guc_ct_disable(struct xe_guc_ct */ void xe_guc_ct_stop(struct xe_guc_ct *ct) { + if (!xe_guc_ct_initialized(ct)) + return; + xe_guc_ct_set_state(ct, XE_GUC_CT_STATE_STOPPED); stop_g2h_handler(ct); } @@ -761,7 +764,7 @@ static int __guc_ct_send_locked(struct x u16 seqno; int ret;
- xe_gt_assert(gt, ct->state != XE_GUC_CT_STATE_NOT_INITIALIZED); + xe_gt_assert(gt, xe_guc_ct_initialized(ct)); xe_gt_assert(gt, !g2h_len || !g2h_fence); xe_gt_assert(gt, !num_g2h || !g2h_fence); xe_gt_assert(gt, !g2h_len || num_g2h); @@ -1344,7 +1347,7 @@ static int g2h_read(struct xe_guc_ct *ct u32 action; u32 *hxg;
- xe_gt_assert(gt, ct->state != XE_GUC_CT_STATE_NOT_INITIALIZED); + xe_gt_assert(gt, xe_guc_ct_initialized(ct)); lockdep_assert_held(&ct->fast_lock);
if (ct->state == XE_GUC_CT_STATE_DISABLED) --- a/drivers/gpu/drm/xe/xe_guc_ct.h +++ b/drivers/gpu/drm/xe/xe_guc_ct.h @@ -22,6 +22,11 @@ void xe_guc_ct_snapshot_print(struct xe_ void xe_guc_ct_snapshot_free(struct xe_guc_ct_snapshot *snapshot); void xe_guc_ct_print(struct xe_guc_ct *ct, struct drm_printer *p, bool want_ctb);
+static inline bool xe_guc_ct_initialized(struct xe_guc_ct *ct) +{ + return ct->state != XE_GUC_CT_STATE_NOT_INITIALIZED; +} + static inline bool xe_guc_ct_enabled(struct xe_guc_ct *ct) { return ct->state == XE_GUC_CT_STATE_ENABLED; --- a/drivers/gpu/drm/xe/xe_guc_submit.c +++ b/drivers/gpu/drm/xe/xe_guc_submit.c @@ -1759,6 +1759,9 @@ int xe_guc_submit_reset_prepare(struct x { int ret;
+ if (!guc->submission_state.initialized) + return 0; + /* * Using an atomic here rather than submission_state.lock as this * function can be called while holding the CT lock (engine reset
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä ville.syrjala@linux.intel.com
commit c464ce6af332e7c802c36cd337cacf81db05400c upstream.
BXT_MIPI_TRANS_VTOTAL must be programmed with vtotal-1 instead of vtotal. Make it so.
Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20250314150136.22564-1-ville.s... Reviewed-by: Jani Nikula jani.nikula@intel.com (cherry picked from commit 7b3685c9b38c3097f465efec8b24dbed63258cf6) Signed-off-by: Joonas Lahtinen joonas.lahtinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/vlv_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/i915/display/vlv_dsi.c +++ b/drivers/gpu/drm/i915/display/vlv_dsi.c @@ -1060,7 +1060,7 @@ static void bxt_dsi_get_pipe_config(stru BXT_MIPI_TRANS_VACTIVE(port)); adjusted_mode->crtc_vtotal = intel_de_read(display, - BXT_MIPI_TRANS_VTOTAL(port)); + BXT_MIPI_TRANS_VTOTAL(port)) + 1;
hactive = adjusted_mode->crtc_hdisplay; hfp = intel_de_read(display, MIPI_HFP_COUNT(display, port)); @@ -1265,7 +1265,7 @@ static void set_dsi_timings(struct intel intel_de_write(display, BXT_MIPI_TRANS_VACTIVE(port), adjusted_mode->crtc_vdisplay); intel_de_write(display, BXT_MIPI_TRANS_VTOTAL(port), - adjusted_mode->crtc_vtotal); + adjusted_mode->crtc_vtotal - 1); }
intel_de_write(display, MIPI_HACTIVE_AREA_COUNT(display, port),
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jesse Zhang jesse.zhang@amd.com
commit 7f3b16f3f229e37cc3e02e9e4e7106c523b119e9 upstream.
This commit makes two key fixes to SDMA v4.4.2 handling:
1. disable UTC_L1 in sdma_cntl register when stopping SDMA engines by reading the current value before modifying UTC_L1_ENABLE bit.
2. Ensure UTC_L1_ENABLE is consistently managed by: - Adding the missing register write when enabling UTC_L1 during start - Keeping UTC_L1 enabled by default as per hardware requirements
v2: Correct SDMA_CNTL setting (Philip)
Suggested-by: Jonathan Kim jonathan.kim@amd.com Signed-off-by: Jesse Zhang Jesse.Zhang@amd.com Acked-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 375bf564654e85a7b1b0657b191645b3edca1bda) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c @@ -489,7 +489,7 @@ static void sdma_v4_4_2_inst_gfx_stop(st { struct amdgpu_ring *sdma[AMDGPU_MAX_SDMA_INSTANCES]; u32 doorbell_offset, doorbell; - u32 rb_cntl, ib_cntl; + u32 rb_cntl, ib_cntl, sdma_cntl; int i;
for_each_inst(i, inst_mask) { @@ -501,6 +501,9 @@ static void sdma_v4_4_2_inst_gfx_stop(st ib_cntl = RREG32_SDMA(i, regSDMA_GFX_IB_CNTL); ib_cntl = REG_SET_FIELD(ib_cntl, SDMA_GFX_IB_CNTL, IB_ENABLE, 0); WREG32_SDMA(i, regSDMA_GFX_IB_CNTL, ib_cntl); + sdma_cntl = RREG32_SDMA(i, regSDMA_CNTL); + sdma_cntl = REG_SET_FIELD(sdma_cntl, SDMA_CNTL, UTC_L1_ENABLE, 0); + WREG32_SDMA(i, regSDMA_CNTL, sdma_cntl);
if (sdma[i]->use_doorbell) { doorbell = RREG32_SDMA(i, regSDMA_GFX_DOORBELL); @@ -994,6 +997,7 @@ static int sdma_v4_4_2_inst_start(struct /* set utc l1 enable flag always to 1 */ temp = RREG32_SDMA(i, regSDMA_CNTL); temp = REG_SET_FIELD(temp, SDMA_CNTL, UTC_L1_ENABLE, 1); + WREG32_SDMA(i, regSDMA_CNTL, temp);
if (amdgpu_ip_version(adev, SDMA0_HWIP, 0) < IP_VERSION(4, 4, 5)) { /* enable context empty interrupt during initialization */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher alexander.deucher@amd.com
commit ebe43542702c3d15d1a1d95e8e13b1b54076f05a upstream.
Use the amdgpu fence container so we can store additional data in the fence. This also fixes the start_time handling for MCBP since we were casting the fence to an amdgpu_fence and it wasn't.
Fixes: 3f4c175d62d8 ("drm/amdgpu: MCBP based on DRM scheduler (v9)") Reviewed-by: Christian König christian.koenig@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit bf1cd14f9e2e1fdf981eed273ddd595863f5288c) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 2 - drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 - drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 30 ++++++---------------------- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 +++++------ drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 - drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 16 ++++++++++++++ 6 files changed, 32 insertions(+), 32 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -1902,7 +1902,7 @@ no_preempt: continue; } job = to_amdgpu_job(s_job); - if (preempted && (&job->hw_fence) == fence) + if (preempted && (&job->hw_fence.base) == fence) /* mark the job as preempted */ job->preemption_status |= AMDGPU_IB_PREEMPTED; } --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -6083,7 +6083,7 @@ int amdgpu_device_gpu_recover(struct amd * * job->base holds a reference to parent fence */ - if (job && dma_fence_is_signaled(&job->hw_fence)) { + if (job && dma_fence_is_signaled(&job->hw_fence.base)) { job_signaled = true; dev_info(adev->dev, "Guilty job already signaled, skipping HW reset"); goto skip_hw_reset; --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c @@ -41,22 +41,6 @@ #include "amdgpu_trace.h" #include "amdgpu_reset.h"
-/* - * Fences mark an event in the GPUs pipeline and are used - * for GPU/CPU synchronization. When the fence is written, - * it is expected that all buffers associated with that fence - * are no longer in use by the associated ring on the GPU and - * that the relevant GPU caches have been flushed. - */ - -struct amdgpu_fence { - struct dma_fence base; - - /* RB, DMA, etc. */ - struct amdgpu_ring *ring; - ktime_t start_timestamp; -}; - static struct kmem_cache *amdgpu_fence_slab;
int amdgpu_fence_slab_init(void) @@ -151,12 +135,12 @@ int amdgpu_fence_emit(struct amdgpu_ring am_fence = kmem_cache_alloc(amdgpu_fence_slab, GFP_ATOMIC); if (am_fence == NULL) return -ENOMEM; - fence = &am_fence->base; - am_fence->ring = ring; } else { /* take use of job-embedded fence */ - fence = &job->hw_fence; + am_fence = &job->hw_fence; } + fence = &am_fence->base; + am_fence->ring = ring;
seq = ++ring->fence_drv.sync_seq; if (job && job->job_run_counter) { @@ -718,7 +702,7 @@ void amdgpu_fence_driver_clear_job_fence * it right here or we won't be able to track them in fence_drv * and they will remain unsignaled during sa_bo free. */ - job = container_of(old, struct amdgpu_job, hw_fence); + job = container_of(old, struct amdgpu_job, hw_fence.base); if (!job->base.s_fence && !dma_fence_is_signaled(old)) dma_fence_signal(old); RCU_INIT_POINTER(*ptr, NULL); @@ -780,7 +764,7 @@ static const char *amdgpu_fence_get_time
static const char *amdgpu_job_fence_get_timeline_name(struct dma_fence *f) { - struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); + struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base);
return (const char *)to_amdgpu_ring(job->base.sched)->name; } @@ -810,7 +794,7 @@ static bool amdgpu_fence_enable_signalin */ static bool amdgpu_job_fence_enable_signaling(struct dma_fence *f) { - struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence); + struct amdgpu_job *job = container_of(f, struct amdgpu_job, hw_fence.base);
if (!timer_pending(&to_amdgpu_ring(job->base.sched)->fence_drv.fallback_timer)) amdgpu_fence_schedule_fallback(to_amdgpu_ring(job->base.sched)); @@ -845,7 +829,7 @@ static void amdgpu_job_fence_free(struct struct dma_fence *f = container_of(rcu, struct dma_fence, rcu);
/* free job if fence has a parent job */ - kfree(container_of(f, struct amdgpu_job, hw_fence)); + kfree(container_of(f, struct amdgpu_job, hw_fence.base)); }
/** --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -272,8 +272,8 @@ void amdgpu_job_free_resources(struct am /* Check if any fences where initialized */ if (job->base.s_fence && job->base.s_fence->finished.ops) f = &job->base.s_fence->finished; - else if (job->hw_fence.ops) - f = &job->hw_fence; + else if (job->hw_fence.base.ops) + f = &job->hw_fence.base; else f = NULL;
@@ -290,10 +290,10 @@ static void amdgpu_job_free_cb(struct dr amdgpu_sync_free(&job->explicit_sync);
/* only put the hw fence if has embedded fence */ - if (!job->hw_fence.ops) + if (!job->hw_fence.base.ops) kfree(job); else - dma_fence_put(&job->hw_fence); + dma_fence_put(&job->hw_fence.base); }
void amdgpu_job_set_gang_leader(struct amdgpu_job *job, @@ -322,10 +322,10 @@ void amdgpu_job_free(struct amdgpu_job * if (job->gang_submit != &job->base.s_fence->scheduled) dma_fence_put(job->gang_submit);
- if (!job->hw_fence.ops) + if (!job->hw_fence.base.ops) kfree(job); else - dma_fence_put(&job->hw_fence); + dma_fence_put(&job->hw_fence.base); }
struct dma_fence *amdgpu_job_submit(struct amdgpu_job *job) --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.h @@ -48,7 +48,7 @@ struct amdgpu_job { struct drm_sched_job base; struct amdgpu_vm *vm; struct amdgpu_sync explicit_sync; - struct dma_fence hw_fence; + struct amdgpu_fence hw_fence; struct dma_fence *gang_submit; uint32_t preamble_status; uint32_t preemption_status; --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h @@ -127,6 +127,22 @@ struct amdgpu_fence_driver { struct dma_fence **fences; };
+/* + * Fences mark an event in the GPUs pipeline and are used + * for GPU/CPU synchronization. When the fence is written, + * it is expected that all buffers associated with that fence + * are no longer in use by the associated ring on the GPU and + * that the relevant GPU caches have been flushed. + */ + +struct amdgpu_fence { + struct dma_fence base; + + /* RB, DMA, etc. */ + struct amdgpu_ring *ring; + ktime_t start_timestamp; +}; + extern const struct drm_sched_backend_ops amdgpu_sched_ops;
void amdgpu_fence_driver_clear_job_fences(struct amdgpu_ring *ring);
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frank Min Frank.Min@amd.com
commit 854171405e7f093532b33d8ed0875b9e34fc55b4 upstream.
1. Add kicker firmwares loading for gfx11/smu13/psp13 2. Register additional MODULE_FIRMWARE entries for kicker fws - gc_11_0_0_rlc_kicker.bin - gc_11_0_0_imu_kicker.bin - psp_13_0_0_sos_kicker.bin - psp_13_0_0_ta_kicker.bin - smu_13_0_0_kicker.bin
Signed-off-by: Frank Min Frank.Min@amd.com Reviewed-by: Hawking Zhang Hawking.Zhang@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit fb5ec2174d70a8989bc207d257db90ffeca3b163) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 16 ++++++++++++---- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 5 +++++ drivers/gpu/drm/amd/amdgpu/imu_v11_0.c | 9 +++++++-- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 2 ++ drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 12 +++++++++--- 5 files changed, 35 insertions(+), 9 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c @@ -3521,8 +3521,12 @@ int psp_init_sos_microcode(struct psp_co uint8_t *ucode_array_start_addr; int err = 0;
- err = amdgpu_ucode_request(adev, &adev->psp.sos_fw, AMDGPU_UCODE_REQUIRED, - "amdgpu/%s_sos.bin", chip_name); + if (amdgpu_is_kicker_fw(adev)) + err = amdgpu_ucode_request(adev, &adev->psp.sos_fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_sos_kicker.bin", chip_name); + else + err = amdgpu_ucode_request(adev, &adev->psp.sos_fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_sos.bin", chip_name); if (err) goto out;
@@ -3798,8 +3802,12 @@ int psp_init_ta_microcode(struct psp_con struct amdgpu_device *adev = psp->adev; int err;
- err = amdgpu_ucode_request(adev, &adev->psp.ta_fw, AMDGPU_UCODE_REQUIRED, - "amdgpu/%s_ta.bin", chip_name); + if (amdgpu_is_kicker_fw(adev)) + err = amdgpu_ucode_request(adev, &adev->psp.ta_fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_ta_kicker.bin", chip_name); + else + err = amdgpu_ucode_request(adev, &adev->psp.ta_fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_ta.bin", chip_name); if (err) return err;
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -83,6 +83,7 @@ MODULE_FIRMWARE("amdgpu/gc_11_0_0_pfp.bi MODULE_FIRMWARE("amdgpu/gc_11_0_0_me.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_0_mec.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc_kicker.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_0_rlc_1.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_0_toc.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_1_pfp.bin"); @@ -744,6 +745,10 @@ static int gfx_v11_0_init_microcode(stru err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, AMDGPU_UCODE_REQUIRED, "amdgpu/gc_11_0_0_rlc_1.bin"); + else if (amdgpu_is_kicker_fw(adev)) + err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, + AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_rlc_kicker.bin", ucode_prefix); else err = amdgpu_ucode_request(adev, &adev->gfx.rlc_fw, AMDGPU_UCODE_REQUIRED, --- a/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/imu_v11_0.c @@ -32,6 +32,7 @@ #include "gc/gc_11_0_0_sh_mask.h"
MODULE_FIRMWARE("amdgpu/gc_11_0_0_imu.bin"); +MODULE_FIRMWARE("amdgpu/gc_11_0_0_imu_kicker.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_1_imu.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_2_imu.bin"); MODULE_FIRMWARE("amdgpu/gc_11_0_3_imu.bin"); @@ -51,8 +52,12 @@ static int imu_v11_0_init_microcode(stru DRM_DEBUG("\n");
amdgpu_ucode_ip_version_decode(adev, GC_HWIP, ucode_prefix, sizeof(ucode_prefix)); - err = amdgpu_ucode_request(adev, &adev->gfx.imu_fw, AMDGPU_UCODE_REQUIRED, - "amdgpu/%s_imu.bin", ucode_prefix); + if (amdgpu_is_kicker_fw(adev)) + err = amdgpu_ucode_request(adev, &adev->gfx.imu_fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_imu_kicker.bin", ucode_prefix); + else + err = amdgpu_ucode_request(adev, &adev->gfx.imu_fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_imu.bin", ucode_prefix); if (err) goto out;
--- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -42,7 +42,9 @@ MODULE_FIRMWARE("amdgpu/psp_13_0_5_ta.bi MODULE_FIRMWARE("amdgpu/psp_13_0_8_toc.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_8_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos.bin"); +MODULE_FIRMWARE("amdgpu/psp_13_0_0_sos_kicker.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta.bin"); +MODULE_FIRMWARE("amdgpu/psp_13_0_0_ta_kicker.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_7_sos.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_7_ta.bin"); MODULE_FIRMWARE("amdgpu/psp_13_0_10_sos.bin"); --- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c +++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c @@ -58,6 +58,7 @@
MODULE_FIRMWARE("amdgpu/aldebaran_smc.bin"); MODULE_FIRMWARE("amdgpu/smu_13_0_0.bin"); +MODULE_FIRMWARE("amdgpu/smu_13_0_0_kicker.bin"); MODULE_FIRMWARE("amdgpu/smu_13_0_7.bin"); MODULE_FIRMWARE("amdgpu/smu_13_0_10.bin");
@@ -92,7 +93,7 @@ const int pmfw_decoded_link_width[7] = { int smu_v13_0_init_microcode(struct smu_context *smu) { struct amdgpu_device *adev = smu->adev; - char ucode_prefix[15]; + char ucode_prefix[30]; int err = 0; const struct smc_firmware_header_v1_0 *hdr; const struct common_firmware_header *header; @@ -103,8 +104,13 @@ int smu_v13_0_init_microcode(struct smu_ return 0;
amdgpu_ucode_ip_version_decode(adev, MP1_HWIP, ucode_prefix, sizeof(ucode_prefix)); - err = amdgpu_ucode_request(adev, &adev->pm.fw, AMDGPU_UCODE_REQUIRED, - "amdgpu/%s.bin", ucode_prefix); + + if (amdgpu_is_kicker_fw(adev)) + err = amdgpu_ucode_request(adev, &adev->pm.fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s_kicker.bin", ucode_prefix); + else + err = amdgpu_ucode_request(adev, &adev->pm.fw, AMDGPU_UCODE_REQUIRED, + "amdgpu/%s.bin", ucode_prefix); if (err) goto out;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicholas Kazlauskas nicholas.kazlauskas@amd.com
commit 0d57dd1765d311111d9885346108c4deeae1deb4 upstream.
[WHY] For non-zero DSC instances it's possible that the HUBP domain required to drive it for sequential ONO ASICs isn't met, potentially causing the logic to the tile to enter an undefined state leading to a system hang.
[HOW] Add more checks to ensure that the HUBP domain matching the DSC instance is appropriately powered.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Reviewed-by: Duncan Ma duncan.ma@amd.com Signed-off-by: Nicholas Kazlauskas nicholas.kazlauskas@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit da63df07112e5a9857a8d2aaa04255c4206754ec) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 28 ++++++++++++++++ 1 file changed, 28 insertions(+)
--- a/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c +++ b/drivers/gpu/drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c @@ -1047,6 +1047,15 @@ void dcn35_calc_blocks_to_gate(struct dc if (dc->caps.sequential_ono) { update_state->pg_pipe_res_update[PG_HUBP][pipe_ctx->stream_res.dsc->inst] = false; update_state->pg_pipe_res_update[PG_DPP][pipe_ctx->stream_res.dsc->inst] = false; + + /* All HUBP/DPP instances must be powered if the DSC inst != HUBP inst */ + if (!pipe_ctx->top_pipe && pipe_ctx->plane_res.hubp && + pipe_ctx->plane_res.hubp->inst != pipe_ctx->stream_res.dsc->inst) { + for (j = 0; j < dc->res_pool->pipe_count; ++j) { + update_state->pg_pipe_res_update[PG_HUBP][j] = false; + update_state->pg_pipe_res_update[PG_DPP][j] = false; + } + } } }
@@ -1193,6 +1202,25 @@ void dcn35_calc_blocks_to_ungate(struct update_state->pg_pipe_res_update[PG_HDMISTREAM][0] = true;
if (dc->caps.sequential_ono) { + for (i = 0; i < dc->res_pool->pipe_count; i++) { + struct pipe_ctx *new_pipe = &context->res_ctx.pipe_ctx[i]; + + if (new_pipe->stream_res.dsc && !new_pipe->top_pipe && + update_state->pg_pipe_res_update[PG_DSC][new_pipe->stream_res.dsc->inst]) { + update_state->pg_pipe_res_update[PG_HUBP][new_pipe->stream_res.dsc->inst] = true; + update_state->pg_pipe_res_update[PG_DPP][new_pipe->stream_res.dsc->inst] = true; + + /* All HUBP/DPP instances must be powered if the DSC inst != HUBP inst */ + if (new_pipe->plane_res.hubp && + new_pipe->plane_res.hubp->inst != new_pipe->stream_res.dsc->inst) { + for (j = 0; j < dc->res_pool->pipe_count; ++j) { + update_state->pg_pipe_res_update[PG_HUBP][j] = true; + update_state->pg_pipe_res_update[PG_DPP][j] = true; + } + } + } + } + for (i = dc->res_pool->pipe_count - 1; i >= 0; i--) { if (update_state->pg_pipe_res_update[PG_HUBP][i] && update_state->pg_pipe_res_update[PG_DPP][i]) {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peichen Huang PeiChen.Huang@amd.com
commit 3251b69b7efb82eba24c9e168a6142a3078de72f upstream.
[WHAT] 1. add dc cap for dp tunneling 2. add function to get index of host router
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Reviewed-by: Cruise Hung cruise.hung@amd.com Signed-off-by: Peichen Huang PeiChen.Huang@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 29e178d13979cf6fdb42c5fe2dfec2da2306c4ad) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/core/dc.c | 33 ++++++++++ drivers/gpu/drm/amd/display/dc/dc.h | 8 ++ drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c | 3 drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c | 3 drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c | 3 drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c | 3 drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c | 3 7 files changed, 55 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c +++ b/drivers/gpu/drm/amd/display/dc/core/dc.c @@ -239,6 +239,7 @@ static bool create_links( DC_LOG_DC("BIOS object table - end");
/* Create a link for each usb4 dpia port */ + dc->lowest_dpia_link_index = MAX_LINKS; for (i = 0; i < dc->res_pool->usb4_dpia_count; i++) { struct link_init_data link_init_params = {0}; struct dc_link *link; @@ -251,6 +252,9 @@ static bool create_links(
link = dc->link_srv->create_link(&link_init_params); if (link) { + if (dc->lowest_dpia_link_index > dc->link_count) + dc->lowest_dpia_link_index = dc->link_count; + dc->links[dc->link_count] = link; link->dc = dc; ++dc->link_count; @@ -6247,6 +6251,35 @@ struct dc_power_profile dc_get_power_pro profile.power_level = dc->res_pool->funcs->get_power_profile(context); return profile; } +/** + *********************************************************************************************** + * dc_get_host_router_index: Get index of host router from a dpia link + * + * This function return a host router index of the target link. If the target link is dpia link. + * + * @param [in] link: target link + * @param [out] host_router_index: host router index of the target link + * + * @return: true if the host router index is found and valid. + * + *********************************************************************************************** + */ +bool dc_get_host_router_index(const struct dc_link *link, unsigned int *host_router_index) +{ + struct dc *dc = link->ctx->dc; + + if (link->ep_type != DISPLAY_ENDPOINT_USB4_DPIA) + return false; + + if (link->link_index < dc->lowest_dpia_link_index) + return false; + + *host_router_index = (link->link_index - dc->lowest_dpia_link_index) / dc->caps.num_of_dpias_per_host_router; + if (*host_router_index < dc->caps.num_of_host_routers) + return true; + else + return false; +}
/* ********************************************************************************** --- a/drivers/gpu/drm/amd/display/dc/dc.h +++ b/drivers/gpu/drm/amd/display/dc/dc.h @@ -66,7 +66,8 @@ struct dmub_notification; #define MAX_STREAMS 6 #define MIN_VIEWPORT_SIZE 12 #define MAX_NUM_EDP 2 -#define MAX_HOST_ROUTERS_NUM 2 +#define MAX_HOST_ROUTERS_NUM 3 +#define MAX_DPIA_PER_HOST_ROUTER 2
/* Display Core Interfaces */ struct dc_versions { @@ -303,6 +304,8 @@ struct dc_caps { /* Conservative limit for DCC cases which require ODM4:1 to support*/ uint32_t dcc_plane_width_limit; struct dc_scl_caps scl_caps; + uint8_t num_of_host_routers; + uint8_t num_of_dpias_per_host_router; };
struct dc_bug_wa { @@ -1431,6 +1434,7 @@ struct dc {
uint8_t link_count; struct dc_link *links[MAX_LINKS]; + uint8_t lowest_dpia_link_index; struct link_service *link_srv;
struct dc_state *current_state; @@ -2586,6 +2590,8 @@ struct dc_power_profile dc_get_power_pro
unsigned int dc_get_det_buffer_size_from_state(const struct dc_state *context);
+bool dc_get_host_router_index(const struct dc_link *link, unsigned int *host_router_index); + /* DSC Interfaces */ #include "dc_dsc.h"
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn31/dcn31_resource.c @@ -1954,6 +1954,9 @@ static bool dcn31_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1;
+ dc->caps.num_of_host_routers = 2; + dc->caps.num_of_dpias_per_host_router = 2; + /* Use pipe context based otg sync logic */ dc->config.use_pipe_ctx_sync_logic = true; dc->config.disable_hbr_audio_dp2 = true; --- a/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn314/dcn314_resource.c @@ -1885,6 +1885,9 @@ static bool dcn314_resource_construct(
dc->caps.max_disp_clock_khz_at_vmin = 650000;
+ dc->caps.num_of_host_routers = 2; + dc->caps.num_of_dpias_per_host_router = 2; + /* Use pipe context based otg sync logic */ dc->config.use_pipe_ctx_sync_logic = true;
--- a/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn35/dcn35_resource.c @@ -1894,6 +1894,9 @@ static bool dcn35_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1;
+ dc->caps.num_of_host_routers = 2; + dc->caps.num_of_dpias_per_host_router = 2; + /* max_disp_clock_khz_at_vmin is slightly lower than the STA value in order * to provide some margin. * It's expected for furture ASIC to have equal or higher value, in order to --- a/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn351/dcn351_resource.c @@ -1866,6 +1866,9 @@ static bool dcn351_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1;
+ dc->caps.num_of_host_routers = 2; + dc->caps.num_of_dpias_per_host_router = 2; + /* max_disp_clock_khz_at_vmin is slightly lower than the STA value in order * to provide some margin. * It's expected for furture ASIC to have equal or higher value, in order to --- a/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c +++ b/drivers/gpu/drm/amd/display/dc/resource/dcn36/dcn36_resource.c @@ -1867,6 +1867,9 @@ static bool dcn36_resource_construct( dc->caps.color.mpc.ogam_rom_caps.hlg = 0; dc->caps.color.mpc.ocsc = 1;
+ dc->caps.num_of_host_routers = 2; + dc->caps.num_of_dpias_per_host_router = 2; + /* max_disp_clock_khz_at_vmin is slightly lower than the STA value in order * to provide some margin. * It's expected for furture ASIC to have equal or higher value, in order to
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Hung alex.hung@amd.com
commit 8724a5380c4390eed81e271d22f34ff06453ded9 upstream.
[WHAT] Severe video playback corruption is observed in the following setup:
weston 14.0.90 (built from source) + mpv v0.40.0 with command: mpv bbb_sunflower_1080p_60fps_normal.mp4 --vo=gpu
[HOW] ABGR16161616 needs to be included in dml2/2.1 translation.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Acked-by: Aurabindo Pillai aurabindo.pillai@amd.com Reviewed-by: Harry Wentland harry.wentland@amd.com Reviewed-by: Austin Zheng austin.zheng@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit d023de809f85307ca819a9dbbceee6ae1f50e2ad) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c | 1 + drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c | 1 + 2 files changed, 2 insertions(+)
--- a/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml21/dml21_translation_helper.c @@ -785,6 +785,7 @@ static void populate_dml21_plane_config_ plane->pixel_format = dml2_420_10; break; case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: plane->pixel_format = dml2_444_64; --- a/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c +++ b/drivers/gpu/drm/amd/display/dc/dml2/dml2_translation_helper.c @@ -953,6 +953,7 @@ static void populate_dml_surface_cfg_fro out->SourcePixelFormat[location] = dml_420_10; break; case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: out->SourcePixelFormat[location] = dml_444_64;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Konrad Dybcio konrad.dybcio@oss.qualcomm.com
[ Upstream commit fbf5e007588f3f2bace84309b4a0d428ad619322 ]
Certain X1 SKUs vary very noticeably, but the CRDs based on them don't.
Commonize the existing X1E80100 DTSI to allow reuse.
Signed-off-by: Konrad Dybcio konrad.dybcio@oss.qualcomm.com Link: https://lore.kernel.org/r/20250203-topic-x1p4_dts-v2-5-72cd4cdc767b@oss.qual... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/x1-crd.dtsi | 1275 +++++++++++++++++++++ arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 1270 +------------------- arch/arm64/boot/dts/qcom/x1e80100.dtsi | 2 +- 3 files changed, 1279 insertions(+), 1268 deletions(-) create mode 100644 arch/arm64/boot/dts/qcom/x1-crd.dtsi
diff --git a/arch/arm64/boot/dts/qcom/x1-crd.dtsi b/arch/arm64/boot/dts/qcom/x1-crd.dtsi new file mode 100644 index 0000000000000..296b41409ad17 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/x1-crd.dtsi @@ -0,0 +1,1275 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> + +#include "x1e80100-pmics.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. X1E80100 CRD"; + compatible = "qcom,x1e80100-crd", "qcom,x1e80100"; + + aliases { + serial0 = &uart21; + }; + + wcd938x: audio-codec { + compatible = "qcom,wcd9385-codec"; + + pinctrl-names = "default"; + pinctrl-0 = <&wcd_default>; + + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + qcom,micbias4-microvolt = <1800000>; + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>; + qcom,mbhc-headset-vthreshold-microvolt = <1700000>; + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; + qcom,rx-device = <&wcd_rx>; + qcom,tx-device = <&wcd_tx>; + + reset-gpios = <&tlmm 191 GPIO_ACTIVE_LOW>; + + vdd-buck-supply = <&vreg_l15b_1p8>; + vdd-rxtx-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l15b_1p8>; + vdd-mic-bias-supply = <&vreg_bob1>; + + #sound-dai-cells = <1>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&hall_int_n_default>; + pinctrl-names = "default"; + + switch-lid { + gpios = <&tlmm 92 GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + wakeup-source; + wakeup-event-action = <EV_ACT_DEASSERTED>; + }; + }; + + pmic-glink { + compatible = "qcom,x1e80100-pmic-glink", + "qcom,sm8550-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>, + <&tlmm 123 GPIO_ACTIVE_HIGH>, + <&tlmm 125 GPIO_ACTIVE_HIGH>; + + /* Left-side rear port */ + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_ss0_hs_in: endpoint { + remote-endpoint = <&usb_1_ss0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss0_ss_in: endpoint { + remote-endpoint = <&usb_1_ss0_qmpphy_out>; + }; + }; + }; + }; + + /* Left-side front port */ + connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_ss1_hs_in: endpoint { + remote-endpoint = <&usb_1_ss1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss1_ss_in: endpoint { + remote-endpoint = <&usb_1_ss1_qmpphy_out>; + }; + }; + }; + }; + + /* Right-side port */ + connector@2 { + compatible = "usb-c-connector"; + reg = <2>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_ss2_hs_in: endpoint { + remote-endpoint = <&usb_1_ss2_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss2_ss_in: endpoint { + remote-endpoint = <&usb_1_ss2_qmpphy_out>; + }; + }; + }; + }; + }; + + reserved-memory { + linux,cma { + compatible = "shared-dma-pool"; + size = <0x0 0x8000000>; + reusable; + linux,cma-default; + }; + }; + + sound { + compatible = "qcom,x1e80100-sndcard"; + model = "X1E80100-CRD"; + audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT", + "TweeterLeft IN", "WSA WSA_SPK2 OUT", + "WooferRight IN", "WSA2 WSA_SPK2 OUT", + "TweeterRight IN", "WSA2 WSA_SPK2 OUT", + "IN1_HPHL", "HPHL_OUT", + "IN2_HPHR", "HPHR_OUT", + "AMIC2", "MIC BIAS2", + "VA DMIC0", "MIC BIAS3", + "VA DMIC1", "MIC BIAS3", + "VA DMIC2", "MIC BIAS1", + "VA DMIC3", "MIC BIAS1", + "VA DMIC0", "VA MIC BIAS3", + "VA DMIC1", "VA MIC BIAS3", + "VA DMIC2", "VA MIC BIAS1", + "VA DMIC3", "VA MIC BIAS1", + "TX SWR_INPUT1", "ADC2_OUTPUT"; + + wcd-playback-dai-link { + link-name = "WCD Playback"; + + cpu { + sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; + }; + + codec { + sound-dai = <&wcd938x 0>, <&swr1 0>, <&lpass_rxmacro 0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-capture-dai-link { + link-name = "WCD Capture"; + + cpu { + sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; + }; + + codec { + sound-dai = <&wcd938x 1>, <&swr2 1>, <&lpass_txmacro 0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wsa-dai-link { + link-name = "WSA Playback"; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + codec { + sound-dai = <&left_woofer>, <&left_tweeter>, + <&swr0 0>, <&lpass_wsamacro 0>, + <&right_woofer>, <&right_tweeter>, + <&swr3 0>, <&lpass_wsa2macro 0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + va-dai-link { + link-name = "VA Capture"; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + vreg_edp_3p3: regulator-edp-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_misc_3p3: regulator-misc-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_MISC_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pm8550ve_8_gpios 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&misc_3p3_reg_en>; + + regulator-boot-on; + regulator-always-on; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <&nvme_reg_en>; + + regulator-boot-on; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-always-on; + regulator-boot-on; + }; + + vreg_wwan: regulator-wwan { + compatible = "regulator-fixed"; + + regulator-name = "SDX_VPH_PWR"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 221 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wwan_sw_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm8550-rpmh-regulators"; + qcom,pmic-id = "b"; + + vdd-bob1-supply = <&vph_pwr>; + vdd-bob2-supply = <&vph_pwr>; + vdd-l1-l4-l10-supply = <&vreg_s4c_1p8>; + vdd-l2-l13-l14-supply = <&vreg_bob1>; + vdd-l5-l16-supply = <&vreg_bob1>; + vdd-l6-l7-supply = <&vreg_bob2>; + vdd-l8-l9-supply = <&vreg_bob1>; + vdd-l12-supply = <&vreg_s5j_1p2>; + vdd-l15-supply = <&vreg_s4c_1p8>; + vdd-l17-supply = <&vreg_bob2>; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1b_1p8: ldo1 { + regulator-name = "vreg_l1b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3100000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4b_1p8: ldo4 { + regulator-name = "vreg_l4b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5b_3p0: ldo5 { + regulator-name = "vreg_l5b_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6b_1p8: ldo6 { + regulator-name = "vreg_l6b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_2p8: ldo7 { + regulator-name = "vreg_l7b_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_3p0: ldo8 { + regulator-name = "vreg_l8b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_2p9: ldo9 { + regulator-name = "vreg_l9b_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10b_1p8: ldo10 { + regulator-name = "vreg_l10b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_1p2: ldo12 { + regulator-name = "vreg_l12b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13b_3p0: ldo13 { + regulator-name = "vreg_l13b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3100000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l14b_3p0: ldo14 { + regulator-name = "vreg_l14b_3p0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l16b_2p9: ldo16 { + regulator-name = "vreg_l16b_2p9"; + regulator-min-microvolt = <2912000>; + regulator-max-microvolt = <2912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-l1-supply = <&vreg_s5j_1p2>; + vdd-l2-supply = <&vreg_s1f_0p7>; + vdd-l3-supply = <&vreg_s1f_0p7>; + vdd-s4-supply = <&vph_pwr>; + + vreg_s4c_1p8: smps4 { + regulator-name = "vreg_s4c_1p8"; + regulator-min-microvolt = <1856000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1c_1p2: ldo1 { + regulator-name = "vreg_l1c_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c_0p8: ldo2 { + regulator-name = "vreg_l2c_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c_0p8: ldo3 { + regulator-name = "vreg_l3c_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pmc8380-rpmh-regulators"; + qcom,pmic-id = "d"; + + vdd-l1-supply = <&vreg_s1f_0p7>; + vdd-l2-supply = <&vreg_s1f_0p7>; + vdd-l3-supply = <&vreg_s4c_1p8>; + vdd-s1-supply = <&vph_pwr>; + + vreg_l1d_0p8: ldo1 { + regulator-name = "vreg_l1d_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2d_0p9: ldo2 { + regulator-name = "vreg_l2d_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3d_1p8: ldo3 { + regulator-name = "vreg_l3d_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pmc8380-rpmh-regulators"; + qcom,pmic-id = "e"; + + vdd-l2-supply = <&vreg_s1f_0p7>; + vdd-l3-supply = <&vreg_s5j_1p2>; + + vreg_l2e_0p8: ldo2 { + regulator-name = "vreg_l2e_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3e_1p2: ldo3 { + regulator-name = "vreg_l3e_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pmc8380-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-l1-supply = <&vreg_s5j_1p2>; + vdd-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-supply = <&vreg_s5j_1p2>; + vdd-s1-supply = <&vph_pwr>; + + vreg_s1f_0p7: smps1 { + regulator-name = "vreg_s1f_0p7"; + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1f_1p0: ldo1 { + regulator-name = "vreg_l1f_1p0"; + regulator-min-microvolt = <1024000>; + regulator-max-microvolt = <1024000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_1p0: ldo2 { + regulator-name = "vreg_l2f_1p0"; + regulator-min-microvolt = <1024000>; + regulator-max-microvolt = <1024000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_1p0: ldo3 { + regulator-name = "vreg_l3f_1p0"; + regulator-min-microvolt = <1024000>; + regulator-max-microvolt = <1024000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-6 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "i"; + + vdd-l1-supply = <&vreg_s4c_1p8>; + vdd-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-supply = <&vreg_s1f_0p7>; + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + + vreg_s1i_0p9: smps1 { + regulator-name = "vreg_s1i_0p9"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s2i_1p0: smps2 { + regulator-name = "vreg_s2i_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1i_1p8: ldo1 { + regulator-name = "vreg_l1i_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2i_1p2: ldo2 { + regulator-name = "vreg_l2i_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3i_0p8: ldo3 { + regulator-name = "vreg_l3i_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-7 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "j"; + + vdd-l1-supply = <&vreg_s1f_0p7>; + vdd-l2-supply = <&vreg_s5j_1p2>; + vdd-l3-supply = <&vreg_s1f_0p7>; + vdd-s5-supply = <&vph_pwr>; + + vreg_s5j_1p2: smps5 { + regulator-name = "vreg_s5j_1p2"; + regulator-min-microvolt = <1256000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1j_0p8: ldo1 { + regulator-name = "vreg_l1j_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2j_1p2: ldo2 { + regulator-name = "vreg_l2j_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3j_0p8: ldo3 { + regulator-name = "vreg_l3j_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&gpu { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + + status = "okay"; + + touchpad@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l12b_1p2>; + + pinctrl-0 = <&tpad_default>; + pinctrl-names = "default"; + + wakeup-source; + }; + + keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l12b_1p2>; + + pinctrl-0 = <&kybd_default>; + pinctrl-names = "default"; + + wakeup-source; + }; +}; + +&i2c8 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@10 { + compatible = "hid-over-i2c"; + reg = <0x10>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_1p8>; + + pinctrl-0 = <&ts0_default>; + pinctrl-names = "default"; + }; +}; + +&lpass_tlmm { + spkr_01_sd_n_active: spkr-01-sd-n-active-state { + pins = "gpio12"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + output-low; + }; + + spkr_23_sd_n_active: spkr-23-sd-n-active-state { + pins = "gpio13"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + output-low; + }; +}; + +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>, <&dmic23_default>; + pinctrl-names = "default"; + + vdd-micb-supply = <&vreg_l1b_1p8>; + qcom,dmic-sample-rate = <4800000>; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp3 { + compatible = "qcom,x1e80100-dp"; + /delete-property/ #sound-dai-cells; + + status = "okay"; + + aux-bus { + panel { + compatible = "samsung,atna45af01", "samsung,atna33xc20"; + enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp_3p3>; + + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; + + port { + edp_panel_in: endpoint { + remote-endpoint = <&mdss_dp3_out>; + }; + }; + }; + }; + + ports { + port@1 { + reg = <1>; + mdss_dp3_out: endpoint { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + + remote-endpoint = <&edp_panel_in>; + }; + }; + }; +}; + +&mdss_dp3_phy { + vdda-phy-supply = <&vreg_l3j_0p8>; + vdda-pll-supply = <&vreg_l2j_1p2>; + + status = "okay"; +}; + +&pcie4 { + perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l3i_0p8>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pcie5 { + perst-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; + + vddpe-3v3-supply = <&vreg_wwan>; + + pinctrl-0 = <&pcie5_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie5_phy { + vdda-phy-supply = <&vreg_l3i_0p8>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pcie6a { + perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; + + vddpe-3v3-supply = <&vreg_nvme>; + + pinctrl-names = "default"; + pinctrl-0 = <&pcie6a_default>; + + status = "okay"; +}; + +&pcie6a_phy { + vdda-phy-supply = <&vreg_l1d_0p8>; + vdda-pll-supply = <&vreg_l2j_1p2>; + + status = "okay"; +}; + +&pm8550ve_8_gpios { + misc_3p3_reg_en: misc-3p3-reg-en-state { + pins = "gpio6"; + function = "normal"; + bias-disable; + input-disable; + output-enable; + drive-push-pull; + power-source = <1>; /* 1.8 V */ + qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; + }; +}; + +&pmc8380_3_gpios { + edp_bl_en: edp-bl-en-state { + pins = "gpio4"; + function = "normal"; + power-source = <1>; /* 1.8V */ + input-disable; + output-enable; + }; +}; + +&qupv3_0 { + status = "okay"; +}; + +&qupv3_1 { + status = "okay"; +}; + +&qupv3_2 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/x1e80100/adsp.mbn", + "qcom/x1e80100/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/x1e80100/cdsp.mbn", + "qcom/x1e80100/cdsp_dtb.mbn"; + + status = "okay"; +}; + +&smb2360_0 { + status = "okay"; +}; + +&smb2360_0_eusb2_repeater { + vdd18-supply = <&vreg_l3d_1p8>; + vdd3-supply = <&vreg_l2b_3p0>; +}; + +&smb2360_1 { + status = "okay"; +}; + +&smb2360_1_eusb2_repeater { + vdd18-supply = <&vreg_l3d_1p8>; + vdd3-supply = <&vreg_l14b_3p0>; +}; + +&smb2360_2 { + status = "okay"; +}; + +&smb2360_2_eusb2_repeater { + vdd18-supply = <&vreg_l3d_1p8>; + vdd3-supply = <&vreg_l8b_3p0>; +}; + +&swr0 { + status = "okay"; + + pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>; + pinctrl-names = "default"; + + /* WSA8845, Left Woofer */ + left_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferLeft"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <1 2 3 7 10 13>; + }; + + /* WSA8845, Left Tweeter */ + left_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterLeft"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <4 5 6 7 11 13>; + }; +}; + +&swr1 { + status = "okay"; + + /* WCD9385 RX */ + wcd_rx: codec@0,4 { + compatible = "sdw20217010d00"; + reg = <0 4>; + qcom,rx-port-mapping = <1 2 3 4 5>; + }; +}; + +&swr2 { + status = "okay"; + + /* WCD9385 TX */ + wcd_tx: codec@0,3 { + compatible = "sdw20217010d00"; + reg = <0 3>; + qcom,tx-port-mapping = <2 2 3 4>; + }; +}; + +&swr3 { + status = "okay"; + + pinctrl-0 = <&wsa2_swr_active>, <&spkr_23_sd_n_active>; + pinctrl-names = "default"; + + /* WSA8845, Right Woofer */ + right_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferRight"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <1 2 3 7 10 13>; + }; + + /* WSA8845, Right Tweeter */ + right_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterRight"; + vdd-1p8-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l12b_1p2>; + qcom,port-mapping = <4 5 6 7 11 13>; + }; +}; + +&tlmm { + gpio-reserved-ranges = <34 2>, /* Unused */ + <44 4>, /* SPI (TPM) */ + <238 1>; /* UFS Reset */ + + edp_reg_en: edp-reg-en-state { + pins = "gpio70"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + hall_int_n_default: hall-int-n-state { + pins = "gpio92"; + function = "gpio"; + bias-disable; + }; + + kybd_default: kybd-default-state { + pins = "gpio67"; + function = "gpio"; + bias-disable; + }; + + nvme_reg_en: nvme-reg-en-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie5_default: pcie5-default-state { + clkreq-n-pins { + pins = "gpio150"; + function = "pcie5_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio149"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio151"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie6a_default: pcie6a-default-state { + clkreq-n-pins { + pins = "gpio153"; + function = "pcie6a_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio152"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio154"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + tpad_default: tpad-default-state { + pins = "gpio3"; + function = "gpio"; + bias-disable; + }; + + ts0_default: ts0-default-state { + int-n-pins { + pins = "gpio51"; + function = "gpio"; + bias-disable; + }; + + reset-n-pins { + pins = "gpio48"; + function = "gpio"; + output-high; + drive-strength = <16>; + }; + }; + + wcd_default: wcd-reset-n-active-state { + pins = "gpio191"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + output-low; + }; + + wwan_sw_en: wwan-sw-en-state { + pins = "gpio221"; + function = "gpio"; + drive-strength = <4>; + bias-disable; + }; +}; + +&uart21 { + compatible = "qcom,geni-debug-uart"; + status = "okay"; +}; + +&usb_1_ss0_hsphy { + vdd-supply = <&vreg_l3j_0p8>; + vdda12-supply = <&vreg_l2j_1p2>; + + phys = <&smb2360_0_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_ss0_qmpphy { + vdda-phy-supply = <&vreg_l2j_1p2>; + vdda-pll-supply = <&vreg_l1j_0p8>; + + status = "okay"; +}; + +&usb_1_ss0 { + status = "okay"; +}; + +&usb_1_ss0_dwc3 { + dr_mode = "host"; +}; + +&usb_1_ss0_dwc3_hs { + remote-endpoint = <&pmic_glink_ss0_hs_in>; +}; + +&usb_1_ss0_qmpphy_out { + remote-endpoint = <&pmic_glink_ss0_ss_in>; +}; + +&usb_1_ss1_hsphy { + vdd-supply = <&vreg_l3j_0p8>; + vdda12-supply = <&vreg_l2j_1p2>; + + phys = <&smb2360_1_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_ss1_qmpphy { + vdda-phy-supply = <&vreg_l2j_1p2>; + vdda-pll-supply = <&vreg_l2d_0p9>; + + status = "okay"; +}; + +&usb_1_ss1 { + status = "okay"; +}; + +&usb_1_ss1_dwc3 { + dr_mode = "host"; +}; + +&usb_1_ss1_dwc3_hs { + remote-endpoint = <&pmic_glink_ss1_hs_in>; +}; + +&usb_1_ss1_qmpphy_out { + remote-endpoint = <&pmic_glink_ss1_ss_in>; +}; + +&usb_1_ss2_hsphy { + vdd-supply = <&vreg_l3j_0p8>; + vdda12-supply = <&vreg_l2j_1p2>; + + phys = <&smb2360_2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_ss2_qmpphy { + vdda-phy-supply = <&vreg_l2j_1p2>; + vdda-pll-supply = <&vreg_l2d_0p9>; + + status = "okay"; +}; + +&usb_1_ss2 { + status = "okay"; +}; + +&usb_1_ss2_dwc3 { + dr_mode = "host"; +}; + +&usb_1_ss2_dwc3_hs { + remote-endpoint = <&pmic_glink_ss2_hs_in>; +}; + +&usb_1_ss2_qmpphy_out { + remote-endpoint = <&pmic_glink_ss2_ss_in>; +}; diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts index ff5b3472fafd3..976b8e44b5763 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts @@ -5,1278 +5,14 @@
/dts-v1/;
-#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/input/gpio-keys.h> -#include <dt-bindings/input/input.h> -#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> -#include <dt-bindings/regulator/qcom,rpmh-regulator.h> - #include "x1e80100.dtsi" -#include "x1e80100-pmics.dtsi" +#include "x1-crd.dtsi"
/ { model = "Qualcomm Technologies, Inc. X1E80100 CRD"; compatible = "qcom,x1e80100-crd", "qcom,x1e80100"; - - aliases { - serial0 = &uart21; - }; - - wcd938x: audio-codec { - compatible = "qcom,wcd9385-codec"; - - pinctrl-names = "default"; - pinctrl-0 = <&wcd_default>; - - qcom,micbias1-microvolt = <1800000>; - qcom,micbias2-microvolt = <1800000>; - qcom,micbias3-microvolt = <1800000>; - qcom,micbias4-microvolt = <1800000>; - qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 500000 500000 500000 500000>; - qcom,mbhc-headset-vthreshold-microvolt = <1700000>; - qcom,mbhc-headphone-vthreshold-microvolt = <50000>; - qcom,rx-device = <&wcd_rx>; - qcom,tx-device = <&wcd_tx>; - - reset-gpios = <&tlmm 191 GPIO_ACTIVE_LOW>; - - vdd-buck-supply = <&vreg_l15b_1p8>; - vdd-rxtx-supply = <&vreg_l15b_1p8>; - vdd-io-supply = <&vreg_l15b_1p8>; - vdd-mic-bias-supply = <&vreg_bob1>; - - #sound-dai-cells = <1>; - }; - - chosen { - stdout-path = "serial0:115200n8"; - }; - - gpio-keys { - compatible = "gpio-keys"; - - pinctrl-0 = <&hall_int_n_default>; - pinctrl-names = "default"; - - switch-lid { - gpios = <&tlmm 92 GPIO_ACTIVE_LOW>; - linux,input-type = <EV_SW>; - linux,code = <SW_LID>; - wakeup-source; - wakeup-event-action = <EV_ACT_DEASSERTED>; - }; - }; - - pmic-glink { - compatible = "qcom,x1e80100-pmic-glink", - "qcom,sm8550-pmic-glink", - "qcom,pmic-glink"; - #address-cells = <1>; - #size-cells = <0>; - orientation-gpios = <&tlmm 121 GPIO_ACTIVE_HIGH>, - <&tlmm 123 GPIO_ACTIVE_HIGH>, - <&tlmm 125 GPIO_ACTIVE_HIGH>; - - /* Left-side rear port */ - connector@0 { - compatible = "usb-c-connector"; - reg = <0>; - power-role = "dual"; - data-role = "dual"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - pmic_glink_ss0_hs_in: endpoint { - remote-endpoint = <&usb_1_ss0_dwc3_hs>; - }; - }; - - port@1 { - reg = <1>; - - pmic_glink_ss0_ss_in: endpoint { - remote-endpoint = <&usb_1_ss0_qmpphy_out>; - }; - }; - }; - }; - - /* Left-side front port */ - connector@1 { - compatible = "usb-c-connector"; - reg = <1>; - power-role = "dual"; - data-role = "dual"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - pmic_glink_ss1_hs_in: endpoint { - remote-endpoint = <&usb_1_ss1_dwc3_hs>; - }; - }; - - port@1 { - reg = <1>; - - pmic_glink_ss1_ss_in: endpoint { - remote-endpoint = <&usb_1_ss1_qmpphy_out>; - }; - }; - }; - }; - - /* Right-side port */ - connector@2 { - compatible = "usb-c-connector"; - reg = <2>; - power-role = "dual"; - data-role = "dual"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - pmic_glink_ss2_hs_in: endpoint { - remote-endpoint = <&usb_1_ss2_dwc3_hs>; - }; - }; - - port@1 { - reg = <1>; - - pmic_glink_ss2_ss_in: endpoint { - remote-endpoint = <&usb_1_ss2_qmpphy_out>; - }; - }; - }; - }; - }; - - reserved-memory { - linux,cma { - compatible = "shared-dma-pool"; - size = <0x0 0x8000000>; - reusable; - linux,cma-default; - }; - }; - - sound { - compatible = "qcom,x1e80100-sndcard"; - model = "X1E80100-CRD"; - audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT", - "TweeterLeft IN", "WSA WSA_SPK2 OUT", - "WooferRight IN", "WSA2 WSA_SPK2 OUT", - "TweeterRight IN", "WSA2 WSA_SPK2 OUT", - "IN1_HPHL", "HPHL_OUT", - "IN2_HPHR", "HPHR_OUT", - "AMIC2", "MIC BIAS2", - "VA DMIC0", "MIC BIAS3", - "VA DMIC1", "MIC BIAS3", - "VA DMIC2", "MIC BIAS1", - "VA DMIC3", "MIC BIAS1", - "VA DMIC0", "VA MIC BIAS3", - "VA DMIC1", "VA MIC BIAS3", - "VA DMIC2", "VA MIC BIAS1", - "VA DMIC3", "VA MIC BIAS1", - "TX SWR_INPUT1", "ADC2_OUTPUT"; - - wcd-playback-dai-link { - link-name = "WCD Playback"; - - cpu { - sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; - }; - - codec { - sound-dai = <&wcd938x 0>, <&swr1 0>, <&lpass_rxmacro 0>; - }; - - platform { - sound-dai = <&q6apm>; - }; - }; - - wcd-capture-dai-link { - link-name = "WCD Capture"; - - cpu { - sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; - }; - - codec { - sound-dai = <&wcd938x 1>, <&swr2 1>, <&lpass_txmacro 0>; - }; - - platform { - sound-dai = <&q6apm>; - }; - }; - - wsa-dai-link { - link-name = "WSA Playback"; - - cpu { - sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; - }; - - codec { - sound-dai = <&left_woofer>, <&left_tweeter>, - <&swr0 0>, <&lpass_wsamacro 0>, - <&right_woofer>, <&right_tweeter>, - <&swr3 0>, <&lpass_wsa2macro 0>; - }; - - platform { - sound-dai = <&q6apm>; - }; - }; - - va-dai-link { - link-name = "VA Capture"; - - cpu { - sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; - }; - - codec { - sound-dai = <&lpass_vamacro 0>; - }; - - platform { - sound-dai = <&q6apm>; - }; - }; - }; - - vreg_edp_3p3: regulator-edp-3p3 { - compatible = "regulator-fixed"; - - regulator-name = "VREG_EDP_3P3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; - enable-active-high; - - pinctrl-0 = <&edp_reg_en>; - pinctrl-names = "default"; - - regulator-boot-on; - }; - - vreg_misc_3p3: regulator-misc-3p3 { - compatible = "regulator-fixed"; - - regulator-name = "VREG_MISC_3P3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&pm8550ve_8_gpios 6 GPIO_ACTIVE_HIGH>; - enable-active-high; - - pinctrl-names = "default"; - pinctrl-0 = <&misc_3p3_reg_en>; - - regulator-boot-on; - regulator-always-on; - }; - - vreg_nvme: regulator-nvme { - compatible = "regulator-fixed"; - - regulator-name = "VREG_NVME_3P3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&tlmm 18 GPIO_ACTIVE_HIGH>; - enable-active-high; - - pinctrl-names = "default"; - pinctrl-0 = <&nvme_reg_en>; - - regulator-boot-on; - }; - - vph_pwr: regulator-vph-pwr { - compatible = "regulator-fixed"; - - regulator-name = "vph_pwr"; - regulator-min-microvolt = <3700000>; - regulator-max-microvolt = <3700000>; - - regulator-always-on; - regulator-boot-on; - }; - - vreg_wwan: regulator-wwan { - compatible = "regulator-fixed"; - - regulator-name = "SDX_VPH_PWR"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - - gpio = <&tlmm 221 GPIO_ACTIVE_HIGH>; - enable-active-high; - - pinctrl-0 = <&wwan_sw_en>; - pinctrl-names = "default"; - - regulator-boot-on; - }; -}; - -&apps_rsc { - regulators-0 { - compatible = "qcom,pm8550-rpmh-regulators"; - qcom,pmic-id = "b"; - - vdd-bob1-supply = <&vph_pwr>; - vdd-bob2-supply = <&vph_pwr>; - vdd-l1-l4-l10-supply = <&vreg_s4c_1p8>; - vdd-l2-l13-l14-supply = <&vreg_bob1>; - vdd-l5-l16-supply = <&vreg_bob1>; - vdd-l6-l7-supply = <&vreg_bob2>; - vdd-l8-l9-supply = <&vreg_bob1>; - vdd-l12-supply = <&vreg_s5j_1p2>; - vdd-l15-supply = <&vreg_s4c_1p8>; - vdd-l17-supply = <&vreg_bob2>; - - vreg_bob1: bob1 { - regulator-name = "vreg_bob1"; - regulator-min-microvolt = <3008000>; - regulator-max-microvolt = <3960000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_bob2: bob2 { - regulator-name = "vreg_bob2"; - regulator-min-microvolt = <2504000>; - regulator-max-microvolt = <3008000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l1b_1p8: ldo1 { - regulator-name = "vreg_l1b_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l2b_3p0: ldo2 { - regulator-name = "vreg_l2b_3p0"; - regulator-min-microvolt = <3072000>; - regulator-max-microvolt = <3100000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l4b_1p8: ldo4 { - regulator-name = "vreg_l4b_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l5b_3p0: ldo5 { - regulator-name = "vreg_l5b_3p0"; - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <3000000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l6b_1p8: ldo6 { - regulator-name = "vreg_l6b_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <2960000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l7b_2p8: ldo7 { - regulator-name = "vreg_l7b_2p8"; - regulator-min-microvolt = <2800000>; - regulator-max-microvolt = <2800000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l8b_3p0: ldo8 { - regulator-name = "vreg_l8b_3p0"; - regulator-min-microvolt = <3072000>; - regulator-max-microvolt = <3072000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l9b_2p9: ldo9 { - regulator-name = "vreg_l9b_2p9"; - regulator-min-microvolt = <2960000>; - regulator-max-microvolt = <2960000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l10b_1p8: ldo10 { - regulator-name = "vreg_l10b_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l12b_1p2: ldo12 { - regulator-name = "vreg_l12b_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l13b_3p0: ldo13 { - regulator-name = "vreg_l13b_3p0"; - regulator-min-microvolt = <3072000>; - regulator-max-microvolt = <3100000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l14b_3p0: ldo14 { - regulator-name = "vreg_l14b_3p0"; - regulator-min-microvolt = <3072000>; - regulator-max-microvolt = <3072000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l15b_1p8: ldo15 { - regulator-name = "vreg_l15b_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l16b_2p9: ldo16 { - regulator-name = "vreg_l16b_2p9"; - regulator-min-microvolt = <2912000>; - regulator-max-microvolt = <2912000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l17b_2p5: ldo17 { - regulator-name = "vreg_l17b_2p5"; - regulator-min-microvolt = <2504000>; - regulator-max-microvolt = <2504000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - }; - - regulators-1 { - compatible = "qcom,pm8550ve-rpmh-regulators"; - qcom,pmic-id = "c"; - - vdd-l1-supply = <&vreg_s5j_1p2>; - vdd-l2-supply = <&vreg_s1f_0p7>; - vdd-l3-supply = <&vreg_s1f_0p7>; - vdd-s4-supply = <&vph_pwr>; - - vreg_s4c_1p8: smps4 { - regulator-name = "vreg_s4c_1p8"; - regulator-min-microvolt = <1856000>; - regulator-max-microvolt = <2000000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l1c_1p2: ldo1 { - regulator-name = "vreg_l1c_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l2c_0p8: ldo2 { - regulator-name = "vreg_l2c_0p8"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l3c_0p8: ldo3 { - regulator-name = "vreg_l3c_0p8"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - }; - - regulators-2 { - compatible = "qcom,pmc8380-rpmh-regulators"; - qcom,pmic-id = "d"; - - vdd-l1-supply = <&vreg_s1f_0p7>; - vdd-l2-supply = <&vreg_s1f_0p7>; - vdd-l3-supply = <&vreg_s4c_1p8>; - vdd-s1-supply = <&vph_pwr>; - - vreg_l1d_0p8: ldo1 { - regulator-name = "vreg_l1d_0p8"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l2d_0p9: ldo2 { - regulator-name = "vreg_l2d_0p9"; - regulator-min-microvolt = <912000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l3d_1p8: ldo3 { - regulator-name = "vreg_l3d_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - }; - - regulators-3 { - compatible = "qcom,pmc8380-rpmh-regulators"; - qcom,pmic-id = "e"; - - vdd-l2-supply = <&vreg_s1f_0p7>; - vdd-l3-supply = <&vreg_s5j_1p2>; - - vreg_l2e_0p8: ldo2 { - regulator-name = "vreg_l2e_0p8"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l3e_1p2: ldo3 { - regulator-name = "vreg_l3e_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - }; - - regulators-4 { - compatible = "qcom,pmc8380-rpmh-regulators"; - qcom,pmic-id = "f"; - - vdd-l1-supply = <&vreg_s5j_1p2>; - vdd-l2-supply = <&vreg_s5j_1p2>; - vdd-l3-supply = <&vreg_s5j_1p2>; - vdd-s1-supply = <&vph_pwr>; - - vreg_s1f_0p7: smps1 { - regulator-name = "vreg_s1f_0p7"; - regulator-min-microvolt = <700000>; - regulator-max-microvolt = <1100000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l1f_1p0: ldo1 { - regulator-name = "vreg_l1f_1p0"; - regulator-min-microvolt = <1024000>; - regulator-max-microvolt = <1024000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l2f_1p0: ldo2 { - regulator-name = "vreg_l2f_1p0"; - regulator-min-microvolt = <1024000>; - regulator-max-microvolt = <1024000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l3f_1p0: ldo3 { - regulator-name = "vreg_l3f_1p0"; - regulator-min-microvolt = <1024000>; - regulator-max-microvolt = <1024000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - }; - - regulators-6 { - compatible = "qcom,pm8550ve-rpmh-regulators"; - qcom,pmic-id = "i"; - - vdd-l1-supply = <&vreg_s4c_1p8>; - vdd-l2-supply = <&vreg_s5j_1p2>; - vdd-l3-supply = <&vreg_s1f_0p7>; - vdd-s1-supply = <&vph_pwr>; - vdd-s2-supply = <&vph_pwr>; - - vreg_s1i_0p9: smps1 { - regulator-name = "vreg_s1i_0p9"; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_s2i_1p0: smps2 { - regulator-name = "vreg_s2i_1p0"; - regulator-min-microvolt = <1000000>; - regulator-max-microvolt = <1100000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l1i_1p8: ldo1 { - regulator-name = "vreg_l1i_1p8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l2i_1p2: ldo2 { - regulator-name = "vreg_l2i_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l3i_0p8: ldo3 { - regulator-name = "vreg_l3i_0p8"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - }; - - regulators-7 { - compatible = "qcom,pm8550ve-rpmh-regulators"; - qcom,pmic-id = "j"; - - vdd-l1-supply = <&vreg_s1f_0p7>; - vdd-l2-supply = <&vreg_s5j_1p2>; - vdd-l3-supply = <&vreg_s1f_0p7>; - vdd-s5-supply = <&vph_pwr>; - - vreg_s5j_1p2: smps5 { - regulator-name = "vreg_s5j_1p2"; - regulator-min-microvolt = <1256000>; - regulator-max-microvolt = <1304000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l1j_0p8: ldo1 { - regulator-name = "vreg_l1j_0p8"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l2j_1p2: ldo2 { - regulator-name = "vreg_l2j_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - - vreg_l3j_0p8: ldo3 { - regulator-name = "vreg_l3j_0p8"; - regulator-min-microvolt = <880000>; - regulator-max-microvolt = <920000>; - regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; - }; - }; -}; - -&gpu { - status = "okay"; - - zap-shader { - firmware-name = "qcom/x1e80100/gen70500_zap.mbn"; - }; -}; - -&i2c0 { - clock-frequency = <400000>; - - status = "okay"; - - touchpad@15 { - compatible = "hid-over-i2c"; - reg = <0x15>; - - hid-descr-addr = <0x1>; - interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; - - vdd-supply = <&vreg_misc_3p3>; - vddl-supply = <&vreg_l12b_1p2>; - - pinctrl-0 = <&tpad_default>; - pinctrl-names = "default"; - - wakeup-source; - }; - - keyboard@3a { - compatible = "hid-over-i2c"; - reg = <0x3a>; - - hid-descr-addr = <0x1>; - interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>; - - vdd-supply = <&vreg_misc_3p3>; - vddl-supply = <&vreg_l12b_1p2>; - - pinctrl-0 = <&kybd_default>; - pinctrl-names = "default"; - - wakeup-source; - }; -}; - -&i2c8 { - clock-frequency = <400000>; - - status = "okay"; - - touchscreen@10 { - compatible = "hid-over-i2c"; - reg = <0x10>; - - hid-descr-addr = <0x1>; - interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>; - - vdd-supply = <&vreg_misc_3p3>; - vddl-supply = <&vreg_l15b_1p8>; - - pinctrl-0 = <&ts0_default>; - pinctrl-names = "default"; - }; -}; - -&lpass_tlmm { - spkr_01_sd_n_active: spkr-01-sd-n-active-state { - pins = "gpio12"; - function = "gpio"; - drive-strength = <16>; - bias-disable; - output-low; - }; - - spkr_23_sd_n_active: spkr-23-sd-n-active-state { - pins = "gpio13"; - function = "gpio"; - drive-strength = <16>; - bias-disable; - output-low; - }; -}; - -&lpass_vamacro { - pinctrl-0 = <&dmic01_default>, <&dmic23_default>; - pinctrl-names = "default"; - - vdd-micb-supply = <&vreg_l1b_1p8>; - qcom,dmic-sample-rate = <4800000>; -}; - -&mdss { - status = "okay"; -}; - -&mdss_dp3 { - compatible = "qcom,x1e80100-dp"; - /delete-property/ #sound-dai-cells; - - status = "okay"; - - aux-bus { - panel { - compatible = "samsung,atna45af01", "samsung,atna33xc20"; - enable-gpios = <&pmc8380_3_gpios 4 GPIO_ACTIVE_HIGH>; - power-supply = <&vreg_edp_3p3>; - - pinctrl-0 = <&edp_bl_en>; - pinctrl-names = "default"; - - port { - edp_panel_in: endpoint { - remote-endpoint = <&mdss_dp3_out>; - }; - }; - }; - }; - - ports { - port@1 { - reg = <1>; - mdss_dp3_out: endpoint { - data-lanes = <0 1 2 3>; - link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; - - remote-endpoint = <&edp_panel_in>; - }; - }; - }; -}; - -&mdss_dp3_phy { - vdda-phy-supply = <&vreg_l3j_0p8>; - vdda-pll-supply = <&vreg_l2j_1p2>; - - status = "okay"; -}; - -&pcie4 { - perst-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; - - pinctrl-0 = <&pcie4_default>; - pinctrl-names = "default"; - - status = "okay"; -}; - -&pcie4_phy { - vdda-phy-supply = <&vreg_l3i_0p8>; - vdda-pll-supply = <&vreg_l3e_1p2>; - - status = "okay"; -}; - -&pcie5 { - perst-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; - - vddpe-3v3-supply = <&vreg_wwan>; - - pinctrl-0 = <&pcie5_default>; - pinctrl-names = "default"; - - status = "okay"; -}; - -&pcie5_phy { - vdda-phy-supply = <&vreg_l3i_0p8>; - vdda-pll-supply = <&vreg_l3e_1p2>; - - status = "okay"; -}; - -&pcie6a { - perst-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; - - vddpe-3v3-supply = <&vreg_nvme>; - - pinctrl-names = "default"; - pinctrl-0 = <&pcie6a_default>; - - status = "okay"; -}; - -&pcie6a_phy { - vdda-phy-supply = <&vreg_l1d_0p8>; - vdda-pll-supply = <&vreg_l2j_1p2>; - - status = "okay"; -}; - -&pm8550ve_8_gpios { - misc_3p3_reg_en: misc-3p3-reg-en-state { - pins = "gpio6"; - function = "normal"; - bias-disable; - input-disable; - output-enable; - drive-push-pull; - power-source = <1>; /* 1.8 V */ - qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; - }; -}; - -&pmc8380_3_gpios { - edp_bl_en: edp-bl-en-state { - pins = "gpio4"; - function = "normal"; - power-source = <1>; /* 1.8V */ - input-disable; - output-enable; - }; -}; - -&qupv3_0 { - status = "okay"; -}; - -&qupv3_1 { - status = "okay"; -}; - -&qupv3_2 { - status = "okay"; -}; - -&remoteproc_adsp { - firmware-name = "qcom/x1e80100/adsp.mbn", - "qcom/x1e80100/adsp_dtb.mbn"; - - status = "okay"; -}; - -&remoteproc_cdsp { - firmware-name = "qcom/x1e80100/cdsp.mbn", - "qcom/x1e80100/cdsp_dtb.mbn"; - - status = "okay"; -}; - -&smb2360_0 { - status = "okay"; -}; - -&smb2360_0_eusb2_repeater { - vdd18-supply = <&vreg_l3d_1p8>; - vdd3-supply = <&vreg_l2b_3p0>; -}; - -&smb2360_1 { - status = "okay"; -}; - -&smb2360_1_eusb2_repeater { - vdd18-supply = <&vreg_l3d_1p8>; - vdd3-supply = <&vreg_l14b_3p0>; -}; - -&smb2360_2 { - status = "okay"; -}; - -&smb2360_2_eusb2_repeater { - vdd18-supply = <&vreg_l3d_1p8>; - vdd3-supply = <&vreg_l8b_3p0>; -}; - -&swr0 { - status = "okay"; - - pinctrl-0 = <&wsa_swr_active>, <&spkr_01_sd_n_active>; - pinctrl-names = "default"; - - /* WSA8845, Left Woofer */ - left_woofer: speaker@0,0 { - compatible = "sdw20217020400"; - reg = <0 0>; - reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; - #sound-dai-cells = <0>; - sound-name-prefix = "WooferLeft"; - vdd-1p8-supply = <&vreg_l15b_1p8>; - vdd-io-supply = <&vreg_l12b_1p2>; - qcom,port-mapping = <1 2 3 7 10 13>; - }; - - /* WSA8845, Left Tweeter */ - left_tweeter: speaker@0,1 { - compatible = "sdw20217020400"; - reg = <0 1>; - reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; - #sound-dai-cells = <0>; - sound-name-prefix = "TweeterLeft"; - vdd-1p8-supply = <&vreg_l15b_1p8>; - vdd-io-supply = <&vreg_l12b_1p2>; - qcom,port-mapping = <4 5 6 7 11 13>; - }; -}; - -&swr1 { - status = "okay"; - - /* WCD9385 RX */ - wcd_rx: codec@0,4 { - compatible = "sdw20217010d00"; - reg = <0 4>; - qcom,rx-port-mapping = <1 2 3 4 5>; - }; -}; - -&swr2 { - status = "okay"; - - /* WCD9385 TX */ - wcd_tx: codec@0,3 { - compatible = "sdw20217010d00"; - reg = <0 3>; - qcom,tx-port-mapping = <2 2 3 4>; - }; -}; - -&swr3 { - status = "okay"; - - pinctrl-0 = <&wsa2_swr_active>, <&spkr_23_sd_n_active>; - pinctrl-names = "default"; - - /* WSA8845, Right Woofer */ - right_woofer: speaker@0,0 { - compatible = "sdw20217020400"; - reg = <0 0>; - reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; - #sound-dai-cells = <0>; - sound-name-prefix = "WooferRight"; - vdd-1p8-supply = <&vreg_l15b_1p8>; - vdd-io-supply = <&vreg_l12b_1p2>; - qcom,port-mapping = <1 2 3 7 10 13>; - }; - - /* WSA8845, Right Tweeter */ - right_tweeter: speaker@0,1 { - compatible = "sdw20217020400"; - reg = <0 1>; - reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; - #sound-dai-cells = <0>; - sound-name-prefix = "TweeterRight"; - vdd-1p8-supply = <&vreg_l15b_1p8>; - vdd-io-supply = <&vreg_l12b_1p2>; - qcom,port-mapping = <4 5 6 7 11 13>; - }; -}; - -&tlmm { - gpio-reserved-ranges = <34 2>, /* Unused */ - <44 4>, /* SPI (TPM) */ - <238 1>; /* UFS Reset */ - - edp_reg_en: edp-reg-en-state { - pins = "gpio70"; - function = "gpio"; - drive-strength = <16>; - bias-disable; - }; - - hall_int_n_default: hall-int-n-state { - pins = "gpio92"; - function = "gpio"; - bias-disable; - }; - - kybd_default: kybd-default-state { - pins = "gpio67"; - function = "gpio"; - bias-disable; - }; - - nvme_reg_en: nvme-reg-en-state { - pins = "gpio18"; - function = "gpio"; - drive-strength = <2>; - bias-disable; - }; - - pcie4_default: pcie4-default-state { - clkreq-n-pins { - pins = "gpio147"; - function = "pcie4_clk"; - drive-strength = <2>; - bias-pull-up; - }; - - perst-n-pins { - pins = "gpio146"; - function = "gpio"; - drive-strength = <2>; - bias-disable; - }; - - wake-n-pins { - pins = "gpio148"; - function = "gpio"; - drive-strength = <2>; - bias-pull-up; - }; - }; - - pcie5_default: pcie5-default-state { - clkreq-n-pins { - pins = "gpio150"; - function = "pcie5_clk"; - drive-strength = <2>; - bias-pull-up; - }; - - perst-n-pins { - pins = "gpio149"; - function = "gpio"; - drive-strength = <2>; - bias-disable; - }; - - wake-n-pins { - pins = "gpio151"; - function = "gpio"; - drive-strength = <2>; - bias-pull-up; - }; - }; - - pcie6a_default: pcie6a-default-state { - clkreq-n-pins { - pins = "gpio153"; - function = "pcie6a_clk"; - drive-strength = <2>; - bias-pull-up; - }; - - perst-n-pins { - pins = "gpio152"; - function = "gpio"; - drive-strength = <2>; - bias-disable; - }; - - wake-n-pins { - pins = "gpio154"; - function = "gpio"; - drive-strength = <2>; - bias-pull-up; - }; - }; - - tpad_default: tpad-default-state { - pins = "gpio3"; - function = "gpio"; - bias-disable; - }; - - ts0_default: ts0-default-state { - int-n-pins { - pins = "gpio51"; - function = "gpio"; - bias-disable; - }; - - reset-n-pins { - pins = "gpio48"; - function = "gpio"; - output-high; - drive-strength = <16>; - }; - }; - - wcd_default: wcd-reset-n-active-state { - pins = "gpio191"; - function = "gpio"; - drive-strength = <16>; - bias-disable; - output-low; - }; - - wwan_sw_en: wwan-sw-en-state { - pins = "gpio221"; - function = "gpio"; - drive-strength = <4>; - bias-disable; - }; -}; - -&uart21 { - compatible = "qcom,geni-debug-uart"; - status = "okay"; -}; - -&usb_1_ss0_hsphy { - vdd-supply = <&vreg_l3j_0p8>; - vdda12-supply = <&vreg_l2j_1p2>; - - phys = <&smb2360_0_eusb2_repeater>; - - status = "okay"; -}; - -&usb_1_ss0_qmpphy { - vdda-phy-supply = <&vreg_l2j_1p2>; - vdda-pll-supply = <&vreg_l1j_0p8>; - - status = "okay"; -}; - -&usb_1_ss0 { - status = "okay"; -}; - -&usb_1_ss0_dwc3 { - dr_mode = "host"; -}; - -&usb_1_ss0_dwc3_hs { - remote-endpoint = <&pmic_glink_ss0_hs_in>; -}; - -&usb_1_ss0_qmpphy_out { - remote-endpoint = <&pmic_glink_ss0_ss_in>; -}; - -&usb_1_ss1_hsphy { - vdd-supply = <&vreg_l3j_0p8>; - vdda12-supply = <&vreg_l2j_1p2>; - - phys = <&smb2360_1_eusb2_repeater>; - - status = "okay"; -}; - -&usb_1_ss1_qmpphy { - vdda-phy-supply = <&vreg_l2j_1p2>; - vdda-pll-supply = <&vreg_l2d_0p9>; - - status = "okay"; -}; - -&usb_1_ss1 { - status = "okay"; -}; - -&usb_1_ss1_dwc3 { - dr_mode = "host"; -}; - -&usb_1_ss1_dwc3_hs { - remote-endpoint = <&pmic_glink_ss1_hs_in>; -}; - -&usb_1_ss1_qmpphy_out { - remote-endpoint = <&pmic_glink_ss1_ss_in>; -}; - -&usb_1_ss2_hsphy { - vdd-supply = <&vreg_l3j_0p8>; - vdda12-supply = <&vreg_l2j_1p2>; - - phys = <&smb2360_2_eusb2_repeater>; - - status = "okay"; -}; - -&usb_1_ss2_qmpphy { - vdda-phy-supply = <&vreg_l2j_1p2>; - vdda-pll-supply = <&vreg_l2d_0p9>; - - status = "okay"; -}; - -&usb_1_ss2 { - status = "okay"; -}; - -&usb_1_ss2_dwc3 { - dr_mode = "host"; -}; - -&usb_1_ss2_dwc3_hs { - remote-endpoint = <&pmic_glink_ss2_hs_in>; };
-&usb_1_ss2_qmpphy_out { - remote-endpoint = <&pmic_glink_ss2_ss_in>; +&gpu_zap_shader { + firmware-name = "qcom/x1e80100/gen70500_zap.mbn"; }; diff --git a/arch/arm64/boot/dts/qcom/x1e80100.dtsi b/arch/arm64/boot/dts/qcom/x1e80100.dtsi index 607d32f68c340..a25783c85e163 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e80100.dtsi @@ -3748,7 +3748,7 @@ gpu: gpu@3d00000 {
status = "disabled";
- zap-shader { + gpu_zap_shader: zap-shader { memory-region = <&gpu_microcode_mem>; };
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit abf89bc4bb09c16a53d693b09ea85225cf57ff39 ]
The l12b and l15b supplies are used by components that are not (fully) described (and some never will be) and must never be disabled.
Mark the regulators as always-on to prevent them from being disabled, for example, when consumers probe defer or suspend.
Fixes: bd50b1f5b6f3 ("arm64: dts: qcom: x1e80100: Add Compute Reference Device") Cc: stable@vger.kernel.org # 6.8 Cc: Abel Vesa abel.vesa@linaro.org Cc: Rajendra Nayak quic_rjendra@quicinc.com Cc: Sibi Sankar quic_sibis@quicinc.com Reviewed-by: Konrad Dybcio konrad.dybcio@oss.qualcomm.com Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20250314145440.11371-2-johan+linaro@kernel.org Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/x1-crd.dtsi | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/x1-crd.dtsi b/arch/arm64/boot/dts/qcom/x1-crd.dtsi index 296b41409ad17..780852fb87360 100644 --- a/arch/arm64/boot/dts/qcom/x1-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-crd.dtsi @@ -434,6 +434,7 @@ vreg_l12b_1p2: ldo12 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; };
vreg_l13b_3p0: ldo13 { @@ -455,6 +456,7 @@ vreg_l15b_1p8: ldo15 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; };
vreg_l16b_2p9: ldo16 {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
[ Upstream commit 673fa129e558c5f1196adb27d97ac90ddfe4f19c ]
The l12b and l15b supplies are used by components that are not (fully) described (and some never will be) and must never be disabled.
Mark the regulators as always-on to prevent them from being disabled, for example, when consumers probe defer or suspend.
Fixes: 7d1cbe2f4985 ("arm64: dts: qcom: Add X1E78100 ThinkPad T14s Gen 6") Cc: stable@vger.kernel.org # 6.12 Reviewed-by: Konrad Dybcio konrad.dybcio@oss.qualcomm.com Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20250314145440.11371-3-johan+linaro@kernel.org Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts index b2c2347f54fa6..7f756ce48d2f6 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts @@ -344,6 +344,7 @@ vreg_l12b_1p2: ldo12 { regulator-min-microvolt = <1200000>; regulator-max-microvolt = <1200000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; };
vreg_l13b_3p0: ldo13 { @@ -365,6 +366,7 @@ vreg_l15b_1p8: ldo15 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; };
vreg_l17b_2p5: ldo17 {
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold stephan.gerhold@linaro.org
[ Upstream commit 5ce920e6a8db40e4b094c0d863cbd19fdcfbbb7a ]
In the ACPI DSDT table, PPP_RESOURCE_ID_LDO2_J is configured with 1256000 uV instead of the 1200000 uV we have currently in the device tree. Use the same for consistency and correctness.
Cc: stable@vger.kernel.org Fixes: bd50b1f5b6f3 ("arm64: dts: qcom: x1e80100: Add Compute Reference Device") Signed-off-by: Stephan Gerhold stephan.gerhold@linaro.org Reviewed-by: Johan Hovold johan+linaro@kernel.org Reviewed-by: Abel Vesa abel.vesa@linaro.org Reviewed-by: Konrad Dybcio konrad.dybcio@oss.qualcomm.com Link: https://lore.kernel.org/r/20250423-x1e-vreg-l2j-voltage-v1-1-24b6a2043025@li... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm64/boot/dts/qcom/x1-crd.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/boot/dts/qcom/x1-crd.dtsi b/arch/arm64/boot/dts/qcom/x1-crd.dtsi index 780852fb87360..60f0b32baded3 100644 --- a/arch/arm64/boot/dts/qcom/x1-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-crd.dtsi @@ -674,8 +674,8 @@ vreg_l1j_0p8: ldo1 {
vreg_l2j_1p2: ldo2 { regulator-name = "vreg_l2j_1p2"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; + regulator-min-microvolt = <1256000>; + regulator-max-microvolt = <1256000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; };
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers ebiggers@google.com
[ Upstream commit bc8169003b41e89fe7052e408cf9fdbecb4017fe ]
As discussed in the thread containing https://lore.kernel.org/linux-crypto/20250510053308.GB505731@sol/, the Power10-optimized Poly1305 code is currently not safe to call in softirq context. Disable it for now. It can be re-enabled once it is fixed.
Fixes: ba8f8624fde2 ("crypto: poly1305-p10 - Glue code for optmized Poly1305 implementation for ppc64le") Cc: stable@vger.kernel.org Signed-off-by: Eric Biggers ebiggers@google.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/powerpc/crypto/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig index 370db8192ce62..7b785c8664f5d 100644 --- a/arch/powerpc/crypto/Kconfig +++ b/arch/powerpc/crypto/Kconfig @@ -110,6 +110,7 @@ config CRYPTO_CHACHA20_P10 config CRYPTO_POLY1305_P10 tristate "Hash functions: Poly1305 (P10 or later)" depends on PPC64 && CPU_LITTLE_ENDIAN && VSX + depends on BROKEN # Needs to be fixed to work in softirq context select CRYPTO_HASH select CRYPTO_LIB_POLY1305_GENERIC help
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher alexander.deucher@amd.com
[ Upstream commit 40f970ba7a4ab77be2ffe6d50a70416c8876496a ]
We need to take the MES lock.
Reviewed-by: Michael Chen michael.chen@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c index 5590ad5e8cd76..7164948001e9d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c @@ -836,7 +836,9 @@ int amdgpu_mes_map_legacy_queue(struct amdgpu_device *adev, queue_input.mqd_addr = amdgpu_bo_gpu_offset(ring->mqd_obj); queue_input.wptr_addr = ring->wptr_gpu_addr;
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->map_legacy_queue(&adev->mes, &queue_input); + amdgpu_mes_unlock(&adev->mes); if (r) DRM_ERROR("failed to map legacy queue\n");
@@ -859,7 +861,9 @@ int amdgpu_mes_unmap_legacy_queue(struct amdgpu_device *adev, queue_input.trail_fence_addr = gpu_addr; queue_input.trail_fence_data = seq;
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->unmap_legacy_queue(&adev->mes, &queue_input); + amdgpu_mes_unlock(&adev->mes); if (r) DRM_ERROR("failed to unmap legacy queue\n");
@@ -886,7 +890,9 @@ int amdgpu_mes_reset_legacy_queue(struct amdgpu_device *adev, queue_input.vmid = vmid; queue_input.use_mmio = use_mmio;
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->reset_legacy_queue(&adev->mes, &queue_input); + amdgpu_mes_unlock(&adev->mes); if (r) DRM_ERROR("failed to reset legacy queue\n");
@@ -916,7 +922,9 @@ uint32_t amdgpu_mes_rreg(struct amdgpu_device *adev, uint32_t reg) goto error; }
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->misc_op(&adev->mes, &op_input); + amdgpu_mes_unlock(&adev->mes); if (r) DRM_ERROR("failed to read reg (0x%x)\n", reg); else @@ -944,7 +952,9 @@ int amdgpu_mes_wreg(struct amdgpu_device *adev, goto error; }
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->misc_op(&adev->mes, &op_input); + amdgpu_mes_unlock(&adev->mes); if (r) DRM_ERROR("failed to write reg (0x%x)\n", reg);
@@ -971,7 +981,9 @@ int amdgpu_mes_reg_write_reg_wait(struct amdgpu_device *adev, goto error; }
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->misc_op(&adev->mes, &op_input); + amdgpu_mes_unlock(&adev->mes); if (r) DRM_ERROR("failed to reg_write_reg_wait\n");
@@ -996,7 +1008,9 @@ int amdgpu_mes_reg_wait(struct amdgpu_device *adev, uint32_t reg, goto error; }
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->misc_op(&adev->mes, &op_input); + amdgpu_mes_unlock(&adev->mes); if (r) DRM_ERROR("failed to reg_write_reg_wait\n");
@@ -1687,7 +1701,9 @@ static int amdgpu_mes_set_enforce_isolation(struct amdgpu_device *adev, goto error; }
+ amdgpu_mes_lock(&adev->mes); r = adev->mes.funcs->misc_op(&adev->mes, &op_input); + amdgpu_mes_unlock(&adev->mes); if (r) dev_err(adev->dev, "failed to change_config.\n");
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
[ Upstream commit 55e52d055393f11ba0193975d3db87af36f4b273 ]
Add the missing HID supplies to avoid relying on other consumers to keep them on.
This also avoids the following warnings on boot:
i2c_hid_of 0-0010: supply vdd not found, using dummy regulator i2c_hid_of 0-0010: supply vddl not found, using dummy regulator i2c_hid_of 1-0015: supply vdd not found, using dummy regulator i2c_hid_of 1-002c: supply vdd not found, using dummy regulator i2c_hid_of 1-0015: supply vddl not found, using dummy regulator i2c_hid_of 1-002c: supply vddl not found, using dummy regulator i2c_hid_of 1-003a: supply vdd not found, using dummy regulator i2c_hid_of 1-003a: supply vddl not found, using dummy regulator
Note that VCC3B is also used for things like the modem which are not yet described so mark the regulator as always-on for now.
Fixes: 7d1cbe2f4985 ("arm64: dts: qcom: Add X1E78100 ThinkPad T14s Gen 6") Cc: stable@vger.kernel.org # 6.12 Reviewed-by: Konrad Dybcio konrad.dybcio@oss.qualcomm.com Signed-off-by: Johan Hovold johan+linaro@kernel.org Link: https://lore.kernel.org/r/20250314145440.11371-9-johan+linaro@kernel.org Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../qcom/x1e78100-lenovo-thinkpad-t14s.dts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+)
diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts index 7f756ce48d2f6..999d966b44869 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts @@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/gpio-keys.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
#include "x1e80100.dtsi" @@ -153,6 +154,23 @@ vreg_edp_3p3: regulator-edp-3p3 { regulator-boot-on; };
+ vreg_misc_3p3: regulator-misc-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VCC3B"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pm8550ve_8_gpios 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&misc_3p3_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + regulator-always-on; + }; + vreg_nvme: regulator-nvme { compatible = "regulator-fixed";
@@ -580,6 +598,9 @@ touchpad@15 { hid-descr-addr = <0x1>; interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>;
+ vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l12b_1p2>; + wakeup-source; };
@@ -591,6 +612,9 @@ touchpad@2c { hid-descr-addr = <0x20>; interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>;
+ vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l12b_1p2>; + wakeup-source; };
@@ -602,6 +626,9 @@ keyboard@3a { hid-descr-addr = <0x1>; interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>;
+ vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_1p8>; + pinctrl-0 = <&kybd_default>; pinctrl-names = "default";
@@ -670,6 +697,9 @@ touchscreen@10 { hid-descr-addr = <0x1>; interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>;
+ vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_1p8>; + pinctrl-0 = <&ts0_default>; pinctrl-names = "default"; }; @@ -789,6 +819,19 @@ edp_bl_en: edp-bl-en-state { }; };
+&pm8550ve_8_gpios { + misc_3p3_reg_en: misc-3p3-reg-en-state { + pins = "gpio6"; + function = "normal"; + bias-disable; + drive-push-pull; + input-disable; + output-enable; + power-source = <1>; /* 1.8 V */ + qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; + }; +}; + &qupv3_0 { status = "okay"; };
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
[ Upstream commit c50784e99f0e7199cdb12dbddf02229b102744ef ]
Otherwise, tg->scx.weight can go out of sync while scx_cgroup is not enabled and ops.cgroup_init() may be called with a stale weight value.
Signed-off-by: Tejun Heo tj@kernel.org Fixes: 819513666966 ("sched_ext: Add cgroup support") Cc: stable@vger.kernel.org # v6.12+ Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/ext.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/kernel/sched/ext.c b/kernel/sched/ext.c index afaf49e5ecb97..86ce43fa36693 100644 --- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -4074,12 +4074,12 @@ void scx_group_set_weight(struct task_group *tg, unsigned long weight) { percpu_down_read(&scx_cgroup_rwsem);
- if (scx_cgroup_enabled && tg->scx_weight != weight) { - if (SCX_HAS_OP(cgroup_set_weight)) - SCX_CALL_OP(SCX_KF_UNLOCKED, cgroup_set_weight, NULL, - tg_cgrp(tg), weight); - tg->scx_weight = weight; - } + if (scx_cgroup_enabled && SCX_HAS_OP(cgroup_set_weight) && + tg->scx_weight != weight) + SCX_CALL_OP(SCX_KF_UNLOCKED, cgroup_set_weight, NULL, + tg_cgrp(tg), weight); + + tg->scx_weight = weight;
percpu_up_read(&scx_cgroup_rwsem); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Strauss michael.strauss@amd.com
[ Upstream commit 8989cb919b27cd0d2aadb7f1d144cedbb12e6fca ]
[WHY] Early EQ pattern sequence is required for some LTTPR + old dongle combinations.
[HOW] If DP_EARLY_8B10B_TPS2 chip cap is set, this new sequence programs phy to output TPS2 before initiating link training and writes TPS1 to LTTPR training pattern register as instructed by vendor.
Add function to get embedded LTTPR target address offset.
Reviewed-by: Wenjing Liu wenjing.liu@amd.com Signed-off-by: Michael Strauss michael.strauss@amd.com Signed-off-by: TungYu Lu tungyu.lu@amd.com Signed-off-by: Ray Wu ray.wu@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../dc/link/protocols/link_dp_capability.c | 8 +++ .../dc/link/protocols/link_dp_capability.h | 3 ++ .../dc/link/protocols/link_dp_training.c | 1 - .../link/protocols/link_dp_training_8b_10b.c | 52 +++++++++++++++++-- .../amd/display/include/link_service_types.h | 2 + 5 files changed, 62 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 21ee0d96c9d48..9d49e77a24a1f 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -158,6 +158,14 @@ uint8_t dp_parse_lttpr_repeater_count(uint8_t lttpr_repeater_count) return 0; // invalid value }
+uint32_t dp_get_closest_lttpr_offset(uint8_t lttpr_count) +{ + /* Calculate offset for LTTPR closest to DPTX which is highest in the chain + * Offset is 0 for single LTTPR cases as base LTTPR DPCD addresses target LTTPR 1 + */ + return DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE * (lttpr_count - 1); +} + uint32_t link_bw_kbps_from_raw_frl_link_rate_data(uint8_t bw) { switch (bw) { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h index 0ce0af3ddbebe..940b147cc5d42 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.h @@ -48,6 +48,9 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link); /* Convert PHY repeater count read from DPCD uint8_t. */ uint8_t dp_parse_lttpr_repeater_count(uint8_t lttpr_repeater_count);
+/* Calculate embedded LTTPR address offset for vendor-specific behaviour */ +uint32_t dp_get_closest_lttpr_offset(uint8_t lttpr_count); + bool dp_is_sink_present(struct dc_link *link);
bool dp_is_lttpr_present(struct dc_link *link); diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c index ef358afdfb65b..2dc1a660e5045 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training.c @@ -785,7 +785,6 @@ void override_training_settings( lt_settings->lttpr_mode = LTTPR_MODE_NON_LTTPR;
dp_get_lttpr_mode_override(link, <_settings->lttpr_mode); - }
enum dc_dp_training_pattern decide_cr_training_pattern( diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c index 5a5d48fadbf27..66d0fb1b9b9d2 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_training_8b_10b.c @@ -142,6 +142,14 @@ void decide_8b_10b_training_settings( lt_settings->lttpr_mode = dp_decide_8b_10b_lttpr_mode(link); lt_settings->cr_pattern_time = get_cr_training_aux_rd_interval(link, link_setting, lt_settings->lttpr_mode); dp_hw_to_dpcd_lane_settings(lt_settings, lt_settings->hw_lane_settings, lt_settings->dpcd_lane_settings); + + /* Some embedded LTTPRs rely on receiving TPS2 before LT to interop reliably with sensitive VGA dongles + * This allows these LTTPRs to minimize freq/phase and skew variation during lock and deskew sequences + */ + if ((link->chip_caps & AMD_EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK) == + AMD_EXT_DISPLAY_PATH_CAPS__DP_EARLY_8B10B_TPS2) { + lt_settings->lttpr_early_tps2 = true; + } }
enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link) @@ -173,6 +181,42 @@ enum lttpr_mode dp_decide_8b_10b_lttpr_mode(struct dc_link *link) return LTTPR_MODE_NON_LTTPR; }
+static void set_link_settings_and_perform_early_tps2_retimer_pre_lt_sequence(struct dc_link *link, + const struct link_resource *link_res, + struct link_training_settings *lt_settings, + uint32_t lttpr_count) +{ + /* Vendor-specific LTTPR early TPS2 sequence: + * 1. Output TPS2 + * 2. Wait 400us + * 3. Set link settings as usual + * 4. Write TPS1 to DP_TRAINING_PATTERN_SET_PHY_REPEATERx targeting LTTPR closest to host + * 5. Wait 1ms + * 6. Begin link training as usual + * */ + + uint32_t closest_lttpr_address_offset = dp_get_closest_lttpr_offset(lttpr_count); + + union dpcd_training_pattern dpcd_pattern = {0}; + + dpcd_pattern.v1_4.TRAINING_PATTERN_SET = 1; + dpcd_pattern.v1_4.SCRAMBLING_DISABLE = 1; + + DC_LOG_HW_LINK_TRAINING("%s\n GPU sends TPS2. Wait 400us.\n", __func__); + + dp_set_hw_training_pattern(link, link_res, DP_TRAINING_PATTERN_SEQUENCE_2, DPRX); + + dp_set_hw_lane_settings(link, link_res, lt_settings, DPRX); + + udelay(400); + + dpcd_set_link_settings(link, lt_settings); + + core_link_write_dpcd(link, DP_TRAINING_PATTERN_SET_PHY_REPEATER1 + closest_lttpr_address_offset, &dpcd_pattern.raw, 1); + + udelay(1000); + } + enum link_training_result perform_8b_10b_clock_recovery_sequence( struct dc_link *link, const struct link_resource *link_res, @@ -383,7 +427,7 @@ enum link_training_result dp_perform_8b_10b_link_training( { enum link_training_result status = LINK_TRAINING_SUCCESS;
- uint8_t repeater_cnt; + uint8_t repeater_cnt = dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); uint8_t repeater_id; uint8_t lane = 0;
@@ -391,14 +435,16 @@ enum link_training_result dp_perform_8b_10b_link_training( start_clock_recovery_pattern_early(link, link_res, lt_settings, DPRX);
/* 1. set link rate, lane count and spread. */ - dpcd_set_link_settings(link, lt_settings); + if (lt_settings->lttpr_early_tps2) + set_link_settings_and_perform_early_tps2_retimer_pre_lt_sequence(link, link_res, lt_settings, repeater_cnt); + else + dpcd_set_link_settings(link, lt_settings);
if (lt_settings->lttpr_mode == LTTPR_MODE_NON_TRANSPARENT) {
/* 2. perform link training (set link training done * to false is done as well) */ - repeater_cnt = dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt);
for (repeater_id = repeater_cnt; (repeater_id > 0 && status == LINK_TRAINING_SUCCESS); repeater_id--) { diff --git a/drivers/gpu/drm/amd/display/include/link_service_types.h b/drivers/gpu/drm/amd/display/include/link_service_types.h index 1867aac57cf2c..da74ed66c8f9d 100644 --- a/drivers/gpu/drm/amd/display/include/link_service_types.h +++ b/drivers/gpu/drm/amd/display/include/link_service_types.h @@ -89,6 +89,8 @@ struct link_training_settings { bool enhanced_framing; enum lttpr_mode lttpr_mode;
+ bool lttpr_early_tps2; + /* disallow different lanes to have different lane settings */ bool disallow_per_lane_settings; /* dpcd lane settings will always use the same hw lane settings
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Strauss michael.strauss@amd.com
[ Upstream commit d358a51444c88bcc995e471dc8cc840f19e4b374 ]
[WHY] These fields are read for the explicit purpose of detecting embedded LTTPRs (i.e. between host ASIC and the user-facing port), and thus need to calculate the correct DPCD address offset based on LTTPR count to target the appropriate LTTPR's DPCD register space with these queries.
[HOW] Cascaded LTTPRs in a link each snoop and increment LTTPR count when queried via DPCD read, so an LTTPR embedded in a source device (e.g. USB4 port on a laptop) will always be addressible using the max LTTPR count seen by the host. Therefore we simply need to use a recently added helper function to calculate the correct DPCD address to target potentially embedded LTTPRs based on the received LTTPR count.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Reviewed-by: Wenjing Liu wenjing.liu@amd.com Signed-off-by: Michael Strauss michael.strauss@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 791897f5c77a2a65d0e500be4743af2ddf6eb061) Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 4 +- .../dc/link/protocols/link_dp_capability.c | 38 +++++++++++++++---- 2 files changed, 33 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h index 77c87ad572207..bbd6701096ca9 100644 --- a/drivers/gpu/drm/amd/display/dc/dc_dp_types.h +++ b/drivers/gpu/drm/amd/display/dc/dc_dp_types.h @@ -1157,8 +1157,8 @@ struct dc_lttpr_caps { union dp_128b_132b_supported_lttpr_link_rates supported_128b_132b_rates; union dp_alpm_lttpr_cap alpm; uint8_t aux_rd_interval[MAX_REPEATER_CNT - 1]; - uint8_t lttpr_ieee_oui[3]; - uint8_t lttpr_device_id[6]; + uint8_t lttpr_ieee_oui[3]; // Always read from closest LTTPR to host + uint8_t lttpr_device_id[6]; // Always read from closest LTTPR to host };
struct dc_dongle_dfp_cap_ext { diff --git a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c index 9d49e77a24a1f..ed9d396e3d0ea 100644 --- a/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c +++ b/drivers/gpu/drm/amd/display/dc/link/protocols/link_dp_capability.c @@ -385,9 +385,15 @@ bool dp_is_128b_132b_signal(struct pipe_ctx *pipe_ctx) bool dp_is_lttpr_present(struct dc_link *link) { /* Some sink devices report invalid LTTPR revision, so don't validate against that cap */ - return (dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) != 0 && + uint32_t lttpr_count = dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); + bool is_lttpr_present = (lttpr_count > 0 && link->dpcd_caps.lttpr_caps.max_lane_count > 0 && link->dpcd_caps.lttpr_caps.max_lane_count <= 4); + + if (lttpr_count > 0 && !is_lttpr_present) + DC_LOG_ERROR("LTTPR count is nonzero but invalid lane count reported. Assuming no LTTPR present.\n"); + + return is_lttpr_present; }
/* in DP compliance test, DPR-120 may have @@ -1551,6 +1557,8 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link) uint8_t lttpr_dpcd_data[10] = {0}; enum dc_status status; bool is_lttpr_present; + uint32_t lttpr_count; + uint32_t closest_lttpr_offset;
/* Logic to determine LTTPR support*/ bool vbios_lttpr_interop = link->dc->caps.vbios_lttpr_aware; @@ -1602,20 +1610,22 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link) lttpr_dpcd_data[DP_LTTPR_ALPM_CAPABILITIES - DP_LT_TUNABLE_PHY_REPEATER_FIELD_DATA_STRUCTURE_REV];
+ lttpr_count = dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt); + /* If this chip cap is set, at least one retimer must exist in the chain * Override count to 1 if we receive a known bad count (0 or an invalid value) */ if (((link->chip_caps & AMD_EXT_DISPLAY_PATH_CAPS__EXT_CHIP_MASK) == AMD_EXT_DISPLAY_PATH_CAPS__DP_FIXED_VS_EN) && - (dp_parse_lttpr_repeater_count(link->dpcd_caps.lttpr_caps.phy_repeater_cnt) == 0)) { + lttpr_count == 0) { /* If you see this message consistently, either the host platform has FIXED_VS flag * incorrectly configured or the sink device is returning an invalid count. */ DC_LOG_ERROR("lttpr_caps phy_repeater_cnt is 0x%x, forcing it to 0x80.", link->dpcd_caps.lttpr_caps.phy_repeater_cnt); link->dpcd_caps.lttpr_caps.phy_repeater_cnt = 0x80; + lttpr_count = 1; DC_LOG_DC("lttpr_caps forced phy_repeater_cnt = %d\n", link->dpcd_caps.lttpr_caps.phy_repeater_cnt); }
- /* Attempt to train in LTTPR transparent mode if repeater count exceeds 8. */ is_lttpr_present = dp_is_lttpr_present(link);
DC_LOG_DC("is_lttpr_present = %d\n", is_lttpr_present); @@ -1623,11 +1633,25 @@ enum dc_status dp_retrieve_lttpr_cap(struct dc_link *link) if (is_lttpr_present) { CONN_DATA_DETECT(link, lttpr_dpcd_data, sizeof(lttpr_dpcd_data), "LTTPR Caps: ");
- core_link_read_dpcd(link, DP_LTTPR_IEEE_OUI, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui)); - CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui), "LTTPR IEEE OUI: "); + // Identify closest LTTPR to determine if workarounds required for known embedded LTTPR + closest_lttpr_offset = dp_get_closest_lttpr_offset(lttpr_count);
- core_link_read_dpcd(link, DP_LTTPR_DEVICE_ID, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id)); - CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id), "LTTPR Device ID: "); + core_link_read_dpcd(link, (DP_LTTPR_IEEE_OUI + closest_lttpr_offset), + link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui)); + core_link_read_dpcd(link, (DP_LTTPR_DEVICE_ID + closest_lttpr_offset), + link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id)); + + if (lttpr_count > 1) { + CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui), + "Closest LTTPR To Host's IEEE OUI: "); + CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id), + "Closest LTTPR To Host's LTTPR Device ID: "); + } else { + CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_ieee_oui, sizeof(link->dpcd_caps.lttpr_caps.lttpr_ieee_oui), + "LTTPR IEEE OUI: "); + CONN_DATA_DETECT(link, link->dpcd_caps.lttpr_caps.lttpr_device_id, sizeof(link->dpcd_caps.lttpr_caps.lttpr_device_id), + "LTTPR Device ID: "); + } }
return status;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8b5f3a229a70d242322b78c8e13744ca00212def ]
[Why] DC and AC levels are advertised in a percentage, not a luminance.
[How] Scale DC and AC levels to supported values.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4221 Reviewed-by: Alex Hung alex.hung@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Wayne Lin wayne.lin@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 96118a0e1ffeb..389748c420b02 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4834,6 +4834,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) struct backlight_properties props = { 0 }; struct amdgpu_dm_backlight_caps caps = { 0 }; char bl_name[16]; + int min, max;
if (aconnector->bl_idx == -1) return; @@ -4846,11 +4847,15 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) }
amdgpu_acpi_get_backlight_caps(&caps); - if (caps.caps_valid) { + if (caps.caps_valid && get_brightness_range(&caps, &min, &max)) { if (power_supply_is_system_supplied() > 0) - props.brightness = caps.ac_level; + props.brightness = (max - min) * DIV_ROUND_CLOSEST(caps.ac_level, 100); else - props.brightness = caps.dc_level; + props.brightness = (max - min) * DIV_ROUND_CLOSEST(caps.dc_level, 100); + /* min is zero, so max needs to be adjusted */ + props.max_brightness = max - min; + drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max, + caps.ac_level, caps.dc_level); } else props.brightness = AMDGPU_MAX_BL_LEVEL;
On 03. 07. 25, 16:42, Greg Kroah-Hartman wrote:
6.15-stable review patch. If anyone has any objections, please let me know.
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8b5f3a229a70d242322b78c8e13744ca00212def ]
This is actually 8b5f3a229a70d242322b78c8e13744ca00212def squashed with 4b61b8a390511a1864f26cc42bab72881e93468d -- why?
[Why] DC and AC levels are advertised in a percentage, not a luminance.
[How] Scale DC and AC levels to supported values.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4221 Reviewed-by: Alex Hung alex.hung@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Wayne Lin wayne.lin@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Sasha Levin sashal@kernel.org
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 96118a0e1ffeb..389748c420b02 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4834,6 +4834,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) struct backlight_properties props = { 0 }; struct amdgpu_dm_backlight_caps caps = { 0 }; char bl_name[16];
- int min, max;
if (aconnector->bl_idx == -1) return; @@ -4846,11 +4847,15 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) } amdgpu_acpi_get_backlight_caps(&caps);
- if (caps.caps_valid) {
- if (caps.caps_valid && get_brightness_range(&caps, &min, &max)) { if (power_supply_is_system_supplied() > 0)
props.brightness = caps.ac_level;
elseprops.brightness = (max - min) * DIV_ROUND_CLOSEST(caps.ac_level, 100);
props.brightness = caps.dc_level;
props.brightness = (max - min) * DIV_ROUND_CLOSEST(caps.dc_level, 100);
/* min is zero, so max needs to be adjusted */
props.max_brightness = max - min;
drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max,
} else props.brightness = AMDGPU_MAX_BL_LEVEL;caps.ac_level, caps.dc_level);
On Fri, Jul 04, 2025 at 07:00:06AM +0200, Jiri Slaby wrote:
On 03. 07. 25, 16:42, Greg Kroah-Hartman wrote:
6.15-stable review patch. If anyone has any objections, please let me know.
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8b5f3a229a70d242322b78c8e13744ca00212def ]
This is actually 8b5f3a229a70d242322b78c8e13744ca00212def squashed with 4b61b8a390511a1864f26cc42bab72881e93468d -- why?
Ick, I don't know. Let me go drop it now, good catch! Let me go verify these other drm backports too, the drm stable patch mess is never fun...
Yeah, something went wrong with Sasha's backports, some of these didn't even have an upstream commit id in them :(
I've dropped this one, and the ones after this as they weren't correct, thanks for the review!
greg k-h
On 04. 07. 25, 11:06, Greg Kroah-Hartman wrote:
On Fri, Jul 04, 2025 at 07:00:06AM +0200, Jiri Slaby wrote:
On 03. 07. 25, 16:42, Greg Kroah-Hartman wrote:
6.15-stable review patch. If anyone has any objections, please let me know.
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8b5f3a229a70d242322b78c8e13744ca00212def ]
This is actually 8b5f3a229a70d242322b78c8e13744ca00212def squashed with 4b61b8a390511a1864f26cc42bab72881e93468d -- why?
Ick, I don't know. Let me go drop it now, good catch! Let me go verify these other drm backports too, the drm stable patch mess is never fun...
Yeah, something went wrong with Sasha's backports, some of these didn't even have an upstream commit id in them :(
I've dropped this one, and the ones after this as they weren't correct, thanks for the review!
Actually, we have the two (8b5f3a229a+4b61b8a39) in our tree as they fix: https://bugzilla.suse.com/show_bug.cgi?id=1236415
So dropping them is not a good idea after all ;). Just desquash...
thanks,
On 04. 07. 25, 11:14, Jiri Slaby wrote:
On 04. 07. 25, 11:06, Greg Kroah-Hartman wrote:
On Fri, Jul 04, 2025 at 07:00:06AM +0200, Jiri Slaby wrote:
On 03. 07. 25, 16:42, Greg Kroah-Hartman wrote:
6.15-stable review patch. If anyone has any objections, please let me know.
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8b5f3a229a70d242322b78c8e13744ca00212def ]
This is actually 8b5f3a229a70d242322b78c8e13744ca00212def squashed with 4b61b8a390511a1864f26cc42bab72881e93468d -- why?
Ick, I don't know. Let me go drop it now, good catch! Let me go verify these other drm backports too, the drm stable patch mess is never fun...
Yeah, something went wrong with Sasha's backports, some of these didn't even have an upstream commit id in them :(
I've dropped this one, and the ones after this as they weren't correct, thanks for the review!
Actually, we have the two (8b5f3a229a+4b61b8a39) in our tree as they fix: https://bugzilla.suse.com/show_bug.cgi?id=1236415
No, this one: https://bugzilla.suse.com/show_bug.cgi?id=1240650
So dropping them is not a good idea after all ;). Just desquash...
thanks,
On Fri, Jul 04, 2025 at 11:17:15AM +0200, Jiri Slaby wrote:
On 04. 07. 25, 11:14, Jiri Slaby wrote:
On 04. 07. 25, 11:06, Greg Kroah-Hartman wrote:
On Fri, Jul 04, 2025 at 07:00:06AM +0200, Jiri Slaby wrote:
On 03. 07. 25, 16:42, Greg Kroah-Hartman wrote:
6.15-stable review patch. If anyone has any objections, please let me know.
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8b5f3a229a70d242322b78c8e13744ca00212def ]
This is actually 8b5f3a229a70d242322b78c8e13744ca00212def squashed with 4b61b8a390511a1864f26cc42bab72881e93468d -- why?
Ick, I don't know. Let me go drop it now, good catch! Let me go verify these other drm backports too, the drm stable patch mess is never fun...
Yeah, something went wrong with Sasha's backports, some of these didn't even have an upstream commit id in them :(
I've dropped this one, and the ones after this as they weren't correct, thanks for the review!
Actually, we have the two (8b5f3a229a+4b61b8a39) in our tree as they fix: https://bugzilla.suse.com/show_bug.cgi?id=1236415
No, this one: https://bugzilla.suse.com/show_bug.cgi?id=1240650
Thanks, now both added, and I figured out the others that Sasha had applied without git ids and then added yet-another-fix for those that was also needed.
I'll go push out a -rc2 soon with all of these in them, thanks.
greg k-h
On Fri, Jul 04, 2025 at 11:14:07AM +0200, Jiri Slaby wrote:
On 04. 07. 25, 11:06, Greg Kroah-Hartman wrote:
On Fri, Jul 04, 2025 at 07:00:06AM +0200, Jiri Slaby wrote:
On 03. 07. 25, 16:42, Greg Kroah-Hartman wrote:
6.15-stable review patch. If anyone has any objections, please let me know.
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 8b5f3a229a70d242322b78c8e13744ca00212def ]
This is actually 8b5f3a229a70d242322b78c8e13744ca00212def squashed with 4b61b8a390511a1864f26cc42bab72881e93468d -- why?
Ick, I don't know. Let me go drop it now, good catch! Let me go verify these other drm backports too, the drm stable patch mess is never fun...
Yeah, something went wrong with Sasha's backports, some of these didn't even have an upstream commit id in them :(
I've dropped this one, and the ones after this as they weren't correct, thanks for the review!
Actually, we have the two (8b5f3a229a+4b61b8a39) in our tree as they fix: https://bugzilla.suse.com/show_bug.cgi?id=1236415
So dropping them is not a good idea after all ;). Just desquash...
Ah. Ok, I've applied them individually and that worked. Let me try to figure out what the ones that Sasha added that had no git id were from...
greg k-h
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit ffcaed1d7ecef31198000dfbbea791f30f7ca437 ]
[WHY] Backlight caps are read already in amdgpu_dm_update_backlight_caps(). They may be updated by update_connector_ext_caps(). Reading again when registering backlight device may cause wrong values to be used.
[HOW] Use backlight caps already registered to the dm.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Reviewed-by: Roman Li roman.li@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 148144f6d2f14b02eaaa39b86bbe023cbff350bd) Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 389748c420b02..e61166a8230b6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4832,7 +4832,7 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) struct drm_device *drm = aconnector->base.dev; struct amdgpu_display_manager *dm = &drm_to_adev(drm)->dm; struct backlight_properties props = { 0 }; - struct amdgpu_dm_backlight_caps caps = { 0 }; + struct amdgpu_dm_backlight_caps *caps; char bl_name[16]; int min, max;
@@ -4846,20 +4846,20 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) return; }
- amdgpu_acpi_get_backlight_caps(&caps); - if (caps.caps_valid && get_brightness_range(&caps, &min, &max)) { + caps = &dm->backlight_caps[aconnector->bl_idx]; + if (get_brightness_range(caps, &min, &max)) { if (power_supply_is_system_supplied() > 0) - props.brightness = (max - min) * DIV_ROUND_CLOSEST(caps.ac_level, 100); + props.brightness = (max - min) * DIV_ROUND_CLOSEST(caps->ac_level, 100); else - props.brightness = (max - min) * DIV_ROUND_CLOSEST(caps.dc_level, 100); + props.brightness = (max - min) * DIV_ROUND_CLOSEST(caps->dc_level, 100); /* min is zero, so max needs to be adjusted */ props.max_brightness = max - min; drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max, - caps.ac_level, caps.dc_level); + caps->ac_level, caps->dc_level); } else props.brightness = AMDGPU_MAX_BL_LEVEL;
- if (caps.data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) + if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) drm_info(drm, "Using custom brightness curve\n"); props.max_brightness = AMDGPU_MAX_BL_LEVEL; props.type = BACKLIGHT_RAW;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[Why] When BIOS includes a lot of custom brightness data points, walking the entire list can be time consuming. This is most noticed when dragging a power slider. The "higher" values are "slower" to drag around.
[How] Move custom brightness calculation loop into a static function. Before starting the loop check the "half way" data point to see how it compares to the input. If greater than the half way data point use that as the starting point instead.
Reviewed-by: Alex Hung alex.hung@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Roman Li roman.li@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 53 ++++++++++++------- 1 file changed, 33 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index e61166a8230b6..a9a719f051f90 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4655,41 +4655,54 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, return 1; }
-static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps, - uint32_t brightness) +static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps, + uint32_t *brightness) { - unsigned int min, max; u8 prev_signal = 0, prev_lum = 0; + int i = 0;
- if (!get_brightness_range(caps, &min, &max)) - return brightness; - - for (int i = 0; i < caps->data_points; i++) { - u8 signal, lum; + if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE) + return;
- if (amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE) - break; + if (!caps->data_points) + return;
- signal = caps->luminance_data[i].input_signal; - lum = caps->luminance_data[i].luminance; + /* choose start to run less interpolation steps */ + if (caps->luminance_data[caps->data_points/2].input_signal > *brightness) + i = caps->data_points/2; + do { + u8 signal = caps->luminance_data[i].input_signal; + u8 lum = caps->luminance_data[i].luminance;
/* * brightness == signal: luminance is percent numerator * brightness < signal: interpolate between previous and current luminance numerator * brightness > signal: find next data point */ - if (brightness < signal) - lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) * - (brightness - prev_signal), - signal - prev_signal); - else if (brightness > signal) { + if (*brightness > signal) { prev_signal = signal; prev_lum = lum; + i++; continue; } - brightness = DIV_ROUND_CLOSEST(lum * brightness, 101); - break; - } + if (*brightness < signal) + lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) * + (*brightness - prev_signal), + signal - prev_signal); + *brightness = DIV_ROUND_CLOSEST(lum * *brightness, 101); + return; + } while (i < caps->data_points); +} + +static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *caps, + uint32_t brightness) +{ + unsigned int min, max; + + if (!get_brightness_range(caps, &min, &max)) + return brightness; + + convert_custom_brightness(caps, &brightness);
// Rescale 0..255 to min..max return min + DIV_ROUND_CLOSEST((max - min) * brightness,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[WHY] Userspace currently is offered a range from 0-0xFF but the PWM is programmed from 0-0xFFFF. This can be limiting to some software that wants to apply greater granularity.
[HOW] Convert internally to firmware values only when mapping custom brightness curves because these are in 0-0xFF range. Advertise full PWM range to userspace.
Cc: Mario Limonciello mario.limonciello@amd.com Cc: Alex Deucher alexander.deucher@amd.com Reviewed-by: Roman Li roman.li@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Alex Hung alex.hung@amd.com Tested-by: Daniel Wheeler daniel.wheeler@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 8dbd72cb790058ce52279af38a43c2b302fdd3e5) Cc: stable@vger.kernel.org --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 41 ++++++++++++------- 1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index a9a719f051f90..c5c2f82448f21 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -4655,9 +4655,23 @@ static int get_brightness_range(const struct amdgpu_dm_backlight_caps *caps, return 1; }
+/* Rescale from [min..max] to [0..AMDGPU_MAX_BL_LEVEL] */ +static inline u32 scale_input_to_fw(int min, int max, u64 input) +{ + return DIV_ROUND_CLOSEST_ULL(input * AMDGPU_MAX_BL_LEVEL, max - min); +} + +/* Rescale from [0..AMDGPU_MAX_BL_LEVEL] to [min..max] */ +static inline u32 scale_fw_to_input(int min, int max, u64 input) +{ + return min + DIV_ROUND_CLOSEST_ULL(input * (max - min), AMDGPU_MAX_BL_LEVEL); +} + static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *caps, - uint32_t *brightness) + unsigned int min, unsigned int max, + uint32_t *user_brightness) { + u32 brightness = scale_input_to_fw(min, max, *user_brightness); u8 prev_signal = 0, prev_lum = 0; int i = 0;
@@ -4668,7 +4682,7 @@ static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *cap return;
/* choose start to run less interpolation steps */ - if (caps->luminance_data[caps->data_points/2].input_signal > *brightness) + if (caps->luminance_data[caps->data_points/2].input_signal > brightness) i = caps->data_points/2; do { u8 signal = caps->luminance_data[i].input_signal; @@ -4679,17 +4693,18 @@ static void convert_custom_brightness(const struct amdgpu_dm_backlight_caps *cap * brightness < signal: interpolate between previous and current luminance numerator * brightness > signal: find next data point */ - if (*brightness > signal) { + if (brightness > signal) { prev_signal = signal; prev_lum = lum; i++; continue; } - if (*brightness < signal) + if (brightness < signal) lum = prev_lum + DIV_ROUND_CLOSEST((lum - prev_lum) * - (*brightness - prev_signal), + (brightness - prev_signal), signal - prev_signal); - *brightness = DIV_ROUND_CLOSEST(lum * *brightness, 101); + *user_brightness = scale_fw_to_input(min, max, + DIV_ROUND_CLOSEST(lum * brightness, 101)); return; } while (i < caps->data_points); } @@ -4702,11 +4717,10 @@ static u32 convert_brightness_from_user(const struct amdgpu_dm_backlight_caps *c if (!get_brightness_range(caps, &min, &max)) return brightness;
- convert_custom_brightness(caps, &brightness); + convert_custom_brightness(caps, min, max, &brightness);
- // Rescale 0..255 to min..max - return min + DIV_ROUND_CLOSEST((max - min) * brightness, - AMDGPU_MAX_BL_LEVEL); + // Rescale 0..max to min..max + return min + DIV_ROUND_CLOSEST_ULL((u64)(max - min) * brightness, max); }
static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *caps, @@ -4719,8 +4733,8 @@ static u32 convert_brightness_to_user(const struct amdgpu_dm_backlight_caps *cap
if (brightness < min) return 0; - // Rescale min..max to 0..255 - return DIV_ROUND_CLOSEST(AMDGPU_MAX_BL_LEVEL * (brightness - min), + // Rescale min..max to 0..max + return DIV_ROUND_CLOSEST_ULL((u64)max * (brightness - min), max - min); }
@@ -4870,11 +4884,10 @@ amdgpu_dm_register_backlight_device(struct amdgpu_dm_connector *aconnector) drm_dbg(drm, "Backlight caps: min: %d, max: %d, ac %d, dc %d\n", min, max, caps->ac_level, caps->dc_level); } else - props.brightness = AMDGPU_MAX_BL_LEVEL; + props.brightness = props.max_brightness = AMDGPU_MAX_BL_LEVEL;
if (caps->data_points && !(amdgpu_dc_debug_mask & DC_DISABLE_CUSTOM_BRIGHTNESS_CURVE)) drm_info(drm, "Using custom brightness curve\n"); - props.max_brightness = AMDGPU_MAX_BL_LEVEL; props.type = BACKLIGHT_RAW;
snprintf(bl_name, sizeof(bl_name), "amdgpu_bl%d",
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich dakr@kernel.org
commit 1b56e765bf8990f1f60e124926c11fc4ac63d752 upstream.
Implement a minimal abstraction for the completion synchronization primitive.
This initial abstraction only adds complete_all() and wait_for_completion(), since that is what is required for the subsequent Devres patch.
Cc: Ingo Molnar mingo@redhat.com Cc: Peter Zijlstra peterz@infradead.org Cc: Juri Lelli juri.lelli@redhat.com Cc: Vincent Guittot vincent.guittot@linaro.org Cc: Dietmar Eggemann dietmar.eggemann@arm.com Cc: Steven Rostedt rostedt@goodmis.org Cc: Ben Segall bsegall@google.com Cc: Mel Gorman mgorman@suse.de Cc: Valentin Schneider vschneid@redhat.com Reviewed-by: Alice Ryhl aliceryhl@google.com Reviewed-by: Boqun Feng boqun.feng@gmail.com Reviewed-by: Benno Lossin lossin@kernel.org Acked-by: Miguel Ojeda ojeda@kernel.org Link: https://lore.kernel.org/r/20250612121817.1621-2-dakr@kernel.org Signed-off-by: Danilo Krummrich dakr@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- rust/bindings/bindings_helper.h | 1 rust/helpers/completion.c | 8 ++ rust/helpers/helpers.c | 1 rust/kernel/sync.rs | 2 rust/kernel/sync/completion.rs | 112 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 rust/helpers/completion.c create mode 100644 rust/kernel/sync/completion.rs
--- a/rust/bindings/bindings_helper.h +++ b/rust/bindings/bindings_helper.h @@ -10,6 +10,7 @@ #include <linux/blk-mq.h> #include <linux/blk_types.h> #include <linux/blkdev.h> +#include <linux/completion.h> #include <linux/cpumask.h> #include <linux/cred.h> #include <linux/device/faux.h> --- /dev/null +++ b/rust/helpers/completion.c @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <linux/completion.h> + +void rust_helper_init_completion(struct completion *x) +{ + init_completion(x); +} --- a/rust/helpers/helpers.c +++ b/rust/helpers/helpers.c @@ -11,6 +11,7 @@ #include "bug.c" #include "build_assert.c" #include "build_bug.c" +#include "completion.c" #include "cpumask.c" #include "cred.c" #include "device.c" --- a/rust/kernel/sync.rs +++ b/rust/kernel/sync.rs @@ -10,6 +10,7 @@ use crate::types::Opaque; use pin_init;
mod arc; +pub mod completion; mod condvar; pub mod lock; mod locked_by; @@ -17,6 +18,7 @@ pub mod poll; pub mod rcu;
pub use arc::{Arc, ArcBorrow, UniqueArc}; +pub use completion::Completion; pub use condvar::{new_condvar, CondVar, CondVarTimeoutResult}; pub use lock::global::{global_lock, GlobalGuard, GlobalLock, GlobalLockBackend, GlobalLockedBy}; pub use lock::mutex::{new_mutex, Mutex, MutexGuard}; --- /dev/null +++ b/rust/kernel/sync/completion.rs @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! Completion support. +//! +//! Reference: https://docs.kernel.org/scheduler/completion.html +//! +//! C header: [`include/linux/completion.h`](srctree/include/linux/completion.h) + +use crate::{bindings, prelude::*, types::Opaque}; + +/// Synchronization primitive to signal when a certain task has been completed. +/// +/// The [`Completion`] synchronization primitive signals when a certain task has been completed by +/// waking up other tasks that have been queued up to wait for the [`Completion`] to be completed. +/// +/// # Examples +/// +/// ``` +/// use kernel::sync::{Arc, Completion}; +/// use kernel::workqueue::{self, impl_has_work, new_work, Work, WorkItem}; +/// +/// #[pin_data] +/// struct MyTask { +/// #[pin] +/// work: Work<MyTask>, +/// #[pin] +/// done: Completion, +/// } +/// +/// impl_has_work! { +/// impl HasWork<Self> for MyTask { self.work } +/// } +/// +/// impl MyTask { +/// fn new() -> Result<Arc<Self>> { +/// let this = Arc::pin_init(pin_init!(MyTask { +/// work <- new_work!("MyTask::work"), +/// done <- Completion::new(), +/// }), GFP_KERNEL)?; +/// +/// let _ = workqueue::system().enqueue(this.clone()); +/// +/// Ok(this) +/// } +/// +/// fn wait_for_completion(&self) { +/// self.done.wait_for_completion(); +/// +/// pr_info!("Completion: task complete\n"); +/// } +/// } +/// +/// impl WorkItem for MyTask { +/// type Pointer = Arc<MyTask>; +/// +/// fn run(this: Arc<MyTask>) { +/// // process this task +/// this.done.complete_all(); +/// } +/// } +/// +/// let task = MyTask::new()?; +/// task.wait_for_completion(); +/// # Ok::<(), Error>(()) +/// ``` +#[pin_data] +pub struct Completion { + #[pin] + inner: Opaquebindings::completion, +} + +// SAFETY: `Completion` is safe to be send to any task. +unsafe impl Send for Completion {} + +// SAFETY: `Completion` is safe to be accessed concurrently. +unsafe impl Sync for Completion {} + +impl Completion { + /// Create an initializer for a new [`Completion`]. + pub fn new() -> impl PinInit<Self> { + pin_init!(Self { + inner <- Opaque::ffi_init(|slot: *mut bindings::completion| { + // SAFETY: `slot` is a valid pointer to an uninitialized `struct completion`. + unsafe { bindings::init_completion(slot) }; + }), + }) + } + + fn as_raw(&self) -> *mut bindings::completion { + self.inner.get() + } + + /// Signal all tasks waiting on this completion. + /// + /// This method wakes up all tasks waiting on this completion; after this operation the + /// completion is permanently done, i.e. signals all current and future waiters. + pub fn complete_all(&self) { + // SAFETY: `self.as_raw()` is a pointer to a valid `struct completion`. + unsafe { bindings::complete_all(self.as_raw()) }; + } + + /// Wait for completion of a task. + /// + /// This method waits for the completion of a task; it is not interruptible and there is no + /// timeout. + /// + /// See also [`Completion::complete_all`]. + pub fn wait_for_completion(&self) { + // SAFETY: `self.as_raw()` is a pointer to a valid `struct completion`. + unsafe { bindings::wait_for_completion(self.as_raw()) }; + } +}
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich dakr@kernel.org
commit 4b76fafb20dd4a2becb94949d78e86bc88006509 upstream.
Return a boolean from Revocable::revoke() and Revocable::revoke_nosync() to indicate whether the data has been revoked already.
Return true if the data hasn't been revoked yet (i.e. this call revoked the data), false otherwise.
This is required by Devres in order to synchronize the completion of the revoke process.
Reviewed-by: Benno Lossin lossin@kernel.org Acked-by: Miguel Ojeda ojeda@kernel.org Link: https://lore.kernel.org/r/20250612121817.1621-3-dakr@kernel.org Signed-off-by: Danilo Krummrich dakr@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- rust/kernel/revocable.rs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-)
--- a/rust/kernel/revocable.rs +++ b/rust/kernel/revocable.rs @@ -126,8 +126,10 @@ impl<T> Revocable<T> { /// # Safety /// /// Callers must ensure that there are no more concurrent users of the revocable object. - unsafe fn revoke_internal<const SYNC: bool>(&self) { - if self.is_available.swap(false, Ordering::Relaxed) { + unsafe fn revoke_internal<const SYNC: bool>(&self) -> bool { + let revoke = self.is_available.swap(false, Ordering::Relaxed); + + if revoke { if SYNC { // SAFETY: Just an FFI call, there are no further requirements. unsafe { bindings::synchronize_rcu() }; @@ -137,6 +139,8 @@ impl<T> Revocable<T> { // `compare_exchange` above that takes `is_available` from `true` to `false`. unsafe { drop_in_place(self.data.get()) }; } + + revoke }
/// Revokes access to and drops the wrapped object. @@ -144,10 +148,13 @@ impl<T> Revocable<T> { /// Access to the object is revoked immediately to new callers of [`Revocable::try_access`], /// expecting that there are no concurrent users of the object. /// + /// Returns `true` if `&self` has been revoked with this call, `false` if it was revoked + /// already. + /// /// # Safety /// /// Callers must ensure that there are no more concurrent users of the revocable object. - pub unsafe fn revoke_nosync(&self) { + pub unsafe fn revoke_nosync(&self) -> bool { // SAFETY: By the safety requirement of this function, the caller ensures that nobody is // accessing the data anymore and hence we don't have to wait for the grace period to // finish. @@ -161,7 +168,10 @@ impl<T> Revocable<T> { /// If there are concurrent users of the object (i.e., ones that called /// [`Revocable::try_access`] beforehand and still haven't dropped the returned guard), this /// function waits for the concurrent access to complete before dropping the wrapped object. - pub fn revoke(&self) { + /// + /// Returns `true` if `&self` has been revoked with this call, `false` if it was revoked + /// already. + pub fn revoke(&self) -> bool { // SAFETY: By passing `true` we ask `revoke_internal` to wait for the grace period to // finish. unsafe { self.revoke_internal::<true>() }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich dakr@kernel.org
commit f744201c6159fc7323c40936fd079525f7063598 upstream.
In Devres::drop() we first remove the devres action and then drop the wrapped device resource.
The design goal is to give the owner of a Devres object control over when the device resource is dropped, but limit the overall scope to the corresponding device being bound to a driver.
However, there's a race that was introduced with commit 8ff656643d30 ("rust: devres: remove action in `Devres::drop`"), but also has been (partially) present from the initial version on.
In Devres::drop(), the devres action is removed successfully and subsequently the destructor of the wrapped device resource runs. However, there is no guarantee that the destructor of the wrapped device resource completes before the driver core is done unbinding the corresponding device.
If in Devres::drop(), the devres action can't be removed, it means that the devres callback has been executed already, or is still running concurrently. In case of the latter, either Devres::drop() wins revoking the Revocable or the devres callback wins revoking the Revocable. If Devres::drop() wins, we (again) have no guarantee that the destructor of the wrapped device resource completes before the driver core is done unbinding the corresponding device.
CPU0 CPU1 ------------------------------------------------------------------------ Devres::drop() { Devres::devres_callback() { self.data.revoke() { this.data.revoke() { is_available.swap() == true is_available.swap == false } }
// [...] // device fully unbound drop_in_place() { // release device resource } } }
Depending on the specific device resource, this can potentially lead to user-after-free bugs.
In order to fix this, implement the following logic.
In the devres callback, we're always good when we get to revoke the device resource ourselves, i.e. Revocable::revoke() returns true.
If Revocable::revoke() returns false, it means that Devres::drop(), concurrently, already drops the device resource and we have to wait for Devres::drop() to signal that it finished dropping the device resource.
Note that if we hit the case where we need to wait for the completion of Devres::drop() in the devres callback, it means that we're actually racing with a concurrent Devres::drop() call, which already started revoking the device resource for us. This is rather unlikely and means that the concurrent Devres::drop() already started doing our work and we just need to wait for it to complete it for us. Hence, there should not be any additional overhead from that.
(Actually, for now it's even better if Devres::drop() does the work for us, since it can bypass the synchronize_rcu() call implied by Revocable::revoke(), but this goes away anyways once I get to implement the split devres callback approach, which allows us to first flip the atomics of all registered Devres objects of a certain device, execute a single synchronize_rcu() and then drop all revocable objects.)
In Devres::drop() we try to revoke the device resource. If that is *not* successful, it means that the devres callback already did and we're good.
Otherwise, we try to remove the devres action, which, if successful, means that we're good, since the device resource has just been revoked by us *before* we removed the devres action successfully.
If the devres action could not be removed, it means that the devres callback must be running concurrently, hence we signal that the device resource has been revoked by us, using the completion.
This makes it safe to drop a Devres object from any task and at any point of time, which is one of the design goals.
Fixes: 76c01ded724b ("rust: add devres abstraction") Reported-by: Alice Ryhl aliceryhl@google.com Closes: https://lore.kernel.org/lkml/aD64YNuqbPPZHAa5@google.com/ Reviewed-by: Benno Lossin lossin@kernel.org Link: https://lore.kernel.org/r/20250612121817.1621-4-dakr@kernel.org Signed-off-by: Danilo Krummrich dakr@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- rust/kernel/devres.rs | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-)
--- a/rust/kernel/devres.rs +++ b/rust/kernel/devres.rs @@ -13,7 +13,7 @@ use crate::{ ffi::c_void, prelude::*, revocable::Revocable, - sync::Arc, + sync::{Arc, Completion}, types::ARef, };
@@ -25,13 +25,17 @@ struct DevresInner<T> { callback: unsafe extern "C" fn(*mut c_void), #[pin] data: Revocable<T>, + #[pin] + revoke: Completion, }
/// This abstraction is meant to be used by subsystems to containerize [`Device`] bound resources to /// manage their lifetime. /// /// [`Device`] bound resources should be freed when either the resource goes out of scope or the -/// [`Device`] is unbound respectively, depending on what happens first. +/// [`Device`] is unbound respectively, depending on what happens first. In any case, it is always +/// guaranteed that revoking the device resource is completed before the corresponding [`Device`] +/// is unbound. /// /// To achieve that [`Devres`] registers a devres callback on creation, which is called once the /// [`Device`] is unbound, revoking access to the encapsulated resource (see also [`Revocable`]). @@ -105,6 +109,7 @@ impl<T> DevresInner<T> { dev: dev.into(), callback: Self::devres_callback, data <- Revocable::new(data), + revoke <- Completion::new(), }), flags, )?; @@ -133,26 +138,28 @@ impl<T> DevresInner<T> { self as _ }
- fn remove_action(this: &Arc<Self>) { + fn remove_action(this: &Arc<Self>) -> bool { // SAFETY: // - `self.inner.dev` is a valid `Device`, // - the `action` and `data` pointers are the exact same ones as given to devm_add_action() // previously, // - `self` is always valid, even if the action has been released already. - let ret = unsafe { + let success = unsafe { bindings::devm_remove_action_nowarn( this.dev.as_raw(), Some(this.callback), this.as_ptr() as _, ) - }; + } == 0;
- if ret == 0 { + if success { // SAFETY: We leaked an `Arc` reference to devm_add_action() in `DevresInner::new`; if // devm_remove_action_nowarn() was successful we can (and have to) claim back ownership // of this reference. let _ = unsafe { Arc::from_raw(this.as_ptr()) }; } + + success }
#[allow(clippy::missing_safety_doc)] @@ -164,7 +171,12 @@ impl<T> DevresInner<T> { // `DevresInner::new`. let inner = unsafe { Arc::from_raw(ptr) };
- inner.data.revoke(); + if !inner.data.revoke() { + // If `revoke()` returns false, it means that `Devres::drop` already started revoking + // `inner.data` for us. Hence we have to wait until `Devres::drop()` signals that it + // completed revoking `inner.data`. + inner.revoke.wait_for_completion(); + } } }
@@ -196,6 +208,15 @@ impl<T> Deref for Devres<T> {
impl<T> Drop for Devres<T> { fn drop(&mut self) { - DevresInner::remove_action(&self.0); + // SAFETY: When `drop` runs, it is guaranteed that nobody is accessing the revocable data + // anymore, hence it is safe not to wait for the grace period to finish. + if unsafe { self.revoke_nosync() } { + // We revoked `self.0.data` before the devres action did, hence try to remove it. + if !DevresInner::remove_action(&self.0) { + // We could not remove the devres action, which means that it now runs concurrently, + // hence signal that `self.0.data` has been revoked successfully. + self.0.revoke.complete_all(); + } + } } }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich dakr@kernel.org
commit 20c96ed278e362ae4e324ed7d8c69fb48c508d3c upstream.
We can't expose direct access to the internal Revocable, since this allows users to directly revoke the internal Revocable without Devres having the chance to synchronize with the devres callback -- we have to guarantee that the internal Revocable has been fully revoked before the device is fully unbound.
Hence, remove the corresponding Deref implementation and, instead, provide indirect accessors for the internal Revocable.
Note that we can still support Devres::revoke() by implementing the required synchronization (which would be almost identical to the synchronization in Devres::drop()).
Fixes: 76c01ded724b ("rust: add devres abstraction") Reviewed-by: Benno Lossin lossin@kernel.org Link: https://lore.kernel.org/r/20250611174827.380555-1-dakr@kernel.org Signed-off-by: Danilo Krummrich dakr@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- rust/kernel/devres.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
--- a/rust/kernel/devres.rs +++ b/rust/kernel/devres.rs @@ -12,13 +12,11 @@ use crate::{ error::{Error, Result}, ffi::c_void, prelude::*, - revocable::Revocable, - sync::{Arc, Completion}, + revocable::{Revocable, RevocableGuard}, + sync::{rcu, Arc, Completion}, types::ARef, };
-use core::ops::Deref; - #[pin_data] struct DevresInner<T> { dev: ARef<Device>, @@ -196,13 +194,15 @@ impl<T> Devres<T> {
Ok(()) } -}
-impl<T> Deref for Devres<T> { - type Target = Revocable<T>; + /// [`Devres`] accessor for [`Revocable::try_access`]. + pub fn try_access(&self) -> Option<RevocableGuard<'_, T>> { + self.0.data.try_access() + }
- fn deref(&self) -> &Self::Target { - &self.0.data + /// [`Devres`] accessor for [`Revocable::try_access_with_guard`]. + pub fn try_access_with_guard<'a>(&'a self, guard: &'a rcu::Guard) -> Option<&'a T> { + self.0.data.try_access_with_guard(guard) } }
@@ -210,7 +210,7 @@ impl<T> Drop for Devres<T> { fn drop(&mut self) { // SAFETY: When `drop` runs, it is guaranteed that nobody is accessing the revocable data // anymore, hence it is safe not to wait for the grace period to finish. - if unsafe { self.revoke_nosync() } { + if unsafe { self.0.data.revoke_nosync() } { // We revoked `self.0.data` before the devres action did, hence try to remove it. if !DevresInner::remove_action(&self.0) { // We could not remove the devres action, which means that it now runs concurrently,
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chang S. Bae chang.seok.bae@intel.com
commit 64e54461ab6e8524a8de4e63b7d1a3e4481b5cf3 upstream.
Currently, saving register states in the signal frame, the legacy feature bits are always set in xregs_state->header->xfeatures. This code sequence can be generalized for reuse in similar cases.
Refactor the logic to ensure a consistent approach across similar usages.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Andy Lutomirski luto@kernel.org Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Oleg Nesterov oleg@redhat.com Link: https://lore.kernel.org/r/20250416021720.12305-8-chang.seok.bae@intel.com Cc: Ben Hutchings ben@decadent.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/fpu/signal.c | 11 +---------- arch/x86/kernel/fpu/xstate.h | 13 +++++++++++++ 2 files changed, 14 insertions(+), 10 deletions(-)
--- a/arch/x86/kernel/fpu/signal.c +++ b/arch/x86/kernel/fpu/signal.c @@ -114,7 +114,6 @@ static inline bool save_xstate_epilog(vo { struct xregs_state __user *x = buf; struct _fpx_sw_bytes sw_bytes = {}; - u32 xfeatures; int err;
/* Setup the bytes not touched by the [f]xsave and reserved for SW. */ @@ -128,12 +127,6 @@ static inline bool save_xstate_epilog(vo (__u32 __user *)(buf + fpstate->user_size));
/* - * Read the xfeatures which we copied (directly from the cpu or - * from the state in task struct) to the user buffers. - */ - err |= __get_user(xfeatures, (__u32 __user *)&x->header.xfeatures); - - /* * For legacy compatible, we always set FP/SSE bits in the bit * vector while saving the state to the user context. This will * enable us capturing any changes(during sigreturn) to @@ -144,9 +137,7 @@ static inline bool save_xstate_epilog(vo * header as well as change any contents in the memory layout. * xrestore as part of sigreturn will capture all the changes. */ - xfeatures |= XFEATURE_MASK_FPSSE; - - err |= __put_user(xfeatures, (__u32 __user *)&x->header.xfeatures); + err |= set_xfeature_in_sigframe(x, XFEATURE_MASK_FPSSE);
return !err; } --- a/arch/x86/kernel/fpu/xstate.h +++ b/arch/x86/kernel/fpu/xstate.h @@ -69,6 +69,19 @@ static inline u64 xfeatures_mask_indepen return fpu_kernel_cfg.independent_features; }
+static inline int set_xfeature_in_sigframe(struct xregs_state __user *xbuf, u64 mask) +{ + u64 xfeatures; + int err; + + /* Read the xfeatures value already saved in the user buffer */ + err = __get_user(xfeatures, &xbuf->header.xfeatures); + xfeatures |= mask; + err |= __put_user(xfeatures, &xbuf->header.xfeatures); + + return err; +} + /* * Update the value of PKRU register that was already pushed onto the signal frame. */
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chang S. Bae chang.seok.bae@intel.com
commit d1e420772cd1eb0afe5858619c73ce36f3e781a1 upstream.
The signal delivery logic was modified to always set the PKRU bit in xregs_state->header->xfeatures by this commit:
ae6012d72fa6 ("x86/pkeys: Ensure updated PKRU value is XRSTOR'd")
However, the change derives the bitmask value using XGETBV(1), rather than simply updating the buffer that already holds the value. Thus, this approach induces an unnecessary dependency on XGETBV1 for PKRU handling.
Eliminate the dependency by using the established helper function. Subsequently, remove the now-unused 'mask' argument.
Signed-off-by: Chang S. Bae chang.seok.bae@intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Andy Lutomirski luto@kernel.org Cc: Aruna Ramakrishna aruna.ramakrishna@oracle.com Cc: H. Peter Anvin hpa@zytor.com Cc: Linus Torvalds torvalds@linux-foundation.org Cc: Oleg Nesterov oleg@redhat.com Cc: Tony W Wang-oc TonyWWang-oc@zhaoxin.com Cc: Dave Hansen dave.hansen@linux.intel.com Link: https://lore.kernel.org/r/20250416021720.12305-9-chang.seok.bae@intel.com Cc: Ben Hutchings ben@decadent.org.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kernel/fpu/xstate.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-)
--- a/arch/x86/kernel/fpu/xstate.h +++ b/arch/x86/kernel/fpu/xstate.h @@ -85,18 +85,15 @@ static inline int set_xfeature_in_sigfra /* * Update the value of PKRU register that was already pushed onto the signal frame. */ -static inline int update_pkru_in_sigframe(struct xregs_state __user *buf, u64 mask, u32 pkru) +static inline int update_pkru_in_sigframe(struct xregs_state __user *buf, u32 pkru) { - u64 xstate_bv; int err;
if (unlikely(!cpu_feature_enabled(X86_FEATURE_OSPKE))) return 0;
/* Mark PKRU as in-use so that it is restored correctly. */ - xstate_bv = (mask & xfeatures_in_use()) | XFEATURE_MASK_PKRU; - - err = __put_user(xstate_bv, &buf->header.xfeatures); + err = set_xfeature_in_sigframe(buf, XFEATURE_MASK_PKRU); if (err) return err;
@@ -320,7 +317,7 @@ static inline int xsave_to_user_sigframe clac();
if (!err) - err = update_pkru_in_sigframe(buf, mask, pkru); + err = update_pkru_in_sigframe(buf, pkru);
return err; }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens hca@linux.ibm.com
commit 7f8073cfb04a97842fe891ca50dad60afd1e3121 upstream.
The recent change which added READ_ONCE_NOCHECK() to read the nth entry from the kernel stack incorrectly dropped dereferencing of the stack pointer in order to read the requested entry.
In result the address of the entry is returned instead of its content.
Dereference the pointer again to fix this.
Reported-by: Will Deacon will@kernel.org Closes: https://lore.kernel.org/r/20250612163331.GA13384@willie-the-truck Fixes: d93a855c31b7 ("s390/ptrace: Avoid KASAN false positives in regs_get_kernel_stack_nth()") Cc: stable@vger.kernel.org Reviewed-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com Signed-off-by: Alexander Gordeev agordeev@linux.ibm.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/s390/kernel/ptrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -1574,5 +1574,5 @@ unsigned long regs_get_kernel_stack_nth( addr = kernel_stack_pointer(regs) + n * sizeof(long); if (!regs_within_kernel_stack(regs, addr)) return 0; - return READ_ONCE_NOCHECK(addr); + return READ_ONCE_NOCHECK(*(unsigned long *)addr); }
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe axboe@kernel.dk
Commit 178b8ff66ff827c41b4fa105e9aabb99a0b5c537 upstream.
A previous commit aborted mapping more for a non-incremental ring for bundle peeking, but depending on where in the process this peeking happened, it would not necessarily prevent a retry by the user. That can create gaps in the received/read data.
Add struct buf_sel_arg->partial_map, which can pass this information back. The networking side can then map that to internal state and use it to gate retry as well.
Since this necessitates a new flag, change io_sr_msg->retry to a retry_flags member, and store both the retry and partial map condition in there.
Cc: stable@vger.kernel.org Fixes: 26ec15e4b0c1 ("io_uring/kbuf: don't truncate end buffer for multiple buffer peeks") Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/kbuf.c | 1 + io_uring/kbuf.h | 1 + io_uring/net.c | 23 +++++++++++++++-------- 3 files changed, 17 insertions(+), 8 deletions(-)
--- a/io_uring/kbuf.c +++ b/io_uring/kbuf.c @@ -271,6 +271,7 @@ static int io_ring_buffers_peek(struct i if (len > arg->max_len) { len = arg->max_len; if (!(bl->flags & IOBL_INC)) { + arg->partial_map = 1; if (iov != arg->iovs) break; buf->len = len; --- a/io_uring/kbuf.h +++ b/io_uring/kbuf.h @@ -55,6 +55,7 @@ struct buf_sel_arg { size_t max_len; unsigned short nr_iovs; unsigned short mode; + unsigned short partial_map; };
void __user *io_buffer_select(struct io_kiocb *req, size_t *len, --- a/io_uring/net.c +++ b/io_uring/net.c @@ -76,12 +76,17 @@ struct io_sr_msg { u16 flags; /* initialised and used only by !msg send variants */ u16 buf_group; - bool retry; + unsigned short retry_flags; void __user *msg_control; /* used only for send zerocopy */ struct io_kiocb *notif; };
+enum sr_retry_flags { + IO_SR_MSG_RETRY = 1, + IO_SR_MSG_PARTIAL_MAP = 2, +}; + /* * Number of times we'll try and do receives if there's more data. If we * exceed this limit, then add us to the back of the queue and retry from @@ -188,7 +193,7 @@ static inline void io_mshot_prep_retry(s
req->flags &= ~REQ_F_BL_EMPTY; sr->done_io = 0; - sr->retry = false; + sr->retry_flags = 0; sr->len = 0; /* get from the provided buffer */ req->buf_index = sr->buf_group; } @@ -401,7 +406,7 @@ int io_sendmsg_prep(struct io_kiocb *req struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
sr->done_io = 0; - sr->retry = false; + sr->retry_flags = 0; sr->len = READ_ONCE(sqe->len); sr->flags = READ_ONCE(sqe->ioprio); if (sr->flags & ~SENDMSG_FLAGS) @@ -759,7 +764,7 @@ int io_recvmsg_prep(struct io_kiocb *req struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
sr->done_io = 0; - sr->retry = false; + sr->retry_flags = 0;
if (unlikely(sqe->file_index || sqe->addr2)) return -EINVAL; @@ -831,7 +836,7 @@ static inline bool io_recv_finish(struct
cflags |= io_put_kbufs(req, this_ret, io_bundle_nbufs(kmsg, this_ret), issue_flags); - if (sr->retry) + if (sr->retry_flags & IO_SR_MSG_RETRY) cflags = req->cqe.flags | (cflags & CQE_F_MASK); /* bundle with no more immediate buffers, we're done */ if (req->flags & REQ_F_BL_EMPTY) @@ -840,12 +845,12 @@ static inline bool io_recv_finish(struct * If more is available AND it was a full transfer, retry and * append to this one */ - if (!sr->retry && kmsg->msg.msg_inq > 1 && this_ret > 0 && + if (!sr->retry_flags && kmsg->msg.msg_inq > 1 && this_ret > 0 && !iov_iter_count(&kmsg->msg.msg_iter)) { req->cqe.flags = cflags & ~CQE_F_MASK; sr->len = kmsg->msg.msg_inq; sr->done_io += this_ret; - sr->retry = true; + sr->retry_flags |= IO_SR_MSG_RETRY; return false; } } else { @@ -1089,6 +1094,8 @@ static int io_recv_buf_select(struct io_ kmsg->vec.iovec = arg.iovs; req->flags |= REQ_F_NEED_CLEANUP; } + if (arg.partial_map) + sr->retry_flags |= IO_SR_MSG_PARTIAL_MAP;
/* special case 1 vec, can be a fast path */ if (ret == 1) { @@ -1285,7 +1292,7 @@ int io_send_zc_prep(struct io_kiocb *req int ret;
zc->done_io = 0; - zc->retry = false; + zc->retry_flags = 0;
if (unlikely(READ_ONCE(sqe->__pad2[0]) || READ_ONCE(sqe->addr3))) return -EINVAL;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe axboe@kernel.dk
commit 6f11adcc6f36ffd8f33dbdf5f5ce073368975bc3 upstream.
io_uring marks a request as dealing with a regular file on S_ISREG. This drives things like retries on short reads or writes, which is generally not expected on a regular file (or bdev). Applications tend to not expect that, so io_uring tries hard to ensure it doesn't deliver short IO on regular files.
However, a recent commit added S_IFREG to anonymous inodes. When io_uring is used to read from various things that are backed by anon inodes, like eventfd, timerfd, etc, then it'll now all of a sudden wait for more data when rather than deliver what was read or written in a single operation. This breaks applications that issue reads on anon inodes, if they ask for more data than a single read delivers.
Add a check for !S_ANON_INODE as well before setting REQ_F_ISREG to prevent that.
Cc: Christian Brauner brauner@kernel.org Cc: stable@vger.kernel.org Link: https://github.com/ghostty-org/ghostty/discussions/7720 Fixes: cfd86ef7e8e7 ("anon_inode: use a proper mode internally") Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/io_uring.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1647,11 +1647,12 @@ static void io_iopoll_req_issued(struct
io_req_flags_t io_file_get_flags(struct file *file) { + struct inode *inode = file_inode(file); io_req_flags_t res = 0;
BUILD_BUG_ON(REQ_F_ISREG_BIT != REQ_F_SUPPORT_NOWAIT_BIT + 1);
- if (S_ISREG(file_inode(file)->i_mode)) + if (S_ISREG(inode->i_mode) && !(inode->i_flags & S_ANON_INODE)) res |= REQ_F_ISREG; if ((file->f_flags & O_NONBLOCK) || (file->f_mode & FMODE_NOWAIT)) res |= REQ_F_SUPPORT_NOWAIT;
6.15-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cyril Bur cyrilbur@tenstorrent.com
commit 265d6aba165c500389c80d394ac247460c443ef5 upstream.
During switch to csrs will OR the value of the register into the corresponding csr. In this case we're only interested in restoring the SUM bit not the entire register.
Signed-off-by: Cyril Bur cyrilbur@tenstorrent.com Link: https://lore.kernel.org/r/20250522160954.429333-1-cyrilbur@tenstorrent.com Co-developed-by: Alexandre Ghiti alexghiti@rivosinc.com Signed-off-by: Alexandre Ghiti alexghiti@rivosinc.com Fixes: 788aa64c01f1 ("riscv: save the SR_SUM status over switches") Link: https://lore.kernel.org/r/20250602121543.1544278-1-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@dabbelt.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/riscv/include/asm/processor.h | 2 +- arch/riscv/kernel/asm-offsets.c | 6 +++--- arch/riscv/kernel/entry.S | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-)
--- a/arch/riscv/include/asm/processor.h +++ b/arch/riscv/include/asm/processor.h @@ -103,7 +103,7 @@ struct thread_struct { struct __riscv_d_ext_state fstate; unsigned long bad_cause; unsigned long envcfg; - unsigned long status; + unsigned long sum; u32 riscv_v_flags; u32 vstate_ctrl; struct __riscv_v_ext_state vstate; --- a/arch/riscv/kernel/asm-offsets.c +++ b/arch/riscv/kernel/asm-offsets.c @@ -34,7 +34,7 @@ void asm_offsets(void) OFFSET(TASK_THREAD_S9, task_struct, thread.s[9]); OFFSET(TASK_THREAD_S10, task_struct, thread.s[10]); OFFSET(TASK_THREAD_S11, task_struct, thread.s[11]); - OFFSET(TASK_THREAD_STATUS, task_struct, thread.status); + OFFSET(TASK_THREAD_SUM, task_struct, thread.sum);
OFFSET(TASK_TI_CPU, task_struct, thread_info.cpu); OFFSET(TASK_TI_PREEMPT_COUNT, task_struct, thread_info.preempt_count); @@ -347,8 +347,8 @@ void asm_offsets(void) offsetof(struct task_struct, thread.s[11]) - offsetof(struct task_struct, thread.ra) ); - DEFINE(TASK_THREAD_STATUS_RA, - offsetof(struct task_struct, thread.status) + DEFINE(TASK_THREAD_SUM_RA, + offsetof(struct task_struct, thread.sum) - offsetof(struct task_struct, thread.ra) );
--- a/arch/riscv/kernel/entry.S +++ b/arch/riscv/kernel/entry.S @@ -399,14 +399,15 @@ SYM_FUNC_START(__switch_to) REG_S s11, TASK_THREAD_S11_RA(a3)
/* save the user space access flag */ - li s0, SR_SUM - csrr s1, CSR_STATUS - REG_S s1, TASK_THREAD_STATUS_RA(a3) + csrr s0, CSR_STATUS + REG_S s0, TASK_THREAD_SUM_RA(a3)
/* Save the kernel shadow call stack pointer */ scs_save_current /* Restore context from next->thread */ - REG_L s0, TASK_THREAD_STATUS_RA(a4) + REG_L s0, TASK_THREAD_SUM_RA(a4) + li s1, SR_SUM + and s0, s0, s1 csrs CSR_STATUS, s0 REG_L ra, TASK_THREAD_RA_RA(a4) REG_L sp, TASK_THREAD_SP_RA(a4)
Hi
no regressions here on x86_64 (RKL, Intel 11th Gen. CPU)
Thanks
Tested-by: Ronald Warsow rwarsow@gmx.de
On 7/3/25 07:38, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Tested-by: Florian Fainelli florian.fainelli@broadcom.com
On 25/07/03 04:38PM, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
Tested-by: Christian Heusel christian@heusel.eu
Tested on a ThinkPad E14 Gen 3 with a AMD Ryzen 5 5500U CPU and on a Framework Desktop.
The kernel, bpf tool, and perf tool builds fine for v6.15.5-rc1 on x86 and arm64 Azure VM.
Kernel binary size for x86 build: text data bss dec hex filename 31999332 14279706 6250496 52529534 321897e vmlinux
Kernel binary size for arm64 build: text data bss dec hex filename 37335764 15435073 1038480 53809317 33510a5 vmlinux
Tested-by: Hardik Garg hargar@linux.microsoft.com
Thanks, Hardik
On 7/3/25 08:38, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
Compiled and booted on my test system. No dmesg regressions.
Tested-by: Shuah Khan skhan@linuxfoundation.org
thanks, -- Shuah
On 7/3/25 07:38, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Tested-by: Ron Economos re@w6rz.net
[2025-07-03 16:38] Greg Kroah-Hartman:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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.
Compiles fine for x86_64 with GCC 15.1.1, and runs fine on various physical Intel machines (Ivy Bridge, Haswell, Kaby Lake, Coffee Lake) and in a Skylake VM.
Tested-by: Pascal Ernster git@hardfalcon.net
Regards Pascal
On Thu Jul 3, 2025 at 4:38 PM CEST, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
Tested-By: Achill Gilgenast fossdd@pwned.life
Build-tested on all Alpine architectures and boot-tested on x86_64. Thanks!
Hi Greg
On Thu, Jul 3, 2025 at 11:57 PM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
6.15.5-rc1 tested.
Build successfully completed. Boot successfully completed. No dmesg regressions. Video output normal. Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64) arch linux)
[ 0.000000] Linux version 6.15.5-rc1rv-gd5e6f0c9ca48 (takeshi@ThinkPadX1Gen10J0764) (gcc (GCC) 15.1.1 20250425, GNU ld (GNU Binutils) 2.44.0) #1 SMP PREEMPT_DYNAMIC Fri Jul 4 18:24:44 JST 2025
Thanks
Tested-by: Takeshi Ogasawara takeshi.ogasawara@futuring-girl.com
Tested-by: Luna Jernberg droidbittin@gmail.com
AMD Ryzen 5 5600 6-Core Processor: https://www.inet.se/produkt/5304697/amd-ryzen-5-5600-3-5-ghz-35mb on a https://www.gigabyte.com/Motherboard/B550-AORUS-ELITE-V2-rev-12 https://www.inet.se/produkt/1903406/gigabyte-b550-aorus-elite-v2 motherboard :)
running Arch Linux with the testing repos enabled: https://archlinux.org/ https://archboot.com/ https://wiki.archlinux.org/title/Arch_Testing_Team
Den tors 3 juli 2025 kl 18:35 skrev Greg Kroah-Hartman gregkh@linuxfoundation.org:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 6.15.5-rc1
Cyril Bur cyrilbur@tenstorrent.com riscv: uaccess: Only restore the CSR_STATUS SUM bit
Jens Axboe axboe@kernel.dk io_uring: gate REQ_F_ISREG on !S_ANON_INODE as well
Jens Axboe axboe@kernel.dk io_uring/kbuf: flag partial buffer mappings
Heiko Carstens hca@linux.ibm.com s390/ptrace: Fix pointer dereferencing in regs_get_kernel_stack_nth()
Chang S. Bae chang.seok.bae@intel.com x86/pkeys: Simplify PKRU update in signal frame
Chang S. Bae chang.seok.bae@intel.com x86/fpu: Refactor xfeature bitmask update code for sigframe XSAVE
Danilo Krummrich dakr@kernel.org rust: devres: do not dereference to the internal Revocable
Danilo Krummrich dakr@kernel.org rust: devres: fix race in Devres::drop()
Danilo Krummrich dakr@kernel.org rust: revocable: indicate whether `data` has been revoked already
Danilo Krummrich dakr@kernel.org rust: completion: implement initial abstraction
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Export full brightness range to userspace
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Optimize custom brightness curve
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Only read ACPI backlight caps once
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Fix default DC and AC levels
Michael Strauss michael.strauss@amd.com drm/amd/display: Get LTTPR IEEE OUI/Device ID From Closest LTTPR To Host
Michael Strauss michael.strauss@amd.com drm/amd/display: Add early 8b/10b channel equalization test pattern sequence
Sasha Levin sashal@kernel.org sched_ext: Make scx_group_set_weight() always update tg->scx.weight
Sasha Levin sashal@kernel.org arm64: dts: qcom: x1e78100-t14s: fix missing HID supplies
Alex Deucher alexander.deucher@amd.com drm/amdgpu/mes: add missing locking in helper functions
Eric Biggers ebiggers@google.com crypto: powerpc/poly1305 - add depends on BROKEN for now
Stephan Gerhold stephan.gerhold@linaro.org arm64: dts: qcom: x1-crd: Fix vreg_l2j_1p2 voltage
Sasha Levin sashal@kernel.org arm64: dts: qcom: x1e78100-t14s: mark l12b and l15b always-on
Johan Hovold johan+linaro@kernel.org arm64: dts: qcom: x1e80100-crd: mark l12b and l15b always-on
Konrad Dybcio konrad.dybcio@oss.qualcomm.com arm64: dts: qcom: Commonize X1 CRD DTSI
Alex Hung alex.hung@amd.com drm/amd/display: Fix mpv playback corruption on weston
Peichen Huang PeiChen.Huang@amd.com drm/amd/display: Add dc cap for dp tunneling
Nicholas Kazlauskas nicholas.kazlauskas@amd.com drm/amd/display: Add more checks for DSC / HUBP ONO guarantees
Frank Min Frank.Min@amd.com drm/amdgpu: add kicker fws loading for gfx11/smu13/psp13
Alex Deucher alexander.deucher@amd.com drm/amdgpu: switch job hw_fence to amdgpu_fence
Jesse Zhang jesse.zhang@amd.com drm/amdgpu: Fix SDMA UTC_L1 handling during start/stop sequences
Ville Syrjälä ville.syrjala@linux.intel.com drm/i915/dsi: Fix off by one in BXT_MIPI_TRANS_VTOTAL
Daniele Ceraolo Spurio daniele.ceraolospurio@intel.com drm/xe: Fix early wedge on GuC load failure
Lucas De Marchi lucas.demarchi@intel.com drm/xe: Fix taking invalid lock on wedge
Lucas De Marchi lucas.demarchi@intel.com drm/xe: Fix memset on iomem
Alex Hung alex.hung@amd.com drm/amd/display: Check dce_hwseq before dereferencing it
Frank Min Frank.Min@amd.com drm/amdgpu: Add kicker device detection
Sonny Jiang sonny.jiang@amd.com drm/amdgpu: VCN v5_0_1 to prevent FW checking RB during DPG pause
Yihan Zhu Yihan.Zhu@amd.com drm/amd/display: Fix RMCM programming seq errors
Matthew Auld matthew.auld@intel.com drm/xe/guc_submit: add back fix
Matthew Auld matthew.auld@intel.com drm/xe/sched: stop re-submitting signalled jobs
Matthew Auld matthew.auld@intel.com drm/xe/vm: move rebind_work init earlier
Zhongwei Zhang Zhongwei.Zhang@amd.com drm/amd/display: Correct non-OLED pre_T11_delay.
Alex Deucher alexander.deucher@amd.com drm/amdgpu: disable workload profile switching when OD is enabled
John Olender john.olender@gmail.com drm/amdgpu: amdgpu_vram_mgr_new(): Clamp lpfn to total vram
Wentao Liang vulab@iscas.ac.cn drm/amd/display: Add null pointer check for get_first_active_display()
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Wait for Clk and Data Lanes to be ready
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Check return value when getting default PHY config
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Fix connecting to next bridge
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Fix phy de-init and flag it so
Aradhya Bhatia a-bhatia1@ti.com drm/bridge: cdns-dsi: Fix the clock variable for mode_valid()
Imre Deak imre.deak@intel.com drm/i915/dp_mst: Work around Thunderbolt sink disconnect after SINK_COUNT_ESI read
Imre Deak imre.deak@intel.com drm/i915/ptl: Use everywhere the correct DDI port clock select mask
Jay Cornwall jay.cornwall@amd.com drm/amdkfd: Fix race in GWS queue scheduling
Stephan Gerhold stephan.gerhold@linaro.org drm/msm/gpu: Fix crash when throttling GPU immediately during boot
Thomas Zimmermann tzimmermann@suse.de drm/udl: Unregister device before cleaning up on disconnect
Qiu-ji Chen chenqiuji666@gmail.com drm/tegra: Fix a possible null pointer dereference
Thierry Reding treding@nvidia.com drm/tegra: Assign plane type before registration
Thomas Zimmermann tzimmermann@suse.de drm/simpledrm: Do not upcast in release helpers
Luca Ceresoli luca.ceresoli@bootlin.com drm/panel: simple: Tianma TM070JDHG34-00: add delays
Maíra Canal mcanal@igalia.com drm/etnaviv: Protect the scheduler's pending list with its lock
Thomas Zimmermann tzimmermann@suse.de drm/cirrus-qemu: Fix pitch programming
Thomas Zimmermann tzimmermann@suse.de drm/ast: Fix comment on modeset lock
Karan Tilak Kumar kartilak@cisco.com scsi: fnic: Turn off FDMI ACTIVE flags on link down
Karan Tilak Kumar kartilak@cisco.com scsi: fnic: Fix crash in fnic_wq_cmpl_handler when FDMI times out
anvithdosapati anvithdosapati@google.com scsi: ufs: core: Fix clk scaling to be conditional in reset and restore
Chen Yu yu.c.chen@intel.com scsi: megaraid_sas: Fix invalid node index
Qasim Ijaz qasdev00@gmail.com HID: wacom: fix kobject reference count leak
Qasim Ijaz qasdev00@gmail.com HID: wacom: fix memory leak on sysfs attribute creation failure
Qasim Ijaz qasdev00@gmail.com HID: wacom: fix memory leak on kobject creation failure
Iusico Maxim iusico.maxim@libero.it HID: lenovo: Restrict F7/9/11 mode to compact keyboards only
Qasim Ijaz qasdev00@gmail.com HID: appletb-kbd: fix "appletb_backlight" backlight device reference counting
Chao Yu chao@kernel.org f2fs: fix to zero post-eof page
David Hildenbrand david@redhat.com mm/gup: revert "mm: gup: fix infinite loop within __get_longterm_locked"
Kairui Song kasong@tencent.com mm/shmem, swap: fix softlockup with mTHP swapin
Kairui Song kasong@tencent.com mm: userfaultfd: fix race of userfaultfd_move and swap cache
Liam R. Howlett Liam.Howlett@oracle.com maple_tree: fix MA_STATE_PREALLOC flag in mas_preallocate()
Jiawen Wu jiawenwu@trustnetic.com net: libwx: fix the creation of page_pool
Khairul Anuar Romli khairul.anuar.romli@altera.com spi: spi-cadence-quadspi: Fix pm runtime unbalance
Stephen Smalley stephen.smalley.work@gmail.com selinux: change security_compute_sid to return the ssid or tsid on match
Kuan-Wei Chiu visitorckw@gmail.com Revert "bcache: remove heap-related macros and switch to generic min_heap"
Kuan-Wei Chiu visitorckw@gmail.com Revert "bcache: update min_heap_callbacks to use default builtin swap"
Filipe Manana fdmanana@suse.com btrfs: fix invalid inode pointer dereferences during log replay
Mark Harmstone maharmstone@fb.com btrfs: update superblock's device bytes_used when dropping chunk
Filipe Manana fdmanana@suse.com btrfs: fix a race between renames and directory logging
Kuan-Wei Chiu visitorckw@gmail.com bcache: remove unnecessary select MIN_HEAP
Heinz Mauelshagen heinzm@redhat.com dm-raid: fix variable in journal device check
Frédéric Danis frederic.danis@collabora.com Bluetooth: L2CAP: Fix L2CAP MTU negotiation
Fabio Estevam festevam@gmail.com serial: imx: Restore original RXTL for console to fix data loss
Aidan Stewart astewart@tektelic.com serial: core: restore of_node information in sysfs
Yao Zi ziyao@disroot.org dt-bindings: serial: 8250: Make clocks and clock-frequency exclusive
Nathan Chancellor nathan@kernel.org staging: rtl8723bs: Avoid memset() in aes_cipher() and aes_decipher()
Xin Li (Intel) xin@zytor.com x86/traps: Initialize DR6 by writing its architectural reset value
Avadhut Naik avadhut.naik@amd.com EDAC/amd64: Fix size calculation for Non-Power-of-Two DIMMs
Paulo Alcantara pc@manguebit.org smb: client: fix potential deadlock when reconnecting channels
Michal Wajdeczko michal.wajdeczko@intel.com drm/xe: Process deferred GGTT node removals on device unwind
Michal Wajdeczko michal.wajdeczko@intel.com drm/xe/guc: Explicitly exit CT safe mode on unwind
Jayesh Choudhary j-choudhary@ti.com drm/bridge: ti-sn65dsi86: Add HPD for DisplayPort connector type
Wolfram Sang wsa+renesas@sang-engineering.com drm/bridge: ti-sn65dsi86: make use of debugfs_init callback
Arnd Bergmann arnd@arndb.de drm/i915: fix build error some more
Mario Limonciello mario.limonciello@amd.com drm/amd: Adjust output for discovery error handling
Louis Chauvet louis.chauvet@bootlin.com drm: writeback: Fix drm_writeback_connector_cleanup signature
Charles Mirabile cmirabil@redhat.com riscv: fix runtime constant support for nommu kernels
Christoph Hellwig hch@lst.de nvme: fix atomic write size validation
Christoph Hellwig hch@lst.de nvme: refactor the atomic write unit detection
Jakub Kicinski kuba@kernel.org net: selftests: fix TCP packet checksum
Salvatore Bonaccorso carnil@debian.org ALSA: hda/realtek: Fix built-in mic on ASUS VivoBook X507UAR
Kuniyuki Iwashima kuniyu@google.com atm: Release atm_dev_mutex after removing procfs in atm_dev_deregister().
Jakub Kicinski kuba@kernel.org netlink: specs: tc: replace underscores with dashes in names
Simon Horman horms@kernel.org net: enetc: Correct endianness handling in _enetc_rd_reg64
Adin Scannell amscanne@meta.com libbpf: Fix possible use-after-free for externs
Jens Axboe axboe@kernel.dk io_uring/net: mark iov as dynamically allocated even for single segments
Tiwei Bie tiwei.btw@antgroup.com um: ubd: Add missing error check in start_io_thread()
Yan Zhai yan@cloudflare.com bnxt: properly flush XDP redirect lists
Stefano Garzarella sgarzare@redhat.com vsock/uapi: fix linux/vm_sockets.h userspace compilation errors
Al Viro viro@zeniv.linux.org.uk userns and mnt_idmap leak in open_tree_attr(2)
Johannes Berg johannes.berg@intel.com wifi: mac80211: finish link init before RCU publish
Muna Sinada muna.sinada@oss.qualcomm.com wifi: mac80211: Create separate links for VLAN interfaces
Muna Sinada muna.sinada@oss.qualcomm.com wifi: mac80211: Add link iteration macro for link data
Kuniyuki Iwashima kuniyu@google.com af_unix: Don't set -ECONNRESET for consumed OOB skb.
Lachlan Hodges lachlan.hodges@morsemicro.com wifi: mac80211: fix beacon interval calculation overflow
Ido Schimmel idosch@nvidia.com bridge: mcast: Fix use-after-free during router port configuration
Thomas Fourier fourier.thomas@gmail.com ethernet: ionic: Fix DMA mapping tests
Breno Leitao leitao@debian.org net: netpoll: Initialize UDP checksum field before checksumming
Yuan Chen chenyuan@kylinos.cn libbpf: Fix null pointer dereference in btf_dump__free on allocation failure
Al Viro viro@zeniv.linux.org.uk attach_recursive_mnt(): do not lock the covering tree when sliding something under it
Youngjun Lee yjjuny.lee@samsung.com ALSA: usb-audio: Fix out-of-bounds read in snd_usb_get_audioformat_uac3()
Kuniyuki Iwashima kuniyu@google.com Bluetooth: hci_core: Fix use-after-free in vhci_flush()
Vijendar Mukunda Vijendar.Mukunda@amd.com ASoC: amd: ps: fix for soundwire failures during hibernation exit sequence
Eric Dumazet edumazet@google.com atm: clip: prevent NULL deref in clip_push()
Thomas Fourier fourier.thomas@gmail.com scsi: fnic: Fix missing DMA mapping error in fnic_send_frame()
Dan Williams dan.j.williams@intel.com cxl/ras: Fix CPER handler device confusion
Thomas Zeitlhofer thomas.zeitlhofer+lkml@ze-it.at HID: wacom: fix crash in wacom_aes_battery_handler()
Even Xu even.xu@intel.com HID: Intel-thc-hid: Intel-quicki2c: Enhance QuickI2C reset flow
Matthew Auld matthew.auld@intel.com drm/xe: move DPT l2 flush to a more sensible place
Maarten Lankhorst maarten.lankhorst@linux.intel.com drm/xe: Move DSB l2 flush to a more sensible place
Ankit Nautiyal ankit.k.nautiyal@intel.com drm/i915/snps_hdmi_pll: Fix 64-bit divisor truncation by using div64_u64
Haoxiang Li haoxiang_li2024@163.com drm/xe/display: Add check for alloc_ordered_workqueue()
Alex Deucher alexander.deucher@amd.com drm/amdgpu/mes: add compatibility checks for set_hw_resource_1
Takashi Iwai tiwai@suse.de drm/amd/display: Add sanity checks for drm_edid_raw()
Imre Deak imre.deak@intel.com drm/dp: Change AUX DPCD probe address from DPCD_REV to LANE0_1_STATUS
Nam Cao namcao@linutronix.de Revert "riscv: misaligned: fix sleeping function called during misaligned access handling"
Nam Cao namcao@linutronix.de Revert "riscv: Define TASK_SIZE_MAX for __access_ok()"
Yu Kuai yukuai3@huawei.com lib/group_cpus: fix NULL pointer dereference from group_cpus_evenly()
David Hildenbrand david@redhat.com fs/proc/task_mmu: fix PAGE_IS_PFNZERO detection for the huge zero folio
Pavel Begunkov asml.silence@gmail.com io_uring: don't assume uaddr alignment in io_vec_fill_bvec
Pavel Begunkov asml.silence@gmail.com io_uring/rsrc: don't rely on user vaddr alignment
Pavel Begunkov asml.silence@gmail.com io_uring/rsrc: fix folio unpinning
Fedor Pchelkin pchelkin@ispras.ru s390/pkey: Prevent overflow in size calculation for memdup_user()
Klara Modin klarasmodin@gmail.com riscv: export boot_cpu_hartid
Oliver Schramm oliver.schramm97@gmail.com ASoC: amd: yc: Add DMI quirk for Lenovo IdeaPad Slim 5 15
Han Gao rabenda.cn@gmail.com riscv: vector: Fix context save/restore with xtheadvector
Paulo Alcantara pc@manguebit.org smb: client: fix regression with native SMB symlinks
SeongJae Park sj@kernel.org mm/damon/sysfs-schemes: free old damon_sysfs_scheme_filter->memcg_path on write
Stefan Metzmacher metze@samba.org smb: client: remove \t from TP_printk statements
Niklas Cassel cassel@kernel.org ata: ahci: Use correct DMI identifier for ASUSPRO-D840SA LPM quirk
Florian Fainelli florian.fainelli@broadcom.com scripts/gdb: fix dentry_name() lookup
Haiyue Wang haiyuewa@163.com fuse: fix runtime warning on truncate_folio_batch_exceptionals()
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Check interrupt route from physical CPU
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Fix interrupt route update with EIOINTC
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Add address alignment check for IOCSR emulation
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Disable updating of "num_cpu" and "feature"
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Check validity of "num_cpu" from user space
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Avoid overflow with array index
Wolfram Sang wsa+renesas@sang-engineering.com i2c: robotfuzz-osif: disable zero-length read messages
Wolfram Sang wsa+renesas@sang-engineering.com i2c: tiny-usb: disable zero-length read messages
Lukasz Kucharczyk lukasz.kucharczyk@leica-geosystems.com i2c: imx: fix emulated smbus block read
Christophe JAILLET christophe.jaillet@wanadoo.fr i2c: omap: Fix an error handling path in omap_i2c_probe()
Kuniyuki Iwashima kuniyu@google.com af_unix: Don't leave consecutive consumed OOB skbs.
Haoxiang Li haoxiang_li2024@163.com drm/i915/display: Add check for alloc_ordered_workqueue() and alloc_workqueue()
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: fix area release on registration failure
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: split out memory holders from area
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: improve area validation
Pavel Begunkov asml.silence@gmail.com io_uring/zcrx: move io_zcrx_iov_page
Chao Yu chao@kernel.org f2fs: don't over-report free space or inodes in statvfs
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org ASoC: codecs: wcd9335: Fix missing free of regulator supplies
Peng Fan peng.fan@nxp.com ASoC: codec: wcd9335: Convert to GPIO descriptors
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Rollback non processed entities on error
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Increase/decrease the PM counter per IOCTL
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Create uvc_pm_(get|put) functions
Ricardo Ribalda ribalda@chromium.org media: uvcvideo: Keep streaming state in the file handle
Filipe Manana fdmanana@suse.com btrfs: fix qgroup reservation leak on failure to allocate ordered extent
David Sterba dsterba@suse.com btrfs: use unsigned types for constants defined as bit shifts
Joonas Lahtinen joonas.lahtinen@linux.intel.com Revert "drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1"
Ville Syrjälä ville.syrjala@linux.intel.com drm/i915/gem: Allow EXEC_CAPTURE on recoverable contexts on DG1
Qu Wenruo wqu@suse.com btrfs: handle csum tree error with rescue=ibadroots correctly
Filipe Manana fdmanana@suse.com btrfs: fix race between async reclaim worker and close_ctree()
Kees Cook kees@kernel.org ovl: Check for NULL d_inode() in ovl_dentry_upper()
Ben Dooks ben.dooks@codethink.co.uk riscv: save the SR_SUM status over switches
Ziqi Chen quic_ziqichen@quicinc.com scsi: ufs: core: Don't perform UFS clkscaling during host async scan
Dmitry Kandybka d.kandybka@gmail.com ceph: fix possible integer overflow in ceph_zero_objects()
Shuming Fan shumingf@realtek.com ASoC: rt1320: fix speaker noise when volume bar is 100%
Mario Limonciello mario.limonciello@amd.com ALSA: usb-audio: Add a quirk for Lenovo Thinkpad Thunderbolt 3 dock
Vijendar Mukunda Vijendar.Mukunda@amd.com ALSA: hda: Add new pci id for AMD GPU display HD audio controller
Cezary Rojewski cezary.rojewski@intel.com ALSA: hda: Ignore unsol events for cards being shut down
Clément Léger cleger@rivosinc.com riscv: misaligned: declare misaligned_access_speed under CONFIG_RISCV_MISALIGNED
Heiko Carstens hca@linux.ibm.com s390/mm: Fix in_atomic() handling in do_secure_storage_access()
Andy Chiu andybnac@gmail.com riscv: add a data fence for CMODX in the kernel mode
Michael Grzeschik m.grzeschik@pengutronix.de usb: typec: mux: do not return on EOPNOTSUPP in {mux, switch}_set
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org usb: typec: tipd: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org usb: typec: tcpci: Fix wakeup source leaks on device unbind
Jos Wang joswang@lenovo.com usb: typec: displayport: Receive DP Status Update NAK request exit dp altmode
Peter Korsgaard peter@korsgaard.com usb: gadget: f_hid: wake up readers on disable/unbind
Robert Hodaszi robert.hodaszi@digi.com usb: cdc-wdm: avoid setting WDM_READ for ZLP-s
Andy Shevchenko andriy.shevchenko@linux.intel.com usb: Add checks for snprintf() calls in usb_alloc_dev()
Chance Yang chance.yang@kneron.us usb: common: usb-conn-gpio: use a unique name for usb connector device
Jakub Lewalski jakub.lewalski@nokia.com tty: serial: uartlite: register uart driver in init
Chen Yufeng chenyufeng@iie.ac.cn usb: potential integer overflow in usbg_make_tpg()
Chenyuan Yang chenyuan0y@gmail.com misc: tps6594-pfsm: Add NULL pointer check in tps6594_pfsm_probe()
Zhang Lixu lixu.zhang@intel.com iio: hid-sensor-prox: Add support for 16-bit report size
David Lechner dlechner@baylibre.com iio: adc: ad7606_spi: check error in ad7606B_sw_mode_config()
David Heidelberg david@ixit.cz iio: light: al3000a: Fix an error handling path in al3000a_probe()
Angelo Dureghello adureghello@baylibre.com iio: dac: adi-axi-dac: add cntrl chan check
Purva Yeshi purvayeshi550@gmail.com iio: adc: ad_sigma_delta: Fix use of uninitialized status_pos
Michael Grzeschik m.grzeschik@pengutronix.de usb: dwc2: also exit clock_gating when stopping udc while suspended
James Clark james.clark@linaro.org coresight: Only check bottom two claim bits
Rengarajan S rengarajan.s@microchip.com 8250: microchip: pci1xxxx: Add PCIe Hot reset disable support for Rev C0 and later devices
Benjamin Berg benjamin.berg@intel.com um: use proper care when taking mmap lock during segfault
Sami Tolvanen samitolvanen@google.com um: Add cmpxchg8b_emu and checksum functions to asm-prototypes.h
Daniele Palmas dnlplm@gmail.com bus: mhi: host: pci_generic: Add Telit FN920C04 modem support
Jonathan Cameron Jonathan.Cameron@huawei.com iio: pressure: zpa2326: Use aligned_s64 for the timestamp
Lin.Cao lincao12@amd.com drm/scheduler: signal scheduled fence when kill job
Philip Yang Philip.Yang@amd.com drm/amdgpu: seq64 memory unmap uses uninterruptible lock
Linggang Zeng linggang.zeng@easystack.cn bcache: fix NULL pointer in cache_set_flush()
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn2.5: read back register after written
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn3: read back register after written
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn4: read back register after written
David (Ming Qiang) Wu David.Wu3@amd.com drm/amdgpu/vcn5.0.1: read back register after written
Yifan Zhang yifan1.zhang@amd.com amd/amdkfd: fix a kfd_process ref leak
Yu Kuai yukuai3@huawei.com md/md-bitmap: fix dm-raid max_write_behind setting
Hannes Reinecke hare@kernel.org nvme-tcp: sanitize request list handling
Hannes Reinecke hare@kernel.org nvme-tcp: fix I/O stalls on congested sockets
Ilan Peer ilan.peer@intel.com wifi: iwlwifi: mld: Move regulatory domain initialization
Richard Zhu hongxing.zhu@nxp.com PCI: imx6: Add workaround for errata ERR051624
Hector Martin marcan@marcan.st PCI: apple: Fix missing OF node reference in apple_pcie_setup_port
Wenbin Yao quic_wenbyao@quicinc.com PCI: dwc: Make link training more robust by setting PORT_LOGIC_LINK_WIDTH to one lane
Thomas Gessler thomas.gessler@brueckmann-gmbh.de dmaengine: xilinx_dma: Set dma_device directions
Yi Sun yi.sun@intel.com dmaengine: idxd: Check availability of workqueue allocated by idxd wq driver before using
Lukas Wunner lukas@wunner.de Revert "iommu/amd: Prevent binding other PCI drivers to IOMMU PCI devices"
Rudraksha Gupta guptarud@gmail.com rust: arm: fix unknown (to Clang) argument '-mno-fdpic'
FUJITA Tomonori fujita.tomonori@gmail.com rust: module: place cleanup_module() in .exit.text section
Namjae Jeon linkinjeon@kernel.org ksmbd: provide zero as a unique ID to the Mac client
Namjae Jeon linkinjeon@kernel.org ksmbd: allow a filename to contain special characters on SMB3.1.1 posix extension
Alexis Czezar Torreno alexisczezar.torreno@analog.com hwmon: (pmbus/max34440) Fix support for max34451
Scott Mayhew smayhew@redhat.com NFSv4: xattr handlers should check for absent nfs filehandles
Gregory Price gourry@gourry.net cxl: core/region - ignore interleave granularity when ways=1
Robert Richter rrichter@amd.com cxl/region: Add a dev_err() on missing target list entries
Guang Yuan Wu gwu@ddn.com fuse: fix race between concurrent setattrs from multiple nodes
Sven Schwermer sven.schwermer@disruptive-technologies.com leds: multicolor: Fix intensity setting while SW blinking
Matthew Sakai msakai@redhat.com dm vdo indexer: don't read request structure after enqueuing
Yikai Tsai yikai.tsai.wiwynn@gmail.com hwmon: (isl28022) Fix current reading calculation
Nikhil Jha njha@janestreet.com sunrpc: don't immediately retransmit on seqno miss
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: sprd-sc27xx: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: 88pm886: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: max77705: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: max14577: Fix wakeup source leaks on device unbind
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org mfd: max77541: Fix wakeup source leaks on device unbind
Peng Fan peng.fan@nxp.com mailbox: Not protect module_put with spin_lock_irqsave
Sagi Grimberg sagi@grimberg.me NFSv4.2: fix setattr caching of TIME_[MODIFY|ACCESS]_SET when timestamps are delegated
Olga Kornievskaia okorniev@redhat.com NFSv4.2: fix listxattr to return selinux security label
Han Young hanyang.tony@bytedance.com NFSv4: Always set NLINK even if the server doesn't support it
Pali Rohár pali@kernel.org cifs: Fix encoding of SMB1 Session Setup NTLMSSP Request in non-UNICODE mode
Pali Rohár pali@kernel.org cifs: Fix cifs_query_path_info() for Windows NT servers
Pali Rohár pali@kernel.org cifs: Correctly set SMB1 SessionKey field in Session Setup Request
Diffstat:
Documentation/devicetree/bindings/serial/8250.yaml | 2 +- Documentation/netlink/specs/tc.yaml | 4 +- Makefile | 4 +- arch/arm64/boot/dts/qcom/x1-crd.dtsi | 1277 ++++++++++++++++++++ .../dts/qcom/x1e78100-lenovo-thinkpad-t14s.dts | 45 + arch/arm64/boot/dts/qcom/x1e80100-crd.dts | 1270 +------------------ arch/arm64/boot/dts/qcom/x1e80100.dtsi | 2 +- arch/loongarch/kvm/intc/eiointc.c | 89 +- arch/powerpc/crypto/Kconfig | 1 + arch/riscv/include/asm/cpufeature.h | 5 +- arch/riscv/include/asm/pgtable.h | 1 - arch/riscv/include/asm/processor.h | 1 + arch/riscv/include/asm/runtime-const.h | 2 +- arch/riscv/include/asm/vector.h | 12 +- arch/riscv/kernel/asm-offsets.c | 5 + arch/riscv/kernel/entry.S | 9 + arch/riscv/kernel/setup.c | 1 + arch/riscv/kernel/traps_misaligned.c | 6 +- arch/riscv/mm/cacheflush.c | 15 +- arch/s390/kernel/ptrace.c | 2 +- arch/s390/mm/fault.c | 2 + arch/um/drivers/ubd_user.c | 2 +- arch/um/include/asm/asm-prototypes.h | 5 + arch/um/kernel/trap.c | 129 +- arch/x86/include/uapi/asm/debugreg.h | 21 +- arch/x86/kernel/cpu/common.c | 24 +- arch/x86/kernel/fpu/signal.c | 11 +- arch/x86/kernel/fpu/xstate.h | 22 +- arch/x86/kernel/traps.c | 34 +- arch/x86/um/asm/checksum.h | 3 + drivers/ata/ahci.c | 2 +- drivers/bus/mhi/host/pci_generic.c | 39 + drivers/cxl/core/ras.c | 47 +- drivers/cxl/core/region.c | 9 +- drivers/dma/idxd/cdev.c | 4 +- drivers/dma/xilinx/xilinx_dma.c | 2 + drivers/edac/amd64_edac.c | 57 +- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_discovery.c | 28 +- drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 30 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 8 + drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 12 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_mes.c | 16 + drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c | 16 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h | 16 + drivers/gpu/drm/amd/amdgpu/amdgpu_seq64.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.c | 17 + drivers/gpu/drm/amd/amdgpu/amdgpu_ucode.h | 6 + drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c | 2 +- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 5 + drivers/gpu/drm/amd/amdgpu/imu_v11_0.c | 9 +- drivers/gpu/drm/amd/amdgpu/mes_v11_0.c | 10 +- drivers/gpu/drm/amd/amdgpu/mes_v12_0.c | 3 +- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 2 + drivers/gpu/drm/amd/amdgpu/sdma_v4_4_2.c | 6 +- drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c | 19 + drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c | 20 + drivers/gpu/drm/amd/amdgpu/vcn_v4_0.c | 20 + drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c | 21 +- drivers/gpu/drm/amd/amdkfd/kfd_events.c | 1 + drivers/gpu/drm/amd/amdkfd/kfd_packet_manager_v9.c | 2 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 97 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 4 + drivers/gpu/drm/amd/display/dc/core/dc.c | 33 + drivers/gpu/drm/amd/display/dc/dc.h | 8 +- drivers/gpu/drm/amd/display/dc/dc_dp_types.h | 4 +- .../dc/dml2/dml21/dml21_translation_helper.c | 1 + .../dml21/src/dml2_core/dml2_core_dcn4_calcs.c | 5 +- .../amd/display/dc/dml2/dml2_translation_helper.c | 1 + .../drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 9 +- .../drm/amd/display/dc/hwss/dcn35/dcn35_hwseq.c | 28 + .../display/dc/link/protocols/link_dp_capability.c | 46 +- .../display/dc/link/protocols/link_dp_capability.h | 3 + .../display/dc/link/protocols/link_dp_training.c | 1 - .../dc/link/protocols/link_dp_training_8b_10b.c | 52 +- .../amd/display/dc/resource/dcn31/dcn31_resource.c | 3 + .../display/dc/resource/dcn314/dcn314_resource.c | 3 + .../amd/display/dc/resource/dcn35/dcn35_resource.c | 3 + .../display/dc/resource/dcn351/dcn351_resource.c | 3 + .../amd/display/dc/resource/dcn36/dcn36_resource.c | 3 + .../drm/amd/display/include/link_service_types.h | 2 + .../gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 + drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 22 + drivers/gpu/drm/amd/pm/inc/amdgpu_dpm.h | 1 + drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0.c | 12 +- drivers/gpu/drm/ast/ast_mode.c | 6 +- drivers/gpu/drm/bridge/cadence/cdns-dsi-core.c | 32 +- drivers/gpu/drm/bridge/ti-sn65dsi86.c | 109 +- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- drivers/gpu/drm/drm_writeback.c | 7 +- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 5 +- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 27 +- drivers/gpu/drm/i915/display/intel_cx0_phy_regs.h | 15 +- .../gpu/drm/i915/display/intel_display_driver.c | 30 +- drivers/gpu/drm/i915/display/intel_dp.c | 17 + drivers/gpu/drm/i915/display/intel_snps_hdmi_pll.c | 4 +- drivers/gpu/drm/i915/display/vlv_dsi.c | 4 +- drivers/gpu/drm/i915/i915_pmu.c | 2 +- drivers/gpu/drm/msm/msm_gpu_devfreq.c | 1 + drivers/gpu/drm/panel/panel-simple.c | 6 + drivers/gpu/drm/scheduler/sched_entity.c | 1 + drivers/gpu/drm/tegra/dc.c | 17 +- drivers/gpu/drm/tegra/hub.c | 4 +- drivers/gpu/drm/tegra/hub.h | 3 +- drivers/gpu/drm/tiny/cirrus-qemu.c | 1 - drivers/gpu/drm/tiny/simpledrm.c | 4 +- drivers/gpu/drm/udl/udl_drv.c | 2 +- drivers/gpu/drm/xe/display/xe_display.c | 2 + drivers/gpu/drm/xe/display/xe_dsb_buffer.c | 11 +- drivers/gpu/drm/xe/display/xe_fb_pin.c | 5 +- drivers/gpu/drm/xe/xe_ggtt.c | 11 + drivers/gpu/drm/xe/xe_gpu_scheduler.h | 10 +- drivers/gpu/drm/xe/xe_gt_tlb_invalidation.c | 8 + drivers/gpu/drm/xe/xe_guc_ct.c | 17 +- drivers/gpu/drm/xe/xe_guc_ct.h | 5 + drivers/gpu/drm/xe/xe_guc_pc.c | 2 +- drivers/gpu/drm/xe/xe_guc_submit.c | 23 + drivers/gpu/drm/xe/xe_guc_types.h | 5 + drivers/gpu/drm/xe/xe_vm.c | 8 +- drivers/hid/hid-appletb-kbd.c | 5 + drivers/hid/hid-lenovo.c | 11 +- .../intel-quicki2c/quicki2c-protocol.c | 26 +- drivers/hid/wacom_sys.c | 7 +- drivers/hwmon/isl28022.c | 6 +- drivers/hwmon/pmbus/max34440.c | 48 +- drivers/hwtracing/coresight/coresight-core.c | 3 +- drivers/hwtracing/coresight/coresight-priv.h | 1 + drivers/i2c/busses/i2c-imx.c | 3 +- drivers/i2c/busses/i2c-omap.c | 7 +- drivers/i2c/busses/i2c-robotfuzz-osif.c | 6 + drivers/i2c/busses/i2c-tiny-usb.c | 6 + drivers/iio/adc/ad7606_spi.c | 8 +- drivers/iio/adc/ad_sigma_delta.c | 4 + drivers/iio/dac/adi-axi-dac.c | 24 + drivers/iio/light/al3000a.c | 9 +- drivers/iio/light/hid-sensor-prox.c | 3 + drivers/iio/pressure/zpa2326.c | 2 +- drivers/iommu/amd/init.c | 3 - drivers/leds/led-class-multicolor.c | 3 +- drivers/mailbox/mailbox.c | 2 +- drivers/md/bcache/Kconfig | 1 - drivers/md/bcache/alloc.c | 57 +- drivers/md/bcache/bcache.h | 2 +- drivers/md/bcache/bset.c | 116 +- drivers/md/bcache/bset.h | 40 +- drivers/md/bcache/btree.c | 69 +- drivers/md/bcache/extents.c | 43 +- drivers/md/bcache/movinggc.c | 33 +- drivers/md/bcache/super.c | 10 +- drivers/md/bcache/sysfs.c | 4 +- drivers/md/bcache/util.h | 67 +- drivers/md/bcache/writeback.c | 13 +- drivers/md/dm-raid.c | 2 +- drivers/md/dm-vdo/indexer/volume.c | 24 +- drivers/md/md-bitmap.c | 2 +- drivers/media/usb/uvc/uvc_ctrl.c | 70 +- drivers/media/usb/uvc/uvc_v4l2.c | 93 +- drivers/media/usb/uvc/uvcvideo.h | 5 + drivers/mfd/88pm886.c | 6 +- drivers/mfd/max14577.c | 1 + drivers/mfd/max77541.c | 2 +- drivers/mfd/max77705.c | 4 +- drivers/mfd/sprd-sc27xx-spi.c | 5 +- drivers/misc/tps6594-pfsm.c | 3 + drivers/net/ethernet/broadcom/bnxt/bnxt.c | 5 +- drivers/net/ethernet/freescale/enetc/enetc_hw.h | 2 +- drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 12 +- drivers/net/ethernet/wangxun/libwx/wx_lib.c | 2 +- drivers/net/wireless/intel/iwlwifi/mld/fw.c | 8 +- drivers/nvme/host/core.c | 83 +- drivers/nvme/host/nvme.h | 3 +- drivers/nvme/host/tcp.c | 22 +- drivers/pci/controller/dwc/pci-imx6.c | 15 + drivers/pci/controller/dwc/pcie-designware.c | 5 +- drivers/pci/controller/pcie-apple.c | 3 + drivers/s390/crypto/pkey_api.c | 2 +- drivers/scsi/fnic/fdls_disc.c | 122 +- drivers/scsi/fnic/fnic.h | 2 +- drivers/scsi/fnic/fnic_fcs.c | 2 + drivers/scsi/fnic/fnic_fdls.h | 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 6 +- drivers/spi/spi-cadence-quadspi.c | 12 +- drivers/staging/rtl8723bs/core/rtw_security.c | 44 +- drivers/tty/serial/8250/8250_pci1xxxx.c | 10 + drivers/tty/serial/imx.c | 17 +- drivers/tty/serial/serial_base_bus.c | 1 + drivers/tty/serial/uartlite.c | 25 +- drivers/ufs/core/ufshcd.c | 6 +- drivers/usb/class/cdc-wdm.c | 23 +- drivers/usb/common/usb-conn-gpio.c | 25 +- drivers/usb/core/usb.c | 14 +- drivers/usb/dwc2/gadget.c | 6 + drivers/usb/gadget/function/f_hid.c | 19 +- drivers/usb/gadget/function/f_tcm.c | 4 +- drivers/usb/typec/altmodes/displayport.c | 4 + drivers/usb/typec/mux.c | 4 +- drivers/usb/typec/tcpm/tcpci_maxim_core.c | 5 +- drivers/usb/typec/tipd/core.c | 2 +- fs/btrfs/backref.h | 4 +- fs/btrfs/direct-io.c | 4 +- fs/btrfs/disk-io.c | 25 +- fs/btrfs/extent_io.h | 2 +- fs/btrfs/inode.c | 95 +- fs/btrfs/ordered-data.c | 14 +- fs/btrfs/raid56.c | 5 +- fs/btrfs/tests/extent-io-tests.c | 6 +- fs/btrfs/tree-log.c | 14 +- fs/btrfs/volumes.c | 6 + fs/btrfs/zstd.c | 2 +- fs/ceph/file.c | 2 +- fs/f2fs/file.c | 38 + fs/f2fs/super.c | 30 +- fs/fuse/dir.c | 11 + fs/fuse/inode.c | 4 + fs/namespace.c | 18 +- fs/nfs/inode.c | 51 +- fs/nfs/nfs4proc.c | 25 +- fs/overlayfs/util.c | 4 +- fs/proc/task_mmu.c | 2 +- fs/smb/client/cifsglob.h | 2 + fs/smb/client/cifspdu.h | 6 +- fs/smb/client/cifssmb.c | 1 + fs/smb/client/connect.c | 58 +- fs/smb/client/misc.c | 8 + fs/smb/client/reparse.c | 20 +- fs/smb/client/sess.c | 21 +- fs/smb/client/trace.h | 24 +- fs/smb/server/connection.h | 1 + fs/smb/server/smb2pdu.c | 72 +- fs/smb/server/smb2pdu.h | 3 + include/net/bluetooth/hci_core.h | 2 + include/uapi/linux/vm_sockets.h | 4 + io_uring/io_uring.c | 3 +- io_uring/kbuf.c | 1 + io_uring/kbuf.h | 1 + io_uring/net.c | 34 +- io_uring/rsrc.c | 57 +- io_uring/rsrc.h | 3 +- io_uring/zcrx.c | 101 +- io_uring/zcrx.h | 11 +- kernel/sched/ext.c | 12 +- lib/group_cpus.c | 9 +- lib/maple_tree.c | 4 +- mm/damon/sysfs-schemes.c | 1 + mm/gup.c | 14 +- mm/memory.c | 20 - mm/shmem.c | 6 +- mm/swap.h | 23 + mm/userfaultfd.c | 33 +- net/atm/clip.c | 11 +- net/atm/resources.c | 3 +- net/bluetooth/hci_core.c | 34 +- net/bluetooth/l2cap_core.c | 9 +- net/bridge/br_multicast.c | 9 + net/core/netpoll.c | 2 +- net/core/selftests.c | 5 +- net/mac80211/chan.c | 3 + net/mac80211/ieee80211_i.h | 12 + net/mac80211/iface.c | 12 +- net/mac80211/link.c | 94 +- net/mac80211/util.c | 2 +- net/sunrpc/clnt.c | 9 +- net/unix/af_unix.c | 31 +- rust/Makefile | 2 +- rust/bindings/bindings_helper.h | 1 + rust/helpers/completion.c | 8 + rust/helpers/helpers.c | 1 + rust/kernel/devres.rs | 53 +- rust/kernel/revocable.rs | 18 +- rust/kernel/sync.rs | 2 + rust/kernel/sync/completion.rs | 112 ++ rust/macros/module.rs | 1 + scripts/gdb/linux/vfs.py | 2 +- security/selinux/ss/services.c | 16 +- sound/pci/hda/hda_bind.c | 2 +- sound/pci/hda/hda_intel.c | 3 + sound/pci/hda/patch_realtek.c | 1 + sound/soc/amd/ps/acp63.h | 4 + sound/soc/amd/ps/ps-common.c | 18 + sound/soc/amd/yc/acp6x-mach.c | 7 + sound/soc/codecs/rt1320-sdw.c | 17 +- sound/soc/codecs/wcd9335.c | 40 +- sound/usb/quirks.c | 2 + sound/usb/stream.c | 2 + tools/lib/bpf/btf_dump.c | 3 + tools/lib/bpf/libbpf.c | 10 +- .../selftests/bpf/progs/test_global_map_resize.c | 16 + 289 files changed, 4527 insertions(+), 2538 deletions(-)
On Thu, 03 Jul 2025 16:38:40 +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.15: 10 builds: 10 pass, 0 fail 28 boots: 28 pass, 0 fail 120 tests: 120 pass, 0 fail
Linux version: 6.15.5-rc1-gd5e6f0c9ca48 Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000, tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000, tegra194-p3509-0000+p3668-0000, tegra20-ventana, tegra210-p2371-2180, tegra210-p3450-0000, tegra30-cardhu-a04
Tested-by: Jon Hunter jonathanh@nvidia.com
Jon
On Thu, 3 Jul 2025 at 20:27, Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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, 05 Jul 2025 14:39:10 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at: https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.15.5-rc1.... or in the git tree and branch at: git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-6.15.y and the diffstat can be found below.
thanks,
greg k-h
Results from Linaro’s test farm. No regressions on arm64, arm, x86_64, and i386.
Tested-by: Linux Kernel Functional Testing lkft@linaro.org
## Build * kernel: 6.15.5-rc1 * git: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git * git commit: d5e6f0c9ca48c1efb86783db4a2b4e457118c27b * git describe: v6.15.4-264-gd5e6f0c9ca48 * test details: https://qa-reports.linaro.org/lkft/linux-stable-rc-linux-6.15.y/build/v6.15....
## Test Regressions (compared to v6.15.3-590-gd93bc5feded1)
## Metric Regressions (compared to v6.15.3-590-gd93bc5feded1)
## Test Fixes (compared to v6.15.3-590-gd93bc5feded1)
## Metric Fixes (compared to v6.15.3-590-gd93bc5feded1)
## Test result summary total: 261397, pass: 239055, fail: 6046, skip: 16296, xfail: 0
## Build Summary * arc: 5 total, 5 passed, 0 failed * arm: 139 total, 136 passed, 1 failed, 2 skipped * arm64: 57 total, 49 passed, 0 failed, 8 skipped * i386: 18 total, 18 passed, 0 failed * mips: 34 total, 27 passed, 7 failed * parisc: 4 total, 4 passed, 0 failed * powerpc: 40 total, 39 passed, 1 failed * riscv: 25 total, 25 passed, 0 failed * s390: 22 total, 22 passed, 0 failed * sh: 5 total, 5 passed, 0 failed * sparc: 4 total, 3 passed, 1 failed * x86_64: 49 total, 48 passed, 0 failed, 1 skipped
## Test suites summary * boot * commands * kselftest-arm64 * kselftest-breakpoints * kselftest-capabilities * kselftest-cgroup * kselftest-clone3 * kselftest-core * kselftest-cpu-hotplug * kselftest-cpufreq * kselftest-efivarfs * kselftest-exec * kselftest-fpu * kselftest-ftrace * kselftest-futex * kselftest-gpio * kselftest-intel_pstate * kselftest-ipc * kselftest-kcmp * kselftest-kvm * kselftest-livepatch * kselftest-membarrier * kselftest-memfd * kselftest-mincore * kselftest-mm * kselftest-mqueue * kselftest-net * kselftest-net-mptcp * kselftest-openat2 * kselftest-ptrace * kselftest-rseq * kselftest-rtc * kselftest-rust * kselftest-seccomp * kselftest-sigaltstack * kselftest-size * kselftest-tc-testing * kselftest-timers * kselftest-tmpfs * kselftest-tpm2 * kselftest-user_events * kselftest-vDSO * kselftest-x86 * kunit * kvm-unit-tests * lava * libgpiod * libhugetlbfs * log-parser-boot * log-parser-build-clang * log-parser-build-gcc * log-parser-test * ltp-capability * ltp-commands * ltp-containers * ltp-controllers * ltp-cpuhotplug * ltp-crypto * ltp-cve * ltp-dio * ltp-fcntl-locktests * ltp-fs * ltp-fs_bind * ltp-fs_perms_simple * ltp-hugetlb * ltp-math * ltp-mm * ltp-nptl * ltp-pty * ltp-sched * ltp-smoke * ltp-syscalls * ltp-tracing * modules * perf * rcutorture * rt-tests-cyclicdeadline * rt-tests-pi-stress * rt-tests-pmqtest * rt-tests-rt-migrate-test * rt-tests-signaltest
-- Linaro LKFT https://lkft.linaro.org
On Thu, Jul 03, 2025 at 04:38:40PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.15.5 release. There are 263 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.
Tested-by: Mark Brown broonie@kernel.org
linux-stable-mirror@lists.linaro.org