This is the start of the stable review cycle for the 6.14.5 release. There are 311 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 01 May 2025 16:10:15 +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.14.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.14.y and the diffstat can be found below.
thanks,
greg k-h
------------- Pseudo-Shortlog of commits:
Greg Kroah-Hartman gregkh@linuxfoundation.org Linux 6.14.5-rc1
Herbert Xu herbert@gondor.apana.org.au crypto: Kconfig - Select LIB generic option
Josh Poimboeuf jpoimboe@kernel.org objtool: Silence more KCOV warnings, part 2
Josh Poimboeuf jpoimboe@kernel.org objtool: Ignore end-of-section jumps for KCOV/GCOV
Michal Pecio michal.pecio@gmail.com usb: xhci: Fix Short Packet handling rework ignoring errors
Hannes Reinecke hare@kernel.org nvme: fixup scan failure for non-ANA multipath controllers
Ming Lei ming.lei@redhat.com ublk: don't fail request for recovery & reissue in case of ubq->canceling
Miguel Ojeda ojeda@kernel.org rust: kbuild: skip `--remap-path-prefix` for `rustdoc`
Dimitri Fedrau dimitri.fedrau@liebherr.com net: phy: dp83822: fix transmit amplitude if CONFIG_OF_MDIO not defined
Thomas Bogendoerfer tsbogend@alpha.franken.de MIPS: cm: Fix warning if MIPS_CM is disabled
Dan Carpenter dan.carpenter@linaro.org media: i2c: imx214: Fix uninitialized variable in imx214_set_ctrl()
Herbert Xu herbert@gondor.apana.org.au crypto: lib/Kconfig - Hide arch options from user
Ian Abbott abbotti@mev.co.uk comedi: jr3_pci: Fix synchronous deletion of timer
Daniel Borkmann daniel@iogearbox.net vmxnet3: Fix malformed packet sizing in vmxnet3_process_xdp
Dmitry Torokhov dmitry.torokhov@gmail.com driver core: fix potential NULL pointer dereference in dev_uevent()
Dmitry Torokhov dmitry.torokhov@gmail.com driver core: introduce device_set_driver() helper
Dmitry Torokhov dmitry.torokhov@gmail.com Revert "drivers: core: synchronize really_probe() and dev_uevent()"
Tamura Dai kirinode0@gmail.com spi: spi-imx: Add check for spi_imx_setupxfer()
Ming Lei ming.lei@redhat.com ublk: rely on ->canceling for dealing with ublk_nosrv_dev_should_queue_io
Ming Lei ming.lei@redhat.com ublk: add ublk_force_abort_dev()
Lijo Lazar lijo.lazar@amd.com drm/amdgpu: Use the right function for hdp flush
Mario Limonciello mario.limonciello@amd.com drm/amd: Forbid suspending into non-default suspend states
Christian König christian.koenig@amd.com drm/amdgpu: use a dummy owner for sysfs triggered cleaner shaders v4
Meir Elisha meir.elisha@volumez.com md/raid1: Add check for missing source disk in process_checks()
Pi Xiange xiange.pi@intel.com x86/cpu: Add CPU model number for Bartlett Lake CPUs with Raptor Cove cores
Damien Le Moal dlemoal@kernel.org nvmet: pci-epf: cleanup link state management
Mostafa Saleh smostafa@google.com ubsan: Fix panic from test_ubsan_out_of_bounds
Breno Leitao leitao@debian.org spi: tegra210-quad: add rate limiting and simplify timeout error message
Breno Leitao leitao@debian.org spi: tegra210-quad: use WARN_ON_ONCE instead of WARN_ON for timeouts
Namjae Jeon linkinjeon@kernel.org ksmbd: fix WARNING "do not call blocking ops when !TASK_RUNNING"
Andrew Jones ajones@ventanamicro.com riscv: Provide all alternative macros all the time
Gou Hao gouhao@uniontech.com iomap: skip unnecessary ifs_block_is_uptodate check
Song Liu song@kernel.org netfs: Only create /proc/fs/netfs with CONFIG_PROC_FS
Hans de Goede hdegoede@redhat.com platform/x86: x86-android-tablets: Add Vexia Edu Atla 10 tablet 5V data
Hans de Goede hdegoede@redhat.com platform/x86: x86-android-tablets: Add "9v" to Vexia EDU ATLA 10 tablet symbols
Fernando Fernandez Mancera ffmancera@riseup.net x86/i8253: Call clockevent_i8253_disable() with interrupts disabled
Weidong Wang wangweidong.a@awinic.com ASoC: codecs: Add of_match_table for aw888081 driver
Shengjiu Wang shengjiu.wang@nxp.com ASoC: fsl_asrc_dma: get codec or cpu dai from backend
Igor Pylypiv ipylypiv@google.com scsi: pm80xx: Set phy_attached to zero when device is gone
Peter Griffin peter.griffin@linaro.org scsi: ufs: exynos: gs101: Put UFS device in reset on .suspend()
Peter Griffin peter.griffin@linaro.org scsi: ufs: exynos: Move phy calls to .exit() callback
Peter Griffin peter.griffin@linaro.org scsi: ufs: exynos: Enable PRDT pre-fetching with UFSHCD_CAP_CRYPTO
Peter Griffin peter.griffin@linaro.org scsi: ufs: exynos: Ensure pre_link() executes before exynos_ufs_phy_init()
Xingui Yang yangxingui@huawei.com scsi: hisi_sas: Fix I/O errors caused by hardware port ID changes
Ojaswin Mujoo ojaswin@linux.ibm.com ext4: make block validity check resistent to sb bh corruption
Robin Murphy robin.murphy@arm.com iommu: Clear iommu-dma ops on cleanup
Pali Rohár pali@kernel.org cifs: Fix querying of WSL CHR and BLK reparse points over SMB1
Sebastian Andrzej Siewior bigeasy@linutronix.de timekeeping: Add a lockdep override in tick_freeze()
Pali Rohár pali@kernel.org cifs: Fix encoding of SMB1 Session Setup Kerberos Request in non-UNICODE mode
Daniel Wagner wagi@kernel.org nvmet-fc: put ref when assoc->del_work is already scheduled
Daniel Wagner wagi@kernel.org nvmet-fc: take tgtport reference only once
Josh Poimboeuf jpoimboe@kernel.org x86/bugs: Don't fill RSB on context switch with eIBRS
Josh Poimboeuf jpoimboe@kernel.org x86/bugs: Don't fill RSB on VMEXIT with eIBRS+retpoline
Josh Poimboeuf jpoimboe@kernel.org x86/bugs: Use SBPB in write_ibpb() if applicable
Qiuxu Zhuo qiuxu.zhuo@intel.com selftests/mincore: Allow read-ahead pages to reach the end of the file
Roger Pau Monne roger.pau@citrix.com x86/xen: disable CPU idle and frequency drivers for PVH dom0
Andy Shevchenko andriy.shevchenko@linux.intel.com gpiolib: of: Move Atmel HSMCI quirk up out of the regulator comment
Josh Poimboeuf jpoimboe@kernel.org objtool: Stop UNRET validation on UD2
Uday Shankar ushankar@purestorage.com nvme: multipath: fix return value of nvme_available_path
Hannes Reinecke hare@kernel.org nvme: re-read ANA log page after ns scan completes
Julia Filipchuk julia.filipchuk@intel.com drm/xe/xe3lpg: Apply Wa_14022293748, Wa_22019794406
Jay Cornwall jay.cornwall@amd.com drm/amdgpu: Increase KIQ invalidate_tlbs timeout
Emily Deng Emily.Deng@amd.com drm/amdkfd: sriov doesn't support per queue reset
Jean-Marc Eurin jmeurin@google.com ACPI PPTT: Fix coding mistakes in a couple of sizeof() calls
Mario Limonciello mario.limonciello@amd.com ACPI: EC: Set ec_no_wakeup for Lenovo Go S
Hannes Reinecke hare@kernel.org nvme: requeue namespace scan on missed AENs
Uwe Kleine-König u.kleine-koenig@baylibre.com pwm: axi-pwmgen: Let .round_waveform_tohw() signal when request was rounded up
Uwe Kleine-König u.kleine-koenig@baylibre.com pwm: Let pwm_set_waveform() succeed even if lowlevel driver rounded up
Jason Andryuk jason.andryuk@amd.com xen: Change xen-acpi-processor dom0 dependency
Gabriel Shahrouzi gshahrouzi@gmail.com perf/core: Fix WARN_ON(!ctx) in __free_event() for partial init
Ming Lei ming.lei@redhat.com selftests: ublk: fix test_stripe_04
Waiman Long longman@redhat.com cgroup/cpuset: Don't allow creation of local partition over a remote one
Xiaogang Chen xiaogang.chen@amd.com udmabuf: fix a buf size overflow issue during udmabuf creation
Thomas Weißschuh thomas.weissschuh@linutronix.de KVM: s390: Don't use %pK through debug printing
Thomas Weißschuh thomas.weissschuh@linutronix.de KVM: s390: Don't use %pK through tracepoints
Oleg Nesterov oleg@redhat.com sched/isolation: Make CONFIG_CPU_ISOLATION depend on CONFIG_SMP
Xi Ruoyao xry111@xry111.site kbuild: add dependency from vmlinux to sorttable
Thomas Weißschuh linux@weissschuh.net kbuild, rust: use -fremap-path-prefix to make paths relative
Pavel Begunkov asml.silence@gmail.com io_uring: always do atomic put from iowq
Steven Rostedt rostedt@goodmis.org tracing: Enforce the persistent ring buffer to be page aligned
Lukas Stockmann lukas.stockmann@siemens.com rtc: pcf85063: do a SW reset if POR failed
Ignacio Encinas ignacio@iencinas.com 9p/trans_fd: mark concurrent read and writes to p9_conn->err
Dominique Martinet asmadeus@codewreck.org 9p/net: fix improper handling of bogus negative read/write replies
Basavaraj Natikar Basavaraj.Natikar@amd.com ntb_hw_amd: Add NTB PCI ID for new gen CPU
Arnd Bergmann arnd@arndb.de ntb: reduce stack usage in idt_scan_mws
Charlie Jenkins charlie@rivosinc.com riscv: tracing: Fix __write_overflow_field in ftrace_partial_regs()
Al Viro viro@zeniv.linux.org.uk qibfs: fix _another_ leak
Josh Poimboeuf jpoimboe@kernel.org objtool, lkdtm: Obfuscate the do_nothing() pointer
Josh Poimboeuf jpoimboe@kernel.org objtool, regulator: rk808: Remove potential undefined behavior in rk806_set_mode_dcdc()
Josh Poimboeuf jpoimboe@kernel.org objtool, ASoC: codecs: wcd934x: Remove potential undefined behavior in wcd934x_slim_irq_handler()
Josh Poimboeuf jpoimboe@kernel.org objtool, panic: Disable SMAP in __stack_chk_fail()
Josh Poimboeuf jpoimboe@kernel.org objtool: Silence more KCOV warnings
Nicolin Chen nicolinc@nvidia.com iommu/arm-smmu-v3: Set MEV bit in nested STE for DoS mitigations
Benjamin Berg benjamin.berg@intel.com um: work around sched_yield not yielding in time-travel mode
Mika Westerberg mika.westerberg@linux.intel.com thunderbolt: Scan retimers after device router has been enumerated
Théo Lebrun theo.lebrun@bootlin.com usb: host: xhci-plat: mvebu: use ->quirks instead of ->init_quirk() func
Chenyuan Yang chenyuan0y@gmail.com usb: gadget: aspeed: Add NULL pointer check in ast_vhub_init_dev()
Andy Yan andy.yan@rock-chips.com phy: rockchip: usbdp: Avoid call hpd_event_trigger in dp_phy_init
Michal Pecio michal.pecio@gmail.com usb: xhci: Avoid Stop Endpoint retry loop if the endpoint seems Running
Vinicius Costa Gomes vinicius.gomes@intel.com dmaengine: dmatest: Fix dmatest waiting less when interrupted
Stanley Chu yschu@nuvoton.com i3c: master: svc: Add support for Nuvoton npcm845 i3c
Mathias Nyman mathias.nyman@linux.intel.com xhci: Handle spurious events on Etron host isoc enpoints
Michal Pecio michal.pecio@gmail.com usb: xhci: Fix isochronous Ring Underrun/Overrun event handling
Michal Pecio michal.pecio@gmail.com usb: xhci: Complete 'error mid TD' transfers when handling Missed Service
Stefan Wahren wahrenst@gmx.net dmaengine: bcm2835-dma: fix warning when CONFIG_PM=n
John Stultz jstultz@google.com sound/virtio: Fix cancel_sync warnings on uninitialized work_structs
Andy Shevchenko andriy.shevchenko@linux.intel.com usb: dwc3: gadget: Avoid using reserved endpoints on Intel Merrifield
Andy Shevchenko andriy.shevchenko@linux.intel.com usb: dwc3: gadget: Refactor loop to avoid NULL endpoints
Edward Adam Davis eadavis@qq.com fs/ntfs3: Fix WARNING in ntfs_extend_initialized_size
Lizhi Xu lizhi.xu@windriver.com fs/ntfs3: Keep write operations atomic
Trevor Gamblin tgamblin@baylibre.com iio: adc: ad4695: make ad4695_exit_conversion_mode() more robust
Dmitry Baryshkov dmitry.baryshkov@linaro.org usb: typec: ucsi: ccg: move command quirks to ucsi_ccg_sync_control()
Dmitry Baryshkov dmitry.baryshkov@linaro.org usb: typec: ucsi: return CCI and message from sync_control callback
Alexander Stein alexander.stein@mailbox.org usb: host: max3421-hcd: Add missing spi_device_id table
Dave Penkler dpenkler@gmail.com staging: gpib: Use min for calculating transfer length
Sudeep Holla sudeep.holla@arm.com mailbox: pcc: Always clear the platform ack interrupt first
Huisong Li lihuisong@huawei.com mailbox: pcc: Fix the possible race in updation of chan_in_use flag
Yafang Shao laoar.shao@gmail.com bpf: Reject attaching fexit/fmod_ret to __noreturn functions
Martin KaFai Lau martin.lau@kernel.org bpf: Only fails the busy counter check in bpf_cgrp_storage_get if it creates storage
Sewon Nam swnam0729@gmail.com bpf: bpftool: Setting error code in do_loader()
Feng Yang yangfeng@kylinos.cn selftests/bpf: Fix cap_enable_effective() return code
Biju Das biju.das.jz@bp.renesas.com clk: renesas: rzv2h: Adjust for CPG_BUS_m_MSTOP starting from m = 1
Haoxiang Li haoxiang_li2024@163.com s390/tty: Fix a potential memory leak bug
Haoxiang Li haoxiang_li2024@163.com s390/sclp: Add check for get_zeroed_page()
Yu-Chun Lin eleanor15x@gmail.com parisc: PDT: Fix missing prototype warning
Heiko Stuebner heiko@sntech.de clk: check for disabled clock-provider in of_clk_get_hw_from_clkspec()
Alexei Starovoitov ast@kernel.org bpf: Fix deadlock between rcu_tasks_trace and event_mutex.
Yonghong Song yonghong.song@linux.dev bpf: Fix kmemleak warning for percpu hashmap
Herbert Xu herbert@gondor.apana.org.au crypto: null - Use spin lock instead of mutex
Herbert Xu herbert@gondor.apana.org.au crypto: lib/Kconfig - Fix lib built-in failure when arch is modular
Devaraj Rangasamy Devaraj.Rangasamy@amd.com crypto: ccp - Add support for PCI device 0x1134
Gregory CLEMENT gregory.clement@bootlin.com MIPS: cm: Detect CM quirks from device tree
Dmitry Mastykin mastichi@gmail.com pinctrl: mcp23s08: Get rid of spurious level interrupts
Chenyuan Yang chenyuan0y@gmail.com pinctrl: renesas: rza2: Fix potential NULL pointer dereference
Amery Hung ameryhung@gmail.com selftests/bpf: Fix stdout race condition in traffic monitor
Lukas Wunner lukas@wunner.de crypto: ecdsa - Harden against integer overflows in DIV_ROUND_UP()
Oliver Neukum oneukum@suse.com USB: wdm: add annotation
Oliver Neukum oneukum@suse.com USB: wdm: wdm_wwan_port_tx_complete mutex in atomic context
Oliver Neukum oneukum@suse.com USB: wdm: close race between wdm_open and wdm_wwan_port_stop
Oliver Neukum oneukum@suse.com USB: wdm: handle IO errors in wdm_wwan_port_start
Dan Carpenter dan.carpenter@linaro.org usb: typec: class: Unlocked on error in typec_register_partner()
Andrei Kuchynski akuchynski@chromium.org usb: typec: class: Invalidate USB device pointers on partner unregistration
Andrei Kuchynski akuchynski@chromium.org usb: typec: class: Fix NULL pointer access
Oliver Neukum oneukum@suse.com USB: VLI disk crashes if LPM is used
Miao Li limiao@kylinos.cn usb: quirks: Add delay init quirk for SanDisk 3.2Gen1 Flash Drive
Miao Li limiao@kylinos.cn usb: quirks: add DELAY_INIT quirk for Silicon Motion Flash Drive
Mike Looijmans mike.looijmans@topic.nl usb: dwc3: xilinx: Prevent spike in reset signal
Frode Isaksen frode@meta.com usb: dwc3: gadget: check that event count does not exceed event buffer length
Huacai Chen chenhuacai@kernel.org USB: OHCI: Add quirk for LS7A OHCI controller (rev 0x02)
Fedor Pchelkin pchelkin@ispras.ru usb: chipidea: ci_hdrc_imx: implement usb_phy_init() error handling
Fedor Pchelkin pchelkin@ispras.ru usb: chipidea: ci_hdrc_imx: fix call balance of regulator routines
Fedor Pchelkin pchelkin@ispras.ru usb: chipidea: ci_hdrc_imx: fix usbmisc handling
Ralph Siemsen ralph.siemsen@linaro.org usb: cdns3: Fix deadlock when using NCM gadget
Michal Pecio michal.pecio@gmail.com usb: xhci: Fix invalid pointer dereference in Etron workaround
Mathias Nyman mathias.nyman@linux.intel.com xhci: Limit time spent with xHC interrupts disabled during bus resume
Craig Hesling craig@hesling.com USB: serial: simple: add OWON HDS200 series oscilloscope support
Adam Xue zxue@semtech.com USB: serial: option: add Sierra Wireless EM9291
Michael Ehrenreich michideep@gmail.com USB: serial: ftdi_sio: add support for Abacus Electrics Optical Probe
Ryo Takakura ryotkkr98@gmail.com serial: sifive: lock port in startup()/shutdown() callbacks
Stephan Gerhold stephan.gerhold@linaro.org serial: msm: Configure correct working mode before starting earlycon
Günther Noack gnoack3000@gmail.com tty: Require CAP_SYS_ADMIN for all usages of TIOCL_SELMOUSEREPORT
Mahesh Rao mahesh.rao@intel.com firmware: stratix10-svc: Add of_platform_default_populate()
Rengarajan S rengarajan.s@microchip.com misc: microchip: pci1xxxx: Fix incorrect IRQ status handling during ack
Rengarajan S rengarajan.s@microchip.com misc: microchip: pci1xxxx: Fix Kernel panic during IRQ handler registration
Thadeu Lima de Souza Cascardo cascardo@igalia.com char: misc: register chrdev region with all possible minors
Sean Christopherson seanjc@google.com KVM: x86: Take irqfds.lock when adding/deleting IRQ bypass producer
Sean Christopherson seanjc@google.com KVM: x86: Reset IRTE to host control if *new* route isn't postable
Sean Christopherson seanjc@google.com KVM: x86: Explicitly treat routing entry type changes as changes
Hans de Goede hdegoede@redhat.com mei: vsc: Fix fortify-panic caused by invalid counted_by() use
Alexander Usyskin alexander.usyskin@intel.com mei: me: add panther lake H DID
Damien Le Moal dlemoal@kernel.org scsi: Improve CDL control
Oliver Neukum oneukum@suse.com USB: storage: quirk for ADATA Portable HDD CH94
Damien Le Moal dlemoal@kernel.org ata: libata-scsi: Fix ata_msense_control_ata_feature()
Damien Le Moal dlemoal@kernel.org ata: libata-scsi: Fix ata_mselect_control_ata_feature() return type
Damien Le Moal dlemoal@kernel.org ata: libata-scsi: Improve CDL control
Haoxiang Li haoxiang_li2024@163.com mcb: fix a double free bug in chameleon_parse_gdd()
Smita Koralahalli Smita.KoralahalliChannabasappa@amd.com cxl/core/regs.c: Skip Memory Space Enable check for RCD and RCH Ports
Sean Christopherson seanjc@google.com KVM: SVM: Allocate IR data using atomic allocation
Jens Axboe axboe@kernel.dk io_uring: fix 'sync' handling of io_fallback_tw()
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Fix PMU pass-through issue if VM exits to host finally
Bibo Mao maobibo@loongson.cn LoongArch: KVM: Fully clear some CSRs when VM reboot
Yulong Han wheatfox17@icloud.com LoongArch: KVM: Fix multiple typos of KVM code
Petr Tesarik ptesarik@suse.com LoongArch: Remove a bogus reference to ZONE_DMA
Ming Wang wangming01@loongson.cn LoongArch: Return NULL from huge_pte_offset() for invalid PMD
Tiezhu Yang yangtiezhu@loongson.cn LoongArch: Handle fp, lsx, lasx and lbt assembly symbols
Carlos Llamas cmllamas@google.com binder: fix offset calculation in debug log
Suzuki K Poulose suzuki.poulose@arm.com irqchip/gic-v2m: Prevent use after free of gicv2m_get_fwnode()
Ilpo Järvinen ilpo.jarvinen@linux.intel.com selftests/pcie_bwctrl: Fix test progs list
Juergen Gross jgross@suse.com x86/mm: Fix _pgd_alloc() for Xen PV mode
Kirill A. Shutemov kirill.shutemov@linux.intel.com x86/insn: Fix CTEST instruction decoding
Mario Limonciello mario.limonciello@amd.com drm/amd/display: Fix ACPI edid parsing on some Lenovo systems
Roman Li Roman.Li@amd.com drm/amd/display: Force full update in gpu reset
Roman Li Roman.Li@amd.com drm/amd/display: Fix gpu reset in multidisplay config
Hugo Villeneuve hvilleneuve@dimonoff.com drm: panel: jd9365da: fix reset signal polarity in unprepare
Christian Schrefl chrisi.schrefl@gmail.com rust: firmware: Use `ffi::c_char` type in `FwFunc`
Ranjan Kumar ranjan.kumar@broadcom.com scsi: mpi3mr: Fix pending I/O counter
Mat Martineau martineau@kernel.org mptcp: pm: Defer freeing of MPTCP userspace path manager entries
Fiona Klute fiona.klute@gmx.de net: phy: microchip: force IRQ polling mode for lan88xx
Oleksij Rempel o.rempel@pengutronix.de net: selftests: initialize TCP header and skb payload with zero
Alexey Nepomnyashih sdl@nppct.ru xen-netfront: handle NULL returned by xdp_convert_buff_to_frame()
Marek Behún kabel@kernel.org crypto: atmel-sha204a - Set hwrng quality to lowest possible
Breno Leitao leitao@debian.org sched_ext: Use kvzalloc for large exit_dump allocation
Halil Pasic pasic@linux.ibm.com virtio_console: fix missing byte order handling for cols and rows
Florian Westphal fw@strlen.de netfilter: fib: avoid lookup if socket is available
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: stmmac: block PHY RXC clock-stop
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: phylink: add functions to block/unblock rx clock stop
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: stmmac: socfpga: remove phy_resume() call
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: stmmac: address non-LPI resume failures properly
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: phylink: add phylink_prepare_resume()
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: stmmac: simplify phylink_suspend() and phylink_resume() calls
Omar Sandoval osandov@fb.com sched/eevdf: Fix se->slice being set to U64_MAX and resulting crash
Tiezhu Yang yangtiezhu@loongson.cn LoongArch: Make do_xyz() exception handlers more robust
Tiezhu Yang yangtiezhu@loongson.cn LoongArch: Make regs_irqs_disabled() more clear
Yuli Wang wangyuli@uniontech.com LoongArch: Select ARCH_USE_MEMTEST
Luo Gengkun luogengkun@huaweicloud.com perf/x86: Fix non-sampling (counting) events on certain x86 platforms
Martin Blumenstingl martin.blumenstingl@googlemail.com drm/meson: use unsigned long long / Hz for frequency types
Christian Hewitt christianshewitt@gmail.com Revert "drm/meson: vclk: fix calculation of 59.94 fractional rates"
Alexei Starovoitov ast@kernel.org bpf: Add namespace to BPF internal symbols
Jan Kara jack@suse.cz fs/xattr: Fix handling of AT_FDCWD in setxattrat(2) and getxattrat(2)
T.J. Mercier tjmercier@google.com splice: remove duplicate noinline from pipe_clear_nowait
Ming Lei ming.lei@redhat.com ublk: call ublk_dispatch_req() for handling UBLK_U_IO_NEED_GET_DATA
Caleb Sander Mateos csander@purestorage.com ublk: remove unused cmd argument to ublk_dispatch_req()
Ming Lei ming.lei@redhat.com ublk: implement ->queue_rqs()
Ming Lei ming.lei@redhat.com ublk: comment on ubq->canceling handling in ublk_queue_rq()
Uday Shankar ushankar@purestorage.com ublk: remove io_cmds list in ublk_queue
Björn Töpel bjorn@rivosinc.com riscv: uprobes: Add missing fence.i after building the XOL buffer
Björn Töpel bjorn@rivosinc.com riscv: Replace function-like macro by static inline function
Sean Christopherson seanjc@google.com iommu/amd: Return an error if vCPU affinity is set for non-vCPU IRTE
Christoph Hellwig hch@lst.de block: don't autoload drivers on stat
Christoph Hellwig hch@lst.de block: remove the backing_inode variable in bdev_statx
Christoph Hellwig hch@lst.de block: move blkdev_{get,put} _no_open prototypes out of blkdev.h
Luis Chamberlain mcgrof@kernel.org bdev: use bdev_io_min() for statx block size
Christoph Hellwig hch@lst.de block: never reduce ra_pages in blk_apply_bdi_limits
Alexis Lothoré alexis.lothore@bootlin.com net: stmmac: fix multiplication overflow when reading timestamp
Alexis Lothore alexis.lothore@bootlin.com net: stmmac: fix dwmac1000 ptp timestamp status offset
Johannes Schneider johannes.schneider@leica-geosystems.com net: dp83822: Fix OF_MDIO config check
Dimitri Fedrau dimitri.fedrau@liebherr.com net: phy: dp83822: Add support for changing the transmit amplitude voltage
Dimitri Fedrau dimitri.fedrau@liebherr.com net: phy: Add helper for getting tx amplitude gain
Shannon Nelson shannon.nelson@amd.com pds_core: make wait_context part of q_info
Brett Creeley brett.creeley@amd.com pds_core: Remove unnecessary check in pds_client_adminq_cmd()
Brett Creeley brett.creeley@amd.com pds_core: handle unsupported PDS_CORE_CMD_FW_CONTROL result
Brett Creeley brett.creeley@amd.com pds_core: Prevent possible adminq overflow/stuck condition
Daniel Golle daniel@makrotopia.org net: dsa: mt7530: sync driver-specific behavior of MT7531 variants
Cong Wang xiyou.wangcong@gmail.com net_sched: hfsc: Fix a potential UAF in hfsc_dequeue() too
Cong Wang xiyou.wangcong@gmail.com net_sched: hfsc: Fix a UAF vulnerability in class handling
Al Viro viro@zeniv.linux.org.uk fix a couple of races in MNT_TREE_BENEATH handling by do_move_mount()
Bo-Cun Chen bc-bocun.chen@mediatek.com net: ethernet: mtk_eth_soc: net: revise NETSYSv3 hardware configuration
Tung Nguyen tung.quang.nguyen@est.tech tipc: fix NULL pointer dereference in tipc_mon_reinit_self()
Bui Quang Minh minhquangbui99@gmail.com virtio-net: disable delayed refill when pausing rx
Joe Damato jdamato@fastly.com virtio-net: Refactor napi_disable paths
Joe Damato jdamato@fastly.com virtio-net: Refactor napi_enable paths
Qingfang Deng qingfang.deng@siflower.com.cn net: phy: leds: fix memory leak
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: phylink: fix suspend/resume with WoL enabled and link down
Russell King (Oracle) rmk+kernel@armlinux.org.uk net: phylink: force link down on major_config failure
Justin Iurman justin.iurman@uliege.be net: lwtunnel: disable BHs when required
Richard Weinberger richard@nod.at nvmet: fix out-of-bounds access in nvmet_enable_port
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: fix frame corruption on bpf_xdp_adjust_head/tail() and XDP_PASS
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: refactor bulk flipping of RX buffers to separate function
Vladimir Oltean vladimir.oltean@nxp.com net: enetc: register XDP RX queues with frag_size
Chenyuan Yang chenyuan0y@gmail.com scsi: ufs: core: Add NULL check in ufshcd_mcq_compl_pending_transfer()
Anastasia Kovaleva a.kovaleva@yadro.com scsi: core: Clear flags for scsi_cmnd that did not complete
Henry Martin bsdhenrymartin@gmail.com net/mlx5: Move ttc allocation after switch case to prevent leaks
Henry Martin bsdhenrymartin@gmail.com net/mlx5: Fix null-ptr-deref in mlx5_create_{inner_,}ttc_table()
Dongli Zhang dongli.zhang@oracle.com vhost-scsi: Fix vhost_scsi_send_status()
Dongli Zhang dongli.zhang@oracle.com vhost-scsi: Fix vhost_scsi_send_bad_target()
Mike Christie michael.christie@oracle.com vhost-scsi: Add better resource allocation failure handling
T.J. Mercier tjmercier@google.com cgroup/cpuset-v1: Add missing support for cpuset_v2_mode
Johannes Thumshirn johannes.thumshirn@wdc.com btrfs: zoned: return EIO on RAID1 block group write pointer mismatch
Qu Wenruo wqu@suse.com btrfs: avoid page_lockend underflow in btrfs_punch_hole_lock_range()
Johan Hovold johan+linaro@kernel.org cpufreq: fix compile-test defaults
Krzysztof Kozlowski krzysztof.kozlowski@linaro.org cpufreq: Do not enable by default during compile testing
Marc Zyngier maz@kernel.org cpufreq: cppc: Fix invalid return value in .get() callback
Daniel Jurgens danielj@nvidia.com virtio_pci: Use self group type for cap commands
Chenyuan Yang chenyuan0y@gmail.com scsi: ufs: mcq: Add NULL check in ufshcd_mcq_abort()
Henry Martin bsdhenrymartin@gmail.com cpufreq: scpi: Fix null-ptr-deref in scpi_cpufreq_get_rate()
Henry Martin bsdhenrymartin@gmail.com cpufreq: scmi: Fix null-ptr-deref in scmi_cpufreq_get_rate()
Henry Martin bsdhenrymartin@gmail.com cpufreq: apple-soc: Fix null-ptr-deref in apple_soc_cpufreq_get_rate()
Arnd Bergmann arnd@arndb.de dma/contiguous: avoid warning about unused size_bytes
Andre Przywara andre.przywara@arm.com cpufreq: sun50i: prevent out-of-bounds access
David Howells dhowells@redhat.com ceph: Fix incorrect flush end position calculation
Nathan Chancellor nathan@kernel.org lib/Kconfig.ubsan: Remove 'default UBSAN' from UBSAN_INTEGER_WRAP
Niranjana Vishwanathapura niranjana.vishwanathapura@intel.com drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change
Lucas De Marchi lucas.demarchi@intel.com drm/xe/rtp: Drop sentinels from arg to xe_rtp_process_to_sr()
Tvrtko Ursulin tvrtko.ursulin@igalia.com drm/xe: Add performance tunings to debugfs
Tejas Upadhyay tejas.upadhyay@intel.com drm/xe/xe3lpg: Add Wa_13012615864
Nirmoy Das nirmoy.das@intel.com drm/xe/ptl: Apply Wa_14023061436
Jonathan Currier dullfire@yahoo.com net/niu: Niu requires MSIX ENTRY_DATA fields touch before entry reads
Biju Das biju.das.jz@bp.renesas.com irqchip/renesas-rzv2h: Prevent TINT spurious interrupt
Biju Das biju.das.jz@bp.renesas.com irqchip/renesas-rzv2h: Add struct rzv2h_hw_info with t_offs variable
Biju Das biju.das.jz@bp.renesas.com irqchip/renesas-rzv2h: Simplify rzv2h_icu_init()
Jonathan Currier dullfire@yahoo.com PCI/MSI: Add an option to write MSIX ENTRY_DATA before any reads
Thomas Gleixner tglx@linutronix.de PCI/MSI: Handle the NOMASK flag correctly for all PCI/MSI backends
Roger Pau Monne roger.pau@citrix.com PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag
Niklas Schnelle schnelle@linux.ibm.com s390/pci: Support mmap() of PCI resources except for ISM devices
Tudor Ambarus tudor.ambarus@linaro.org scsi: ufs: qcom: fix dev reference leaked through of_qcom_ice_get
Zijun Hu quic_zijuhu@quicinc.com of: resolver: Fix device node refcount leakage in of_resolve_phandles()
Rob Herring (Arm) robh@kernel.org of: resolver: Simplify of_resolve_phandles() using __free()
Sergiu Cuciurean sergiu.cuciurean@analog.com iio: adc: ad7768-1: Fix conversion result sign
Jonathan Cameron Jonathan.Cameron@huawei.com iio: adc: ad7768-1: Move setting of val a bit later to avoid unnecessary return value check
Hans de Goede hdegoede@redhat.com media: ov08x40: Add missing ov08x40_identify_module() call on stream-start
Hans de Goede hdegoede@redhat.com media: ov08x40: Move ov08x40_identify_module() function up
André Apitzsch git@apitzsch.eu media: i2c: imx214: Fix link frequency validation
André Apitzsch git@apitzsch.eu media: i2c: imx214: Check number of lanes from device tree
André Apitzsch git@apitzsch.eu media: i2c: imx214: Replace register addresses with macros
André Apitzsch git@apitzsch.eu media: i2c: imx214: Convert to CCI register access helpers
André Apitzsch git@apitzsch.eu media: i2c: imx214: Simplify with dev_err_probe()
André Apitzsch git@apitzsch.eu media: i2c: imx214: Use subdev active state
Rafael J. Wysocki rafael.j.wysocki@intel.com PM: EM: Address RCU-related sparse warnings
Li RongQing lirongqing@baidu.com PM: EM: use kfree_rcu() to simplify the code
Tudor Ambarus tudor.ambarus@linaro.org mmc: sdhci-msm: fix dev reference leaked through of_qcom_ice_get
Tudor Ambarus tudor.ambarus@linaro.org soc: qcom: ice: introduce devm_of_qcom_ice_get
Jinjiang Tu tujinjiang@huawei.com mm/vmscan: don't try to reclaim hwpoison folio
-------------
Diffstat:
Documentation/admin-guide/kernel-parameters.txt | 2 + Documentation/bpf/bpf_devel_QA.rst | 8 + Documentation/trace/debugging.rst | 2 + Makefile | 5 +- arch/arm/crypto/Kconfig | 10 +- arch/arm64/crypto/Kconfig | 6 +- arch/loongarch/Kconfig | 1 + arch/loongarch/include/asm/fpu.h | 33 +- arch/loongarch/include/asm/lbt.h | 10 +- arch/loongarch/include/asm/ptrace.h | 4 +- arch/loongarch/kernel/fpu.S | 6 + arch/loongarch/kernel/lbt.S | 4 + arch/loongarch/kernel/signal.c | 21 - arch/loongarch/kernel/traps.c | 20 +- arch/loongarch/kvm/intc/ipi.c | 4 +- arch/loongarch/kvm/main.c | 4 +- arch/loongarch/kvm/vcpu.c | 8 + arch/loongarch/mm/hugetlbpage.c | 2 +- arch/loongarch/mm/init.c | 3 - arch/mips/crypto/Kconfig | 7 +- arch/mips/include/asm/mips-cm.h | 22 + arch/mips/kernel/mips-cm.c | 14 + arch/parisc/kernel/pdt.c | 2 + arch/powerpc/crypto/Kconfig | 7 +- arch/riscv/crypto/Kconfig | 1 - arch/riscv/include/asm/alternative-macros.h | 21 +- arch/riscv/include/asm/cacheflush.h | 15 +- arch/riscv/include/asm/ftrace.h | 2 +- arch/riscv/include/asm/ptrace.h | 18 +- arch/riscv/kernel/probes/uprobes.c | 10 +- arch/s390/Kconfig | 4 +- arch/s390/crypto/Kconfig | 3 +- arch/s390/include/asm/pci.h | 3 + arch/s390/kvm/intercept.c | 2 +- arch/s390/kvm/interrupt.c | 8 +- arch/s390/kvm/kvm-s390.c | 10 +- arch/s390/kvm/trace-s390.h | 4 +- arch/s390/pci/Makefile | 2 +- arch/s390/pci/pci_fixup.c | 23 + arch/um/include/linux/time-internal.h | 2 + arch/um/kernel/skas/syscall.c | 11 + arch/x86/crypto/Kconfig | 11 +- arch/x86/entry/entry.S | 2 +- arch/x86/events/core.c | 2 +- arch/x86/include/asm/intel-family.h | 2 + arch/x86/include/asm/pgalloc.h | 19 +- arch/x86/kernel/cpu/bugs.c | 36 +- arch/x86/kernel/i8253.c | 3 +- arch/x86/kernel/machine_kexec_32.c | 4 +- arch/x86/kvm/svm/avic.c | 60 +- arch/x86/kvm/vmx/posted_intr.c | 28 +- arch/x86/kvm/x86.c | 20 +- arch/x86/lib/x86-opcode-map.txt | 4 +- arch/x86/mm/pgtable.c | 4 +- arch/x86/mm/tlb.c | 6 +- arch/x86/pci/xen.c | 8 +- arch/x86/platform/efi/efi_64.c | 4 +- arch/x86/xen/enlighten_pvh.c | 19 +- block/bdev.c | 22 +- block/blk-cgroup.c | 2 +- block/blk-settings.c | 8 +- block/blk.h | 3 + block/fops.c | 2 +- crypto/Kconfig | 3 + crypto/crypto_null.c | 37 +- crypto/ecc.c | 2 +- crypto/ecdsa-p1363.c | 2 +- crypto/ecdsa-x962.c | 4 +- drivers/acpi/ec.c | 28 + drivers/acpi/pptt.c | 4 +- drivers/android/binder.c | 2 +- drivers/ata/libata-scsi.c | 25 +- drivers/base/base.h | 17 + drivers/base/bus.c | 2 +- drivers/base/core.c | 38 +- drivers/base/dd.c | 7 +- drivers/block/ublk_drv.c | 214 +++-- drivers/char/misc.c | 2 +- drivers/char/virtio_console.c | 7 +- drivers/clk/clk.c | 4 + drivers/clk/renesas/rzv2h-cpg.c | 12 +- drivers/comedi/drivers/jr3_pci.c | 2 +- drivers/cpufreq/Kconfig.arm | 20 +- drivers/cpufreq/apple-soc-cpufreq.c | 10 +- drivers/cpufreq/cppc_cpufreq.c | 2 +- drivers/cpufreq/scmi-cpufreq.c | 10 +- drivers/cpufreq/scpi-cpufreq.c | 13 +- drivers/cpufreq/sun50i-cpufreq-nvmem.c | 18 +- drivers/crypto/atmel-sha204a.c | 6 + drivers/crypto/ccp/sp-pci.c | 1 + drivers/cxl/core/regs.c | 4 - drivers/dma-buf/udmabuf.c | 2 +- drivers/dma/bcm2835-dma.c | 2 +- drivers/dma/dmatest.c | 6 +- drivers/firmware/stratix10-svc.c | 14 +- drivers/gpio/gpiolib-of.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 14 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 14 +- drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 19 +- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 8 +- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 12 +- drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 6 +- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c | 4 +- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/psp_v14_0.c | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_topology.c | 3 +- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 9 +- .../drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 2 +- drivers/gpu/drm/meson/meson_drv.c | 2 +- drivers/gpu/drm/meson/meson_drv.h | 2 +- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 29 +- drivers/gpu/drm/meson/meson_vclk.c | 195 ++--- drivers/gpu/drm/meson/meson_vclk.h | 13 +- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 4 +- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 4 + drivers/gpu/drm/xe/tests/xe_rtp_test.c | 2 +- drivers/gpu/drm/xe/xe_gt.c | 4 + drivers/gpu/drm/xe/xe_gt_debugfs.c | 11 + drivers/gpu/drm/xe/xe_gt_types.h | 10 + drivers/gpu/drm/xe/xe_hw_engine.c | 18 +- drivers/gpu/drm/xe/xe_reg_whitelist.c | 4 +- drivers/gpu/drm/xe/xe_rtp.c | 6 +- drivers/gpu/drm/xe/xe_rtp.h | 2 +- drivers/gpu/drm/xe/xe_tuning.c | 71 +- drivers/gpu/drm/xe/xe_tuning.h | 3 + drivers/gpu/drm/xe/xe_wa.c | 22 +- drivers/gpu/drm/xe/xe_wa_oob.rules | 2 + drivers/i3c/master/svc-i3c-master.c | 17 +- drivers/iio/adc/ad4695.c | 34 +- drivers/iio/adc/ad7768-1.c | 5 +- drivers/infiniband/hw/qib/qib_fs.c | 1 + drivers/iommu/amd/iommu.c | 2 +- .../iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 2 + drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + drivers/iommu/iommu.c | 3 + drivers/irqchip/irq-gic-v2m.c | 2 +- drivers/irqchip/irq-renesas-rzv2h.c | 91 +- drivers/mailbox/pcc.c | 15 +- drivers/mcb/mcb-parse.c | 2 +- drivers/md/raid1.c | 26 +- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/imx214.c | 934 ++++++++++----------- drivers/media/i2c/ov08x40.c | 78 +- drivers/misc/lkdtm/perms.c | 14 +- drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c | 8 +- drivers/misc/mei/hw-me-regs.h | 1 + drivers/misc/mei/pci-me.c | 1 + drivers/misc/mei/vsc-tp.c | 26 +- drivers/mmc/host/sdhci-msm.c | 2 +- drivers/net/dsa/mt7530.c | 6 +- drivers/net/ethernet/amd/pds_core/adminq.c | 36 +- drivers/net/ethernet/amd/pds_core/auxbus.c | 3 - drivers/net/ethernet/amd/pds_core/core.c | 9 +- drivers/net/ethernet/amd/pds_core/core.h | 4 +- drivers/net/ethernet/amd/pds_core/devlink.c | 4 +- drivers/net/ethernet/freescale/enetc/enetc.c | 45 +- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 24 +- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 +- .../net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c | 26 +- .../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 18 - drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 4 +- .../net/ethernet/stmicro/stmmac/dwmac1000_core.c | 2 +- .../net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 62 +- drivers/net/ethernet/sun/niu.c | 2 + drivers/net/phy/dp83822.c | 40 +- drivers/net/phy/microchip.c | 46 +- drivers/net/phy/phy_device.c | 53 +- drivers/net/phy/phy_led_triggers.c | 23 +- drivers/net/phy/phylink.c | 164 +++- drivers/net/virtio_net.c | 133 ++- drivers/net/vmxnet3/vmxnet3_xdp.c | 2 +- drivers/net/xen-netfront.c | 19 +- drivers/ntb/hw/amd/ntb_hw_amd.c | 1 + drivers/ntb/hw/idt/ntb_hw_idt.c | 18 +- drivers/nvme/host/core.c | 9 + drivers/nvme/host/multipath.c | 2 +- drivers/nvme/target/core.c | 3 + drivers/nvme/target/fc.c | 25 +- drivers/nvme/target/pci-epf.c | 14 +- drivers/of/resolver.c | 37 +- drivers/pci/msi/msi.c | 38 +- drivers/phy/rockchip/phy-rockchip-usbdp.c | 1 - drivers/pinctrl/pinctrl-mcp23s08.c | 23 +- drivers/pinctrl/renesas/pinctrl-rza2.c | 3 + drivers/platform/x86/x86-android-tablets/dmi.c | 14 +- drivers/platform/x86/x86-android-tablets/other.c | 160 ++-- .../x86/x86-android-tablets/x86-android-tablets.h | 3 +- drivers/pwm/core.c | 13 +- drivers/pwm/pwm-axi-pwmgen.c | 10 +- drivers/regulator/rk808-regulator.c | 4 +- drivers/rtc/rtc-pcf85063.c | 19 +- drivers/s390/char/sclp_con.c | 17 + drivers/s390/char/sclp_tty.c | 12 + drivers/s390/net/ism_drv.c | 1 - drivers/scsi/hisi_sas/hisi_sas_main.c | 20 + drivers/scsi/mpi3mr/mpi3mr_fw.c | 2 +- drivers/scsi/pm8001/pm8001_sas.c | 1 + drivers/scsi/scsi.c | 36 +- drivers/scsi/scsi_lib.c | 6 +- drivers/soc/qcom/ice.c | 48 ++ drivers/spi/spi-imx.c | 5 +- drivers/spi/spi-tegra210-quad.c | 6 +- .../staging/gpib/agilent_82350b/agilent_82350b.c | 10 +- drivers/thunderbolt/tb.c | 16 +- drivers/tty/serial/msm_serial.c | 6 + drivers/tty/serial/sifive.c | 6 + drivers/tty/vt/selection.c | 5 +- drivers/ufs/core/ufs-mcq.c | 12 +- drivers/ufs/core/ufshcd.c | 2 + drivers/ufs/host/ufs-exynos.c | 44 +- drivers/ufs/host/ufs-exynos.h | 1 + drivers/ufs/host/ufs-qcom.c | 2 +- drivers/usb/cdns3/cdns3-gadget.c | 2 + drivers/usb/chipidea/ci_hdrc_imx.c | 44 +- drivers/usb/class/cdc-wdm.c | 21 +- drivers/usb/core/quirks.c | 9 + drivers/usb/dwc3/dwc3-pci.c | 10 + drivers/usb/dwc3/dwc3-xilinx.c | 4 +- drivers/usb/dwc3/gadget.c | 28 +- drivers/usb/gadget/udc/aspeed-vhub/dev.c | 3 + drivers/usb/host/max3421-hcd.c | 7 + drivers/usb/host/ohci-pci.c | 23 + drivers/usb/host/xhci-hub.c | 30 +- drivers/usb/host/xhci-mvebu.c | 10 - drivers/usb/host/xhci-mvebu.h | 6 - drivers/usb/host/xhci-plat.c | 2 +- drivers/usb/host/xhci-ring.c | 75 +- drivers/usb/host/xhci.c | 4 +- drivers/usb/host/xhci.h | 4 +- drivers/usb/serial/ftdi_sio.c | 2 + drivers/usb/serial/ftdi_sio_ids.h | 5 + drivers/usb/serial/option.c | 3 + drivers/usb/serial/usb-serial-simple.c | 7 + drivers/usb/storage/unusual_uas.h | 7 + drivers/usb/typec/class.c | 24 +- drivers/usb/typec/class.h | 1 + drivers/usb/typec/ucsi/cros_ec_ucsi.c | 5 +- drivers/usb/typec/ucsi/ucsi.c | 19 +- drivers/usb/typec/ucsi/ucsi.h | 6 +- drivers/usb/typec/ucsi/ucsi_acpi.c | 5 +- drivers/usb/typec/ucsi/ucsi_ccg.c | 67 +- drivers/vhost/scsi.c | 80 +- drivers/virtio/virtio_pci_modern.c | 4 +- drivers/xen/Kconfig | 2 +- fs/btrfs/file.c | 9 +- fs/btrfs/zoned.c | 1 - fs/ceph/inode.c | 2 +- fs/ext4/block_validity.c | 5 +- fs/ext4/inode.c | 7 +- fs/iomap/buffered-io.c | 2 +- fs/namespace.c | 69 +- fs/netfs/main.c | 4 + fs/ntfs3/file.c | 20 +- fs/smb/client/sess.c | 60 +- fs/smb/client/smb1ops.c | 36 + fs/smb/server/vfs_cache.c | 8 +- fs/splice.c | 2 +- fs/xattr.c | 4 +- include/linux/blkdev.h | 4 - include/linux/energy_model.h | 12 +- include/linux/math.h | 12 + include/linux/msi.h | 3 +- include/linux/pci.h | 2 + include/linux/pci_ids.h | 1 + include/linux/phy.h | 4 + include/linux/phylink.h | 4 + include/net/netfilter/nft_fib.h | 21 + include/soc/qcom/ice.h | 2 + include/uapi/linux/virtio_pci.h | 1 + init/Kconfig | 2 +- io_uring/io_uring.c | 15 +- io_uring/refs.h | 7 + kernel/bpf/bpf_cgrp_storage.c | 11 +- kernel/bpf/hashtab.c | 6 +- kernel/bpf/preload/bpf_preload_kern.c | 1 + kernel/bpf/syscall.c | 6 +- kernel/bpf/verifier.c | 32 + kernel/cgroup/cgroup.c | 29 + kernel/cgroup/cpuset-internal.h | 1 + kernel/cgroup/cpuset.c | 14 + kernel/dma/contiguous.c | 3 +- kernel/events/core.c | 6 +- kernel/irq/msi.c | 2 +- kernel/panic.c | 6 + kernel/power/energy_model.c | 47 +- kernel/sched/ext.c | 4 +- kernel/sched/fair.c | 4 +- kernel/time/tick-common.c | 22 + kernel/trace/bpf_trace.c | 7 +- kernel/trace/trace.c | 10 + lib/Kconfig.ubsan | 1 - lib/crypto/Kconfig | 37 +- lib/test_ubsan.c | 18 +- mm/vmscan.c | 7 + net/9p/client.c | 30 +- net/9p/trans_fd.c | 17 +- net/core/lwtunnel.c | 26 +- net/core/selftests.c | 18 +- net/ipv4/netfilter/nft_fib_ipv4.c | 11 +- net/ipv6/netfilter/nft_fib_ipv6.c | 19 +- net/mptcp/pm_userspace.c | 6 +- net/sched/sch_hfsc.c | 23 +- net/tipc/monitor.c | 3 +- rust/Makefile | 8 +- rust/kernel/firmware.rs | 8 +- scripts/Makefile.lib | 2 +- scripts/Makefile.vmlinux | 4 + sound/soc/codecs/aw88081.c | 10 + sound/soc/codecs/wcd934x.c | 2 +- sound/soc/fsl/fsl_asrc_dma.c | 15 +- sound/virtio/virtio_pcm.c | 21 +- tools/arch/x86/lib/x86-opcode-map.txt | 4 +- tools/bpf/bpftool/prog.c | 1 + tools/objtool/check.c | 36 +- tools/testing/selftests/bpf/cap_helpers.c | 8 +- tools/testing/selftests/bpf/cap_helpers.h | 1 + tools/testing/selftests/bpf/network_helpers.c | 33 +- tools/testing/selftests/bpf/prog_tests/verifier.c | 4 +- tools/testing/selftests/bpf/test_loader.c | 6 +- tools/testing/selftests/mincore/mincore_selftest.c | 3 - tools/testing/selftests/pcie_bwctrl/Makefile | 3 +- tools/testing/selftests/ublk/test_stripe_04.sh | 24 + 329 files changed, 3712 insertions(+), 2060 deletions(-)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjiang Tu tujinjiang@huawei.com
[ Upstream commit 1b0449544c6482179ac84530b61fc192a6527bfd ]
Syzkaller reports a bug as follows:
Injecting memory failure for pfn 0x18b00e at process virtual address 0x20ffd000 Memory failure: 0x18b00e: dirty swapcache page still referenced by 2 users Memory failure: 0x18b00e: recovery action for dirty swapcache page: Failed page: refcount:2 mapcount:0 mapping:0000000000000000 index:0x20ffd pfn:0x18b00e memcg:ffff0000dd6d9000 anon flags: 0x5ffffe00482011(locked|dirty|arch_1|swapbacked|hwpoison|node=0|zone=2|lastcpupid=0xfffff) raw: 005ffffe00482011 dead000000000100 dead000000000122 ffff0000e232a7c9 raw: 0000000000020ffd 0000000000000000 00000002ffffffff ffff0000dd6d9000 page dumped because: VM_BUG_ON_FOLIO(!folio_test_uptodate(folio)) ------------[ cut here ]------------ kernel BUG at mm/swap_state.c:184! Internal error: Oops - BUG: 00000000f2000800 [#1] SMP Modules linked in: CPU: 0 PID: 60 Comm: kswapd0 Not tainted 6.6.0-gcb097e7de84e #3 Hardware name: linux,dummy-virt (DT) pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : add_to_swap+0xbc/0x158 lr : add_to_swap+0xbc/0x158 sp : ffff800087f37340 x29: ffff800087f37340 x28: fffffc00052c0380 x27: ffff800087f37780 x26: ffff800087f37490 x25: ffff800087f37c78 x24: ffff800087f377a0 x23: ffff800087f37c50 x22: 0000000000000000 x21: fffffc00052c03b4 x20: 0000000000000000 x19: fffffc00052c0380 x18: 0000000000000000 x17: 296f696c6f662865 x16: 7461646f7470755f x15: 747365745f6f696c x14: 6f6621284f494c4f x13: 0000000000000001 x12: ffff600036d8b97b x11: 1fffe00036d8b97a x10: ffff600036d8b97a x9 : dfff800000000000 x8 : 00009fffc9274686 x7 : ffff0001b6c5cbd3 x6 : 0000000000000001 x5 : ffff0000c25896c0 x4 : 0000000000000000 x3 : 0000000000000000 x2 : 0000000000000000 x1 : ffff0000c25896c0 x0 : 0000000000000000 Call trace: add_to_swap+0xbc/0x158 shrink_folio_list+0x12ac/0x2648 shrink_inactive_list+0x318/0x948 shrink_lruvec+0x450/0x720 shrink_node_memcgs+0x280/0x4a8 shrink_node+0x128/0x978 balance_pgdat+0x4f0/0xb20 kswapd+0x228/0x438 kthread+0x214/0x230 ret_from_fork+0x10/0x20
I can reproduce this issue with the following steps:
1) When a dirty swapcache page is isolated by reclaim process and the page isn't locked, inject memory failure for the page. me_swapcache_dirty() clears uptodate flag and tries to delete from lru, but fails. Reclaim process will put the hwpoisoned page back to lru.
2) The process that maps the hwpoisoned page exits, the page is deleted the page will never be freed and will be in the lru forever.
3) If we trigger a reclaim again and tries to reclaim the page, add_to_swap() will trigger VM_BUG_ON_FOLIO due to the uptodate flag is cleared.
To fix it, skip the hwpoisoned page in shrink_folio_list(). Besides, the hwpoison folio may not be unmapped by hwpoison_user_mappings() yet, unmap it in shrink_folio_list(), otherwise the folio will fail to be unmaped by hwpoison_user_mappings() since the folio isn't in lru list.
Link: https://lkml.kernel.org/r/20250318083939.987651-3-tujinjiang@huawei.com Signed-off-by: Jinjiang Tu tujinjiang@huawei.com Acked-by: Miaohe Lin linmiaohe@huawei.com Cc: David Hildenbrand david@redhat.com Cc: Kefeng Wang wangkefeng.wang@huawei.com Cc: Nanyong Sun sunnanyong@huawei.com Cc: Naoya Horiguchi nao.horiguchi@gmail.com Cc: <stable@vger,kernel.org> Signed-off-by: Andrew Morton akpm@linux-foundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- mm/vmscan.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/mm/vmscan.c b/mm/vmscan.c index fada3b35aff83..e9f3ae8158a66 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -1112,6 +1112,13 @@ static unsigned int shrink_folio_list(struct list_head *folio_list, if (!folio_trylock(folio)) goto keep;
+ if (folio_contain_hwpoisoned_page(folio)) { + unmap_poisoned_folio(folio, folio_pfn(folio), false); + folio_unlock(folio); + folio_put(folio); + continue; + } + VM_BUG_ON_FOLIO(folio_test_active(folio), folio);
nr_pages = folio_nr_pages(folio);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tudor Ambarus tudor.ambarus@linaro.org
[ Upstream commit 1c13d6060d612601a61423f2e8fbf9e48126acca ]
Callers of of_qcom_ice_get() leak the device reference taken by of_find_device_by_node(). Introduce devm variant for of_qcom_ice_get(). Existing consumers need the ICE instance for the entire life of their device, thus exporting qcom_ice_put() is not required.
Signed-off-by: Tudor Ambarus tudor.ambarus@linaro.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Abel Vesa abel.vesa@linaro.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/20250117-qcom-ice-fix-dev-leak-v2-1-1ffa5b6884cb@l... Signed-off-by: Bjorn Andersson andersson@kernel.org Stable-dep-of: cbef7442fba5 ("mmc: sdhci-msm: fix dev reference leaked through of_qcom_ice_get") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/soc/qcom/ice.c | 48 ++++++++++++++++++++++++++++++++++++++++++ include/soc/qcom/ice.h | 2 ++ 2 files changed, 50 insertions(+)
diff --git a/drivers/soc/qcom/ice.c b/drivers/soc/qcom/ice.c index 393d2d1d275f1..79e04bff3e331 100644 --- a/drivers/soc/qcom/ice.c +++ b/drivers/soc/qcom/ice.c @@ -11,6 +11,7 @@ #include <linux/cleanup.h> #include <linux/clk.h> #include <linux/delay.h> +#include <linux/device.h> #include <linux/iopoll.h> #include <linux/of.h> #include <linux/of_platform.h> @@ -324,6 +325,53 @@ struct qcom_ice *of_qcom_ice_get(struct device *dev) } EXPORT_SYMBOL_GPL(of_qcom_ice_get);
+static void qcom_ice_put(const struct qcom_ice *ice) +{ + struct platform_device *pdev = to_platform_device(ice->dev); + + if (!platform_get_resource_byname(pdev, IORESOURCE_MEM, "ice")) + platform_device_put(pdev); +} + +static void devm_of_qcom_ice_put(struct device *dev, void *res) +{ + qcom_ice_put(*(struct qcom_ice **)res); +} + +/** + * devm_of_qcom_ice_get() - Devres managed helper to get an ICE instance from + * a DT node. + * @dev: device pointer for the consumer device. + * + * This function will provide an ICE instance either by creating one for the + * consumer device if its DT node provides the 'ice' reg range and the 'ice' + * clock (for legacy DT style). On the other hand, if consumer provides a + * phandle via 'qcom,ice' property to an ICE DT, the ICE instance will already + * be created and so this function will return that instead. + * + * Return: ICE pointer on success, NULL if there is no ICE data provided by the + * consumer or ERR_PTR() on error. + */ +struct qcom_ice *devm_of_qcom_ice_get(struct device *dev) +{ + struct qcom_ice *ice, **dr; + + dr = devres_alloc(devm_of_qcom_ice_put, sizeof(*dr), GFP_KERNEL); + if (!dr) + return ERR_PTR(-ENOMEM); + + ice = of_qcom_ice_get(dev); + if (!IS_ERR_OR_NULL(ice)) { + *dr = ice; + devres_add(dev, dr); + } else { + devres_free(dr); + } + + return ice; +} +EXPORT_SYMBOL_GPL(devm_of_qcom_ice_get); + static int qcom_ice_probe(struct platform_device *pdev) { struct qcom_ice *engine; diff --git a/include/soc/qcom/ice.h b/include/soc/qcom/ice.h index 5870a94599a25..d5f6a228df659 100644 --- a/include/soc/qcom/ice.h +++ b/include/soc/qcom/ice.h @@ -34,4 +34,6 @@ int qcom_ice_program_key(struct qcom_ice *ice, int slot); int qcom_ice_evict_key(struct qcom_ice *ice, int slot); struct qcom_ice *of_qcom_ice_get(struct device *dev); +struct qcom_ice *devm_of_qcom_ice_get(struct device *dev); + #endif /* __QCOM_ICE_H__ */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tudor Ambarus tudor.ambarus@linaro.org
[ Upstream commit cbef7442fba510b7eb229dcc9f39d3dde4a159a4 ]
The driver leaks the device reference taken with of_find_device_by_node(). Fix the leak by using devm_of_qcom_ice_get().
Fixes: c7eed31e235c ("mmc: sdhci-msm: Switch to the new ICE API") Cc: stable@vger.kernel.org Signed-off-by: Tudor Ambarus tudor.ambarus@linaro.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Acked-by: Ulf Hansson ulf.hansson@linaro.org Reviewed-by: Abel Vesa abel.vesa@linaro.org Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/20250117-qcom-ice-fix-dev-leak-v2-2-1ffa5b6884cb@l... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mmc/host/sdhci-msm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index e3d39311fdc75..3fd898647237f 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c @@ -1873,7 +1873,7 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host, if (!(cqhci_readl(cq_host, CQHCI_CAP) & CQHCI_CAP_CS)) return 0;
- ice = of_qcom_ice_get(dev); + ice = devm_of_qcom_ice_get(dev); if (ice == ERR_PTR(-EOPNOTSUPP)) { dev_warn(dev, "Disabling inline encryption support\n"); ice = NULL;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li RongQing lirongqing@baidu.com
[ Upstream commit 1618f635bdf56f3ac158171114e9bf18db234cbf ]
The callback function of call_rcu() just calls kfree(), so use kfree_rcu() instead of call_rcu() + callback function.
Signed-off-by: Li RongQing lirongqing@baidu.com Reviewed-by: Lukasz Luba lukasz.luba@arm.com Link: https://patch.msgid.link/20250218082021.2766-1-lirongqing@baidu.com Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Stable-dep-of: 3ee7be9e10dd ("PM: EM: Address RCU-related sparse warnings") Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/power/energy_model.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-)
diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 3874f0e97651e..72655eff6fc52 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -161,14 +161,6 @@ static void em_debug_create_pd(struct device *dev) {} static void em_debug_remove_pd(struct device *dev) {} #endif
-static void em_destroy_table_rcu(struct rcu_head *rp) -{ - struct em_perf_table __rcu *table; - - table = container_of(rp, struct em_perf_table, rcu); - kfree(table); -} - static void em_release_table_kref(struct kref *kref) { struct em_perf_table __rcu *table; @@ -176,7 +168,7 @@ static void em_release_table_kref(struct kref *kref) /* It was the last owner of this table so we can free */ table = container_of(kref, struct em_perf_table, kref);
- call_rcu(&table->rcu, em_destroy_table_rcu); + kfree_rcu(table, rcu); }
/**
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rafael J. Wysocki rafael.j.wysocki@intel.com
[ Upstream commit 3ee7be9e10dd5f79448788b899591d4bd2bf0c19 ]
The usage of __rcu in the Energy Model code is quite inconsistent which causes the following sparse warnings to trigger:
kernel/power/energy_model.c:169:15: warning: incorrect type in assignment (different address spaces) kernel/power/energy_model.c:169:15: expected struct em_perf_table [noderef] __rcu *table kernel/power/energy_model.c:169:15: got struct em_perf_table * kernel/power/energy_model.c:171:9: warning: incorrect type in argument 1 (different address spaces) kernel/power/energy_model.c:171:9: expected struct callback_head *head kernel/power/energy_model.c:171:9: got struct callback_head [noderef] __rcu * kernel/power/energy_model.c:171:9: warning: cast removes address space '__rcu' of expression kernel/power/energy_model.c:182:19: warning: incorrect type in argument 1 (different address spaces) kernel/power/energy_model.c:182:19: expected struct kref *kref kernel/power/energy_model.c:182:19: got struct kref [noderef] __rcu * kernel/power/energy_model.c:200:15: warning: incorrect type in assignment (different address spaces) kernel/power/energy_model.c:200:15: expected struct em_perf_table [noderef] __rcu *table kernel/power/energy_model.c:200:15: got void *[assigned] _res kernel/power/energy_model.c:204:20: warning: incorrect type in argument 1 (different address spaces) kernel/power/energy_model.c:204:20: expected struct kref *kref kernel/power/energy_model.c:204:20: got struct kref [noderef] __rcu * kernel/power/energy_model.c:320:19: warning: incorrect type in argument 1 (different address spaces) kernel/power/energy_model.c:320:19: expected struct kref *kref kernel/power/energy_model.c:320:19: got struct kref [noderef] __rcu * kernel/power/energy_model.c:325:45: warning: incorrect type in argument 2 (different address spaces) kernel/power/energy_model.c:325:45: expected struct em_perf_state *table kernel/power/energy_model.c:325:45: got struct em_perf_state [noderef] __rcu * kernel/power/energy_model.c:425:45: warning: incorrect type in argument 3 (different address spaces) kernel/power/energy_model.c:425:45: expected struct em_perf_state *table kernel/power/energy_model.c:425:45: got struct em_perf_state [noderef] __rcu * kernel/power/energy_model.c:442:15: warning: incorrect type in argument 1 (different address spaces) kernel/power/energy_model.c:442:15: expected void const *objp kernel/power/energy_model.c:442:15: got struct em_perf_table [noderef] __rcu *[assigned] em_table kernel/power/energy_model.c:626:55: warning: incorrect type in argument 2 (different address spaces) kernel/power/energy_model.c:626:55: expected struct em_perf_state *table kernel/power/energy_model.c:626:55: got struct em_perf_state [noderef] __rcu * kernel/power/energy_model.c:681:16: warning: incorrect type in assignment (different address spaces) kernel/power/energy_model.c:681:16: expected struct em_perf_state *new_ps kernel/power/energy_model.c:681:16: got struct em_perf_state [noderef] __rcu * kernel/power/energy_model.c:699:37: warning: incorrect type in argument 2 (different address spaces) kernel/power/energy_model.c:699:37: expected struct em_perf_state *table kernel/power/energy_model.c:699:37: got struct em_perf_state [noderef] __rcu * kernel/power/energy_model.c:733:38: warning: incorrect type in argument 3 (different address spaces) kernel/power/energy_model.c:733:38: expected struct em_perf_state *table kernel/power/energy_model.c:733:38: got struct em_perf_state [noderef] __rcu * kernel/power/energy_model.c:855:53: warning: dereference of noderef expression kernel/power/energy_model.c:864:32: warning: dereference of noderef expression
This is because the __rcu annotation for sparse is only applicable to pointers that need rcu_dereference() or equivalent for protection, which basically means pointers assigned with rcu_assign_pointer().
Make all of the above sparse warnings go away by cleaning up the usage of __rcu and using rcu_dereference_protected() where applicable.
Cc: All applicable stable@vger.kernel.org Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Reviewed-by: Lukasz Luba lukasz.luba@arm.com Link: https://patch.msgid.link/5885405.DvuYhMxLoT@rjwysocki.net Signed-off-by: Sasha Levin sashal@kernel.org --- include/linux/energy_model.h | 12 +++++------ kernel/power/energy_model.c | 39 ++++++++++++++++++------------------ 2 files changed, 26 insertions(+), 25 deletions(-)
diff --git a/include/linux/energy_model.h b/include/linux/energy_model.h index 78318d49276dc..b3b8389e9480d 100644 --- a/include/linux/energy_model.h +++ b/include/linux/energy_model.h @@ -167,13 +167,13 @@ struct em_data_callback { struct em_perf_domain *em_cpu_get(int cpu); struct em_perf_domain *em_pd_get(struct device *dev); int em_dev_update_perf_domain(struct device *dev, - struct em_perf_table __rcu *new_table); + struct em_perf_table *new_table); int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *span, bool microwatts); void em_dev_unregister_perf_domain(struct device *dev); -struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd); -void em_table_free(struct em_perf_table __rcu *table); +struct em_perf_table *em_table_alloc(struct em_perf_domain *pd); +void em_table_free(struct em_perf_table *table); int em_dev_compute_costs(struct device *dev, struct em_perf_state *table, int nr_states); int em_dev_update_chip_binning(struct device *dev); @@ -373,14 +373,14 @@ static inline int em_pd_nr_perf_states(struct em_perf_domain *pd) return 0; } static inline -struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd) +struct em_perf_table *em_table_alloc(struct em_perf_domain *pd) { return NULL; } -static inline void em_table_free(struct em_perf_table __rcu *table) {} +static inline void em_table_free(struct em_perf_table *table) {} static inline int em_dev_update_perf_domain(struct device *dev, - struct em_perf_table __rcu *new_table) + struct em_perf_table *new_table) { return -EINVAL; } diff --git a/kernel/power/energy_model.c b/kernel/power/energy_model.c index 72655eff6fc52..76c4343796893 100644 --- a/kernel/power/energy_model.c +++ b/kernel/power/energy_model.c @@ -163,12 +163,8 @@ static void em_debug_remove_pd(struct device *dev) {}
static void em_release_table_kref(struct kref *kref) { - struct em_perf_table __rcu *table; - /* It was the last owner of this table so we can free */ - table = container_of(kref, struct em_perf_table, kref); - - kfree_rcu(table, rcu); + kfree_rcu(container_of(kref, struct em_perf_table, kref), rcu); }
/** @@ -177,7 +173,7 @@ static void em_release_table_kref(struct kref *kref) * * No return values. */ -void em_table_free(struct em_perf_table __rcu *table) +void em_table_free(struct em_perf_table *table) { kref_put(&table->kref, em_release_table_kref); } @@ -190,9 +186,9 @@ void em_table_free(struct em_perf_table __rcu *table) * has a user. * Returns allocated table or NULL. */ -struct em_perf_table __rcu *em_table_alloc(struct em_perf_domain *pd) +struct em_perf_table *em_table_alloc(struct em_perf_domain *pd) { - struct em_perf_table __rcu *table; + struct em_perf_table *table; int table_size;
table_size = sizeof(struct em_perf_state) * pd->nr_perf_states; @@ -300,9 +296,9 @@ int em_dev_compute_costs(struct device *dev, struct em_perf_state *table, * Return 0 on success or an error code on failure. */ int em_dev_update_perf_domain(struct device *dev, - struct em_perf_table __rcu *new_table) + struct em_perf_table *new_table) { - struct em_perf_table __rcu *old_table; + struct em_perf_table *old_table; struct em_perf_domain *pd;
if (!dev) @@ -319,7 +315,8 @@ int em_dev_update_perf_domain(struct device *dev,
kref_get(&new_table->kref);
- old_table = pd->em_table; + old_table = rcu_dereference_protected(pd->em_table, + lockdep_is_held(&em_pd_mutex)); rcu_assign_pointer(pd->em_table, new_table);
em_cpufreq_update_efficiencies(dev, new_table->state); @@ -391,7 +388,7 @@ static int em_create_pd(struct device *dev, int nr_states, struct em_data_callback *cb, cpumask_t *cpus, unsigned long flags) { - struct em_perf_table __rcu *em_table; + struct em_perf_table *em_table; struct em_perf_domain *pd; struct device *cpu_dev; int cpu, ret, num_cpus; @@ -551,6 +548,7 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, struct em_data_callback *cb, cpumask_t *cpus, bool microwatts) { + struct em_perf_table *em_table; unsigned long cap, prev_cap = 0; unsigned long flags = 0; int cpu, ret; @@ -623,7 +621,9 @@ int em_dev_register_perf_domain(struct device *dev, unsigned int nr_states, dev->em_pd->min_perf_state = 0; dev->em_pd->max_perf_state = nr_states - 1;
- em_cpufreq_update_efficiencies(dev, dev->em_pd->em_table->state); + em_table = rcu_dereference_protected(dev->em_pd->em_table, + lockdep_is_held(&em_pd_mutex)); + em_cpufreq_update_efficiencies(dev, em_table->state);
em_debug_create_pd(dev); dev_info(dev, "EM: created perf domain\n"); @@ -660,7 +660,8 @@ void em_dev_unregister_perf_domain(struct device *dev) mutex_lock(&em_pd_mutex); em_debug_remove_pd(dev);
- em_table_free(dev->em_pd->em_table); + em_table_free(rcu_dereference_protected(dev->em_pd->em_table, + lockdep_is_held(&em_pd_mutex)));
kfree(dev->em_pd); dev->em_pd = NULL; @@ -668,9 +669,9 @@ void em_dev_unregister_perf_domain(struct device *dev) } EXPORT_SYMBOL_GPL(em_dev_unregister_perf_domain);
-static struct em_perf_table __rcu *em_table_dup(struct em_perf_domain *pd) +static struct em_perf_table *em_table_dup(struct em_perf_domain *pd) { - struct em_perf_table __rcu *em_table; + struct em_perf_table *em_table; struct em_perf_state *ps, *new_ps; int ps_size;
@@ -692,7 +693,7 @@ static struct em_perf_table __rcu *em_table_dup(struct em_perf_domain *pd) }
static int em_recalc_and_update(struct device *dev, struct em_perf_domain *pd, - struct em_perf_table __rcu *em_table) + struct em_perf_table *em_table) { int ret;
@@ -723,7 +724,7 @@ static void em_adjust_new_capacity(struct device *dev, struct em_perf_domain *pd, u64 max_cap) { - struct em_perf_table __rcu *em_table; + struct em_perf_table *em_table;
em_table = em_table_dup(pd); if (!em_table) { @@ -814,7 +815,7 @@ static void em_update_workfn(struct work_struct *work) */ int em_dev_update_chip_binning(struct device *dev) { - struct em_perf_table __rcu *em_table; + struct em_perf_table *em_table; struct em_perf_domain *pd; int i, ret;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Apitzsch git@apitzsch.eu
[ Upstream commit b6832ff659f55f86198bb8de40f278a20bda0920 ]
Port the imx214 sensor driver to use the subdev active state.
Move all the format configuration to the subdevice state and simplify the format handling, locking and initialization.
While at it, simplify imx214_start_streaming() by removing unneeded goto statements and the corresponding error label.
Signed-off-by: André Apitzsch git@apitzsch.eu Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx214.c | 155 ++++++++++++------------------------- 1 file changed, 50 insertions(+), 105 deletions(-)
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 6a393e18267f4..af6a3859c3f13 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -59,8 +59,6 @@ struct imx214 {
struct v4l2_subdev sd; struct media_pad pad; - struct v4l2_mbus_framefmt fmt; - struct v4l2_rect crop;
struct v4l2_ctrl_handler ctrls; struct v4l2_ctrl *pixel_rate; @@ -71,12 +69,6 @@ struct imx214 { struct regulator_bulk_data supplies[IMX214_NUM_SUPPLIES];
struct gpio_desc *enable_gpio; - - /* - * Serialize control access, get/set format, get selection - * and start streaming. - */ - struct mutex mutex; };
struct reg_8 { @@ -490,6 +482,22 @@ static int __maybe_unused imx214_power_off(struct device *dev) return 0; }
+static void imx214_update_pad_format(struct imx214 *imx214, + const struct imx214_mode *mode, + struct v4l2_mbus_framefmt *fmt, u32 code) +{ + fmt->code = IMX214_MBUS_CODE; + fmt->width = mode->width; + fmt->height = mode->height; + fmt->field = V4L2_FIELD_NONE; + fmt->colorspace = V4L2_COLORSPACE_SRGB; + fmt->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(fmt->colorspace); + fmt->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, + fmt->colorspace, + fmt->ycbcr_enc); + fmt->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(fmt->colorspace); +} + static int imx214_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_mbus_code_enum *code) @@ -549,52 +557,6 @@ static const struct v4l2_subdev_core_ops imx214_core_ops = { #endif };
-static struct v4l2_mbus_framefmt * -__imx214_get_pad_format(struct imx214 *imx214, - struct v4l2_subdev_state *sd_state, - unsigned int pad, - enum v4l2_subdev_format_whence which) -{ - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_state_get_format(sd_state, pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &imx214->fmt; - default: - return NULL; - } -} - -static int imx214_get_format(struct v4l2_subdev *sd, - struct v4l2_subdev_state *sd_state, - struct v4l2_subdev_format *format) -{ - struct imx214 *imx214 = to_imx214(sd); - - mutex_lock(&imx214->mutex); - format->format = *__imx214_get_pad_format(imx214, sd_state, - format->pad, - format->which); - mutex_unlock(&imx214->mutex); - - return 0; -} - -static struct v4l2_rect * -__imx214_get_pad_crop(struct imx214 *imx214, - struct v4l2_subdev_state *sd_state, - unsigned int pad, enum v4l2_subdev_format_whence which) -{ - switch (which) { - case V4L2_SUBDEV_FORMAT_TRY: - return v4l2_subdev_state_get_crop(sd_state, pad); - case V4L2_SUBDEV_FORMAT_ACTIVE: - return &imx214->crop; - default: - return NULL; - } -} - static int imx214_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_format *format) @@ -604,34 +566,20 @@ static int imx214_set_format(struct v4l2_subdev *sd, struct v4l2_rect *__crop; const struct imx214_mode *mode;
- mutex_lock(&imx214->mutex); - - __crop = __imx214_get_pad_crop(imx214, sd_state, format->pad, - format->which); - mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes), width, height, format->format.width, format->format.height);
- __crop->width = mode->width; - __crop->height = mode->height; - - __format = __imx214_get_pad_format(imx214, sd_state, format->pad, - format->which); - __format->width = __crop->width; - __format->height = __crop->height; - __format->code = IMX214_MBUS_CODE; - __format->field = V4L2_FIELD_NONE; - __format->colorspace = V4L2_COLORSPACE_SRGB; - __format->ycbcr_enc = V4L2_MAP_YCBCR_ENC_DEFAULT(__format->colorspace); - __format->quantization = V4L2_MAP_QUANTIZATION_DEFAULT(true, - __format->colorspace, __format->ycbcr_enc); - __format->xfer_func = V4L2_MAP_XFER_FUNC_DEFAULT(__format->colorspace); + imx214_update_pad_format(imx214, mode, &format->format, + format->format.code); + __format = v4l2_subdev_state_get_format(sd_state, 0);
- format->format = *__format; + *__format = format->format;
- mutex_unlock(&imx214->mutex); + __crop = v4l2_subdev_state_get_crop(sd_state, 0); + __crop->width = mode->width; + __crop->height = mode->height;
return 0; } @@ -640,14 +588,9 @@ static int imx214_get_selection(struct v4l2_subdev *sd, struct v4l2_subdev_state *sd_state, struct v4l2_subdev_selection *sel) { - struct imx214 *imx214 = to_imx214(sd); - switch (sel->target) { case V4L2_SEL_TGT_CROP: - mutex_lock(&imx214->mutex); - sel->r = *__imx214_get_pad_crop(imx214, sd_state, sel->pad, - sel->which); - mutex_unlock(&imx214->mutex); + sel->r = *v4l2_subdev_state_get_crop(sd_state, 0); return 0;
case V4L2_SEL_TGT_NATIVE_SIZE: @@ -826,40 +769,35 @@ static int imx214_write_table(struct imx214 *imx214,
static int imx214_start_streaming(struct imx214 *imx214) { + const struct v4l2_mbus_framefmt *fmt; + struct v4l2_subdev_state *state; const struct imx214_mode *mode; int ret;
- mutex_lock(&imx214->mutex); ret = imx214_write_table(imx214, mode_table_common); if (ret < 0) { dev_err(imx214->dev, "could not sent common table %d\n", ret); - goto error; + return ret; }
- mode = v4l2_find_nearest_size(imx214_modes, - ARRAY_SIZE(imx214_modes), width, height, - imx214->fmt.width, imx214->fmt.height); + state = v4l2_subdev_get_locked_active_state(&imx214->sd); + fmt = v4l2_subdev_state_get_format(state, 0); + mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes), + width, height, fmt->width, fmt->height); ret = imx214_write_table(imx214, mode->reg_table); if (ret < 0) { dev_err(imx214->dev, "could not sent mode table %d\n", ret); - goto error; + return ret; } ret = __v4l2_ctrl_handler_setup(&imx214->ctrls); if (ret < 0) { dev_err(imx214->dev, "could not sync v4l2 controls\n"); - goto error; + return ret; } ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING); - if (ret < 0) { + if (ret < 0) dev_err(imx214->dev, "could not sent start table %d\n", ret); - goto error; - }
- mutex_unlock(&imx214->mutex); - return 0; - -error: - mutex_unlock(&imx214->mutex); return ret; }
@@ -877,6 +815,7 @@ static int imx214_stop_streaming(struct imx214 *imx214) static int imx214_s_stream(struct v4l2_subdev *subdev, int enable) { struct imx214 *imx214 = to_imx214(subdev); + struct v4l2_subdev_state *state; int ret;
if (enable) { @@ -884,7 +823,9 @@ static int imx214_s_stream(struct v4l2_subdev *subdev, int enable) if (ret < 0) return ret;
+ state = v4l2_subdev_lock_and_get_active_state(subdev); ret = imx214_start_streaming(imx214); + v4l2_subdev_unlock_state(state); if (ret < 0) goto err_rpm_put; } else { @@ -948,7 +889,7 @@ static const struct v4l2_subdev_pad_ops imx214_subdev_pad_ops = { .enum_mbus_code = imx214_enum_mbus_code, .enum_frame_size = imx214_enum_frame_size, .enum_frame_interval = imx214_enum_frame_interval, - .get_fmt = imx214_get_format, + .get_fmt = v4l2_subdev_get_fmt, .set_fmt = imx214_set_format, .get_selection = imx214_get_selection, .get_frame_interval = imx214_get_frame_interval, @@ -1079,9 +1020,6 @@ static int imx214_probe(struct i2c_client *client) if (ret < 0) goto error_power_off;
- mutex_init(&imx214->mutex); - imx214->ctrls.lock = &imx214->mutex; - imx214->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; imx214->pad.flags = MEDIA_PAD_FL_SOURCE; imx214->sd.dev = &client->dev; @@ -1093,7 +1031,12 @@ static int imx214_probe(struct i2c_client *client) goto free_ctrl; }
- imx214_entity_init_state(&imx214->sd, NULL); + imx214->sd.state_lock = imx214->ctrls.lock; + ret = v4l2_subdev_init_finalize(&imx214->sd); + if (ret < 0) { + dev_err(dev, "subdev init error: %d\n", ret); + goto free_entity; + }
pm_runtime_set_active(imx214->dev); pm_runtime_enable(imx214->dev); @@ -1101,20 +1044,22 @@ static int imx214_probe(struct i2c_client *client) ret = v4l2_async_register_subdev_sensor(&imx214->sd); if (ret < 0) { dev_err(dev, "could not register v4l2 device\n"); - goto free_entity; + goto error_subdev_cleanup; }
pm_runtime_idle(imx214->dev);
return 0;
-free_entity: +error_subdev_cleanup: pm_runtime_disable(imx214->dev); pm_runtime_set_suspended(&client->dev); + v4l2_subdev_cleanup(&imx214->sd); + +free_entity: media_entity_cleanup(&imx214->sd.entity);
free_ctrl: - mutex_destroy(&imx214->mutex); v4l2_ctrl_handler_free(&imx214->ctrls);
error_power_off: @@ -1129,9 +1074,9 @@ static void imx214_remove(struct i2c_client *client) struct imx214 *imx214 = to_imx214(sd);
v4l2_async_unregister_subdev(&imx214->sd); + v4l2_subdev_cleanup(sd); media_entity_cleanup(&imx214->sd.entity); v4l2_ctrl_handler_free(&imx214->ctrls); - mutex_destroy(&imx214->mutex); pm_runtime_disable(&client->dev); if (!pm_runtime_status_suspended(&client->dev)) { imx214_power_off(imx214->dev);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Apitzsch git@apitzsch.eu
[ Upstream commit 5d6dc133e6e4053b4b92a15a2e1b99d54b3f8adb ]
Error handling in probe() can be a bit simpler with dev_err_probe().
Acked-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: André Apitzsch git@apitzsch.eu Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx214.c | 54 +++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 30 deletions(-)
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index af6a3859c3f13..db6cdc3b65e37 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -933,14 +933,12 @@ static int imx214_parse_fwnode(struct device *dev) int ret;
endpoint = fwnode_graph_get_next_endpoint(dev_fwnode(dev), NULL); - if (!endpoint) { - dev_err(dev, "endpoint node not found\n"); - return -EINVAL; - } + if (!endpoint) + return dev_err_probe(dev, -EINVAL, "endpoint node not found\n");
ret = v4l2_fwnode_endpoint_alloc_parse(endpoint, &bus_cfg); if (ret) { - dev_err(dev, "parsing endpoint node failed\n"); + dev_err_probe(dev, ret, "parsing endpoint node failed\n"); goto done; }
@@ -949,8 +947,9 @@ static int imx214_parse_fwnode(struct device *dev) break;
if (i == bus_cfg.nr_of_link_frequencies) { - dev_err(dev, "link-frequencies %d not supported, Please review your DT\n", - IMX214_DEFAULT_LINK_FREQ); + dev_err_probe(dev, -EINVAL, + "link-frequencies %d not supported, Please review your DT\n", + IMX214_DEFAULT_LINK_FREQ); ret = -EINVAL; goto done; } @@ -978,34 +977,28 @@ static int imx214_probe(struct i2c_client *client) imx214->dev = dev;
imx214->xclk = devm_clk_get(dev, NULL); - if (IS_ERR(imx214->xclk)) { - dev_err(dev, "could not get xclk"); - return PTR_ERR(imx214->xclk); - } + if (IS_ERR(imx214->xclk)) + return dev_err_probe(dev, PTR_ERR(imx214->xclk), + "failed to get xclk\n");
ret = clk_set_rate(imx214->xclk, IMX214_DEFAULT_CLK_FREQ); - if (ret) { - dev_err(dev, "could not set xclk frequency\n"); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, + "failed to set xclk frequency\n");
ret = imx214_get_regulators(dev, imx214); - if (ret < 0) { - dev_err(dev, "cannot get regulators\n"); - return ret; - } + if (ret < 0) + return dev_err_probe(dev, ret, "failed to get regulators\n");
imx214->enable_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_LOW); - if (IS_ERR(imx214->enable_gpio)) { - dev_err(dev, "cannot get enable gpio\n"); - return PTR_ERR(imx214->enable_gpio); - } + if (IS_ERR(imx214->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(imx214->enable_gpio), + "failed to get enable gpio\n");
imx214->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config); - if (IS_ERR(imx214->regmap)) { - dev_err(dev, "regmap init failed\n"); - return PTR_ERR(imx214->regmap); - } + if (IS_ERR(imx214->regmap)) + return dev_err_probe(dev, PTR_ERR(imx214->regmap), + "regmap init failed\n");
v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops); imx214->sd.internal_ops = &imx214_internal_ops; @@ -1027,14 +1020,14 @@ static int imx214_probe(struct i2c_client *client)
ret = media_entity_pads_init(&imx214->sd.entity, 1, &imx214->pad); if (ret < 0) { - dev_err(dev, "could not register media entity\n"); + dev_err_probe(dev, ret, "failed to init entity pads\n"); goto free_ctrl; }
imx214->sd.state_lock = imx214->ctrls.lock; ret = v4l2_subdev_init_finalize(&imx214->sd); if (ret < 0) { - dev_err(dev, "subdev init error: %d\n", ret); + dev_err_probe(dev, ret, "subdev init error\n"); goto free_entity; }
@@ -1043,7 +1036,8 @@ static int imx214_probe(struct i2c_client *client)
ret = v4l2_async_register_subdev_sensor(&imx214->sd); if (ret < 0) { - dev_err(dev, "could not register v4l2 device\n"); + dev_err_probe(dev, ret, + "failed to register sensor sub-device\n"); goto error_subdev_cleanup; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Apitzsch git@apitzsch.eu
[ Upstream commit 4f0aeba4f1556f829f09073bf267093c5b6f1821 ]
Use the new common CCI register access helpers to replace the private register access helpers in the imx214 driver. This simplifies the driver by reducing the amount of code.
Acked-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: André Apitzsch git@apitzsch.eu Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/Kconfig | 1 + drivers/media/i2c/imx214.c | 672 +++++++++++++++++-------------------- 2 files changed, 310 insertions(+), 363 deletions(-)
diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index 8ba096b8ebca2..85ecb2aeefdbf 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -140,6 +140,7 @@ config VIDEO_IMX214 tristate "Sony IMX214 sensor support" depends on GPIOLIB select REGMAP_I2C + select V4L2_CCI_I2C help This is a Video4Linux2 sensor driver for the Sony IMX214 camera. diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index db6cdc3b65e37..20d1ebebf13af 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -15,11 +15,12 @@ #include <linux/regmap.h> #include <linux/regulator/consumer.h> #include <media/media-entity.h> +#include <media/v4l2-cci.h> #include <media/v4l2-ctrls.h> #include <media/v4l2-fwnode.h> #include <media/v4l2-subdev.h>
-#define IMX214_REG_MODE_SELECT 0x0100 +#define IMX214_REG_MODE_SELECT CCI_REG8(0x0100) #define IMX214_MODE_STANDBY 0x00 #define IMX214_MODE_STREAMING 0x01
@@ -30,7 +31,7 @@ #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
/* Exposure control */ -#define IMX214_REG_EXPOSURE 0x0202 +#define IMX214_REG_EXPOSURE CCI_REG16(0x0202) #define IMX214_EXPOSURE_MIN 0 #define IMX214_EXPOSURE_MAX 3184 #define IMX214_EXPOSURE_STEP 1 @@ -71,345 +72,324 @@ struct imx214 { struct gpio_desc *enable_gpio; };
-struct reg_8 { - u16 addr; - u8 val; -}; - -enum { - IMX214_TABLE_WAIT_MS = 0, - IMX214_TABLE_END, - IMX214_MAX_RETRIES, - IMX214_WAIT_MS -}; - /*From imx214_mode_tbls.h*/ -static const struct reg_8 mode_4096x2304[] = { - {0x0114, 0x03}, - {0x0220, 0x00}, - {0x0221, 0x11}, - {0x0222, 0x01}, - {0x0340, 0x0C}, - {0x0341, 0x7A}, - {0x0342, 0x13}, - {0x0343, 0x90}, - {0x0344, 0x00}, - {0x0345, 0x38}, - {0x0346, 0x01}, - {0x0347, 0x98}, - {0x0348, 0x10}, - {0x0349, 0x37}, - {0x034A, 0x0A}, - {0x034B, 0x97}, - {0x0381, 0x01}, - {0x0383, 0x01}, - {0x0385, 0x01}, - {0x0387, 0x01}, - {0x0900, 0x00}, - {0x0901, 0x00}, - {0x0902, 0x00}, - {0x3000, 0x35}, - {0x3054, 0x01}, - {0x305C, 0x11}, - - {0x0112, 0x0A}, - {0x0113, 0x0A}, - {0x034C, 0x10}, - {0x034D, 0x00}, - {0x034E, 0x09}, - {0x034F, 0x00}, - {0x0401, 0x00}, - {0x0404, 0x00}, - {0x0405, 0x10}, - {0x0408, 0x00}, - {0x0409, 0x00}, - {0x040A, 0x00}, - {0x040B, 0x00}, - {0x040C, 0x10}, - {0x040D, 0x00}, - {0x040E, 0x09}, - {0x040F, 0x00}, - - {0x0301, 0x05}, - {0x0303, 0x02}, - {0x0305, 0x03}, - {0x0306, 0x00}, - {0x0307, 0x96}, - {0x0309, 0x0A}, - {0x030B, 0x01}, - {0x0310, 0x00}, - - {0x0820, 0x12}, - {0x0821, 0xC0}, - {0x0822, 0x00}, - {0x0823, 0x00}, - - {0x3A03, 0x09}, - {0x3A04, 0x50}, - {0x3A05, 0x01}, - - {0x0B06, 0x01}, - {0x30A2, 0x00}, - - {0x30B4, 0x00}, - - {0x3A02, 0xFF}, - - {0x3011, 0x00}, - {0x3013, 0x01}, - - {0x0202, 0x0C}, - {0x0203, 0x70}, - {0x0224, 0x01}, - {0x0225, 0xF4}, - - {0x0204, 0x00}, - {0x0205, 0x00}, - {0x020E, 0x01}, - {0x020F, 0x00}, - {0x0210, 0x01}, - {0x0211, 0x00}, - {0x0212, 0x01}, - {0x0213, 0x00}, - {0x0214, 0x01}, - {0x0215, 0x00}, - {0x0216, 0x00}, - {0x0217, 0x00}, - - {0x4170, 0x00}, - {0x4171, 0x10}, - {0x4176, 0x00}, - {0x4177, 0x3C}, - {0xAE20, 0x04}, - {0xAE21, 0x5C}, - - {IMX214_TABLE_WAIT_MS, 10}, - {0x0138, 0x01}, - {IMX214_TABLE_END, 0x00} +static const struct cci_reg_sequence mode_4096x2304[] = { + { CCI_REG8(0x0114), 0x03 }, + { CCI_REG8(0x0220), 0x00 }, + { CCI_REG8(0x0221), 0x11 }, + { CCI_REG8(0x0222), 0x01 }, + { CCI_REG8(0x0340), 0x0C }, + { CCI_REG8(0x0341), 0x7A }, + { CCI_REG8(0x0342), 0x13 }, + { CCI_REG8(0x0343), 0x90 }, + { CCI_REG8(0x0344), 0x00 }, + { CCI_REG8(0x0345), 0x38 }, + { CCI_REG8(0x0346), 0x01 }, + { CCI_REG8(0x0347), 0x98 }, + { CCI_REG8(0x0348), 0x10 }, + { CCI_REG8(0x0349), 0x37 }, + { CCI_REG8(0x034A), 0x0A }, + { CCI_REG8(0x034B), 0x97 }, + { CCI_REG8(0x0381), 0x01 }, + { CCI_REG8(0x0383), 0x01 }, + { CCI_REG8(0x0385), 0x01 }, + { CCI_REG8(0x0387), 0x01 }, + { CCI_REG8(0x0900), 0x00 }, + { CCI_REG8(0x0901), 0x00 }, + { CCI_REG8(0x0902), 0x00 }, + { CCI_REG8(0x3000), 0x35 }, + { CCI_REG8(0x3054), 0x01 }, + { CCI_REG8(0x305C), 0x11 }, + + { CCI_REG8(0x0112), 0x0A }, + { CCI_REG8(0x0113), 0x0A }, + { CCI_REG8(0x034C), 0x10 }, + { CCI_REG8(0x034D), 0x00 }, + { CCI_REG8(0x034E), 0x09 }, + { CCI_REG8(0x034F), 0x00 }, + { CCI_REG8(0x0401), 0x00 }, + { CCI_REG8(0x0404), 0x00 }, + { CCI_REG8(0x0405), 0x10 }, + { CCI_REG8(0x0408), 0x00 }, + { CCI_REG8(0x0409), 0x00 }, + { CCI_REG8(0x040A), 0x00 }, + { CCI_REG8(0x040B), 0x00 }, + { CCI_REG8(0x040C), 0x10 }, + { CCI_REG8(0x040D), 0x00 }, + { CCI_REG8(0x040E), 0x09 }, + { CCI_REG8(0x040F), 0x00 }, + + { CCI_REG8(0x0301), 0x05 }, + { CCI_REG8(0x0303), 0x02 }, + { CCI_REG8(0x0305), 0x03 }, + { CCI_REG8(0x0306), 0x00 }, + { CCI_REG8(0x0307), 0x96 }, + { CCI_REG8(0x0309), 0x0A }, + { CCI_REG8(0x030B), 0x01 }, + { CCI_REG8(0x0310), 0x00 }, + + { CCI_REG8(0x0820), 0x12 }, + { CCI_REG8(0x0821), 0xC0 }, + { CCI_REG8(0x0822), 0x00 }, + { CCI_REG8(0x0823), 0x00 }, + + { CCI_REG8(0x3A03), 0x09 }, + { CCI_REG8(0x3A04), 0x50 }, + { CCI_REG8(0x3A05), 0x01 }, + + { CCI_REG8(0x0B06), 0x01 }, + { CCI_REG8(0x30A2), 0x00 }, + + { CCI_REG8(0x30B4), 0x00 }, + + { CCI_REG8(0x3A02), 0xFF }, + + { CCI_REG8(0x3011), 0x00 }, + { CCI_REG8(0x3013), 0x01 }, + + { CCI_REG8(0x0202), 0x0C }, + { CCI_REG8(0x0203), 0x70 }, + { CCI_REG8(0x0224), 0x01 }, + { CCI_REG8(0x0225), 0xF4 }, + + { CCI_REG8(0x0204), 0x00 }, + { CCI_REG8(0x0205), 0x00 }, + { CCI_REG8(0x020E), 0x01 }, + { CCI_REG8(0x020F), 0x00 }, + { CCI_REG8(0x0210), 0x01 }, + { CCI_REG8(0x0211), 0x00 }, + { CCI_REG8(0x0212), 0x01 }, + { CCI_REG8(0x0213), 0x00 }, + { CCI_REG8(0x0214), 0x01 }, + { CCI_REG8(0x0215), 0x00 }, + { CCI_REG8(0x0216), 0x00 }, + { CCI_REG8(0x0217), 0x00 }, + + { CCI_REG8(0x4170), 0x00 }, + { CCI_REG8(0x4171), 0x10 }, + { CCI_REG8(0x4176), 0x00 }, + { CCI_REG8(0x4177), 0x3C }, + { CCI_REG8(0xAE20), 0x04 }, + { CCI_REG8(0xAE21), 0x5C }, };
-static const struct reg_8 mode_1920x1080[] = { - {0x0114, 0x03}, - {0x0220, 0x00}, - {0x0221, 0x11}, - {0x0222, 0x01}, - {0x0340, 0x0C}, - {0x0341, 0x7A}, - {0x0342, 0x13}, - {0x0343, 0x90}, - {0x0344, 0x04}, - {0x0345, 0x78}, - {0x0346, 0x03}, - {0x0347, 0xFC}, - {0x0348, 0x0B}, - {0x0349, 0xF7}, - {0x034A, 0x08}, - {0x034B, 0x33}, - {0x0381, 0x01}, - {0x0383, 0x01}, - {0x0385, 0x01}, - {0x0387, 0x01}, - {0x0900, 0x00}, - {0x0901, 0x00}, - {0x0902, 0x00}, - {0x3000, 0x35}, - {0x3054, 0x01}, - {0x305C, 0x11}, - - {0x0112, 0x0A}, - {0x0113, 0x0A}, - {0x034C, 0x07}, - {0x034D, 0x80}, - {0x034E, 0x04}, - {0x034F, 0x38}, - {0x0401, 0x00}, - {0x0404, 0x00}, - {0x0405, 0x10}, - {0x0408, 0x00}, - {0x0409, 0x00}, - {0x040A, 0x00}, - {0x040B, 0x00}, - {0x040C, 0x07}, - {0x040D, 0x80}, - {0x040E, 0x04}, - {0x040F, 0x38}, - - {0x0301, 0x05}, - {0x0303, 0x02}, - {0x0305, 0x03}, - {0x0306, 0x00}, - {0x0307, 0x96}, - {0x0309, 0x0A}, - {0x030B, 0x01}, - {0x0310, 0x00}, - - {0x0820, 0x12}, - {0x0821, 0xC0}, - {0x0822, 0x00}, - {0x0823, 0x00}, - - {0x3A03, 0x04}, - {0x3A04, 0xF8}, - {0x3A05, 0x02}, - - {0x0B06, 0x01}, - {0x30A2, 0x00}, - - {0x30B4, 0x00}, - - {0x3A02, 0xFF}, - - {0x3011, 0x00}, - {0x3013, 0x01}, - - {0x0202, 0x0C}, - {0x0203, 0x70}, - {0x0224, 0x01}, - {0x0225, 0xF4}, - - {0x0204, 0x00}, - {0x0205, 0x00}, - {0x020E, 0x01}, - {0x020F, 0x00}, - {0x0210, 0x01}, - {0x0211, 0x00}, - {0x0212, 0x01}, - {0x0213, 0x00}, - {0x0214, 0x01}, - {0x0215, 0x00}, - {0x0216, 0x00}, - {0x0217, 0x00}, - - {0x4170, 0x00}, - {0x4171, 0x10}, - {0x4176, 0x00}, - {0x4177, 0x3C}, - {0xAE20, 0x04}, - {0xAE21, 0x5C}, - - {IMX214_TABLE_WAIT_MS, 10}, - {0x0138, 0x01}, - {IMX214_TABLE_END, 0x00} +static const struct cci_reg_sequence mode_1920x1080[] = { + { CCI_REG8(0x0114), 0x03 }, + { CCI_REG8(0x0220), 0x00 }, + { CCI_REG8(0x0221), 0x11 }, + { CCI_REG8(0x0222), 0x01 }, + { CCI_REG8(0x0340), 0x0C }, + { CCI_REG8(0x0341), 0x7A }, + { CCI_REG8(0x0342), 0x13 }, + { CCI_REG8(0x0343), 0x90 }, + { CCI_REG8(0x0344), 0x04 }, + { CCI_REG8(0x0345), 0x78 }, + { CCI_REG8(0x0346), 0x03 }, + { CCI_REG8(0x0347), 0xFC }, + { CCI_REG8(0x0348), 0x0B }, + { CCI_REG8(0x0349), 0xF7 }, + { CCI_REG8(0x034A), 0x08 }, + { CCI_REG8(0x034B), 0x33 }, + { CCI_REG8(0x0381), 0x01 }, + { CCI_REG8(0x0383), 0x01 }, + { CCI_REG8(0x0385), 0x01 }, + { CCI_REG8(0x0387), 0x01 }, + { CCI_REG8(0x0900), 0x00 }, + { CCI_REG8(0x0901), 0x00 }, + { CCI_REG8(0x0902), 0x00 }, + { CCI_REG8(0x3000), 0x35 }, + { CCI_REG8(0x3054), 0x01 }, + { CCI_REG8(0x305C), 0x11 }, + + { CCI_REG8(0x0112), 0x0A }, + { CCI_REG8(0x0113), 0x0A }, + { CCI_REG8(0x034C), 0x07 }, + { CCI_REG8(0x034D), 0x80 }, + { CCI_REG8(0x034E), 0x04 }, + { CCI_REG8(0x034F), 0x38 }, + { CCI_REG8(0x0401), 0x00 }, + { CCI_REG8(0x0404), 0x00 }, + { CCI_REG8(0x0405), 0x10 }, + { CCI_REG8(0x0408), 0x00 }, + { CCI_REG8(0x0409), 0x00 }, + { CCI_REG8(0x040A), 0x00 }, + { CCI_REG8(0x040B), 0x00 }, + { CCI_REG8(0x040C), 0x07 }, + { CCI_REG8(0x040D), 0x80 }, + { CCI_REG8(0x040E), 0x04 }, + { CCI_REG8(0x040F), 0x38 }, + + { CCI_REG8(0x0301), 0x05 }, + { CCI_REG8(0x0303), 0x02 }, + { CCI_REG8(0x0305), 0x03 }, + { CCI_REG8(0x0306), 0x00 }, + { CCI_REG8(0x0307), 0x96 }, + { CCI_REG8(0x0309), 0x0A }, + { CCI_REG8(0x030B), 0x01 }, + { CCI_REG8(0x0310), 0x00 }, + + { CCI_REG8(0x0820), 0x12 }, + { CCI_REG8(0x0821), 0xC0 }, + { CCI_REG8(0x0822), 0x00 }, + { CCI_REG8(0x0823), 0x00 }, + + { CCI_REG8(0x3A03), 0x04 }, + { CCI_REG8(0x3A04), 0xF8 }, + { CCI_REG8(0x3A05), 0x02 }, + + { CCI_REG8(0x0B06), 0x01 }, + { CCI_REG8(0x30A2), 0x00 }, + + { CCI_REG8(0x30B4), 0x00 }, + + { CCI_REG8(0x3A02), 0xFF }, + + { CCI_REG8(0x3011), 0x00 }, + { CCI_REG8(0x3013), 0x01 }, + + { CCI_REG8(0x0202), 0x0C }, + { CCI_REG8(0x0203), 0x70 }, + { CCI_REG8(0x0224), 0x01 }, + { CCI_REG8(0x0225), 0xF4 }, + + { CCI_REG8(0x0204), 0x00 }, + { CCI_REG8(0x0205), 0x00 }, + { CCI_REG8(0x020E), 0x01 }, + { CCI_REG8(0x020F), 0x00 }, + { CCI_REG8(0x0210), 0x01 }, + { CCI_REG8(0x0211), 0x00 }, + { CCI_REG8(0x0212), 0x01 }, + { CCI_REG8(0x0213), 0x00 }, + { CCI_REG8(0x0214), 0x01 }, + { CCI_REG8(0x0215), 0x00 }, + { CCI_REG8(0x0216), 0x00 }, + { CCI_REG8(0x0217), 0x00 }, + + { CCI_REG8(0x4170), 0x00 }, + { CCI_REG8(0x4171), 0x10 }, + { CCI_REG8(0x4176), 0x00 }, + { CCI_REG8(0x4177), 0x3C }, + { CCI_REG8(0xAE20), 0x04 }, + { CCI_REG8(0xAE21), 0x5C }, };
-static const struct reg_8 mode_table_common[] = { +static const struct cci_reg_sequence mode_table_common[] = { /* software reset */
/* software standby settings */ - {0x0100, 0x00}, + { CCI_REG8(0x0100), 0x00 },
/* ATR setting */ - {0x9300, 0x02}, + { CCI_REG8(0x9300), 0x02 },
/* external clock setting */ - {0x0136, 0x18}, - {0x0137, 0x00}, + { CCI_REG8(0x0136), 0x18 }, + { CCI_REG8(0x0137), 0x00 },
/* global setting */ /* basic config */ - {0x0101, 0x00}, - {0x0105, 0x01}, - {0x0106, 0x01}, - {0x4550, 0x02}, - {0x4601, 0x00}, - {0x4642, 0x05}, - {0x6227, 0x11}, - {0x6276, 0x00}, - {0x900E, 0x06}, - {0xA802, 0x90}, - {0xA803, 0x11}, - {0xA804, 0x62}, - {0xA805, 0x77}, - {0xA806, 0xAE}, - {0xA807, 0x34}, - {0xA808, 0xAE}, - {0xA809, 0x35}, - {0xA80A, 0x62}, - {0xA80B, 0x83}, - {0xAE33, 0x00}, + { CCI_REG8(0x0101), 0x00 }, + { CCI_REG8(0x0105), 0x01 }, + { CCI_REG8(0x0106), 0x01 }, + { CCI_REG8(0x4550), 0x02 }, + { CCI_REG8(0x4601), 0x00 }, + { CCI_REG8(0x4642), 0x05 }, + { CCI_REG8(0x6227), 0x11 }, + { CCI_REG8(0x6276), 0x00 }, + { CCI_REG8(0x900E), 0x06 }, + { CCI_REG8(0xA802), 0x90 }, + { CCI_REG8(0xA803), 0x11 }, + { CCI_REG8(0xA804), 0x62 }, + { CCI_REG8(0xA805), 0x77 }, + { CCI_REG8(0xA806), 0xAE }, + { CCI_REG8(0xA807), 0x34 }, + { CCI_REG8(0xA808), 0xAE }, + { CCI_REG8(0xA809), 0x35 }, + { CCI_REG8(0xA80A), 0x62 }, + { CCI_REG8(0xA80B), 0x83 }, + { CCI_REG8(0xAE33), 0x00 },
/* analog setting */ - {0x4174, 0x00}, - {0x4175, 0x11}, - {0x4612, 0x29}, - {0x461B, 0x12}, - {0x461F, 0x06}, - {0x4635, 0x07}, - {0x4637, 0x30}, - {0x463F, 0x18}, - {0x4641, 0x0D}, - {0x465B, 0x12}, - {0x465F, 0x11}, - {0x4663, 0x11}, - {0x4667, 0x0F}, - {0x466F, 0x0F}, - {0x470E, 0x09}, - {0x4909, 0xAB}, - {0x490B, 0x95}, - {0x4915, 0x5D}, - {0x4A5F, 0xFF}, - {0x4A61, 0xFF}, - {0x4A73, 0x62}, - {0x4A85, 0x00}, - {0x4A87, 0xFF}, + { CCI_REG8(0x4174), 0x00 }, + { CCI_REG8(0x4175), 0x11 }, + { CCI_REG8(0x4612), 0x29 }, + { CCI_REG8(0x461B), 0x12 }, + { CCI_REG8(0x461F), 0x06 }, + { CCI_REG8(0x4635), 0x07 }, + { CCI_REG8(0x4637), 0x30 }, + { CCI_REG8(0x463F), 0x18 }, + { CCI_REG8(0x4641), 0x0D }, + { CCI_REG8(0x465B), 0x12 }, + { CCI_REG8(0x465F), 0x11 }, + { CCI_REG8(0x4663), 0x11 }, + { CCI_REG8(0x4667), 0x0F }, + { CCI_REG8(0x466F), 0x0F }, + { CCI_REG8(0x470E), 0x09 }, + { CCI_REG8(0x4909), 0xAB }, + { CCI_REG8(0x490B), 0x95 }, + { CCI_REG8(0x4915), 0x5D }, + { CCI_REG8(0x4A5F), 0xFF }, + { CCI_REG8(0x4A61), 0xFF }, + { CCI_REG8(0x4A73), 0x62 }, + { CCI_REG8(0x4A85), 0x00 }, + { CCI_REG8(0x4A87), 0xFF },
/* embedded data */ - {0x5041, 0x04}, - {0x583C, 0x04}, - {0x620E, 0x04}, - {0x6EB2, 0x01}, - {0x6EB3, 0x00}, - {0x9300, 0x02}, + { CCI_REG8(0x5041), 0x04 }, + { CCI_REG8(0x583C), 0x04 }, + { CCI_REG8(0x620E), 0x04 }, + { CCI_REG8(0x6EB2), 0x01 }, + { CCI_REG8(0x6EB3), 0x00 }, + { CCI_REG8(0x9300), 0x02 },
/* imagequality */ /* HDR setting */ - {0x3001, 0x07}, - {0x6D12, 0x3F}, - {0x6D13, 0xFF}, - {0x9344, 0x03}, - {0x9706, 0x10}, - {0x9707, 0x03}, - {0x9708, 0x03}, - {0x9E04, 0x01}, - {0x9E05, 0x00}, - {0x9E0C, 0x01}, - {0x9E0D, 0x02}, - {0x9E24, 0x00}, - {0x9E25, 0x8C}, - {0x9E26, 0x00}, - {0x9E27, 0x94}, - {0x9E28, 0x00}, - {0x9E29, 0x96}, + { CCI_REG8(0x3001), 0x07 }, + { CCI_REG8(0x6D12), 0x3F }, + { CCI_REG8(0x6D13), 0xFF }, + { CCI_REG8(0x9344), 0x03 }, + { CCI_REG8(0x9706), 0x10 }, + { CCI_REG8(0x9707), 0x03 }, + { CCI_REG8(0x9708), 0x03 }, + { CCI_REG8(0x9E04), 0x01 }, + { CCI_REG8(0x9E05), 0x00 }, + { CCI_REG8(0x9E0C), 0x01 }, + { CCI_REG8(0x9E0D), 0x02 }, + { CCI_REG8(0x9E24), 0x00 }, + { CCI_REG8(0x9E25), 0x8C }, + { CCI_REG8(0x9E26), 0x00 }, + { CCI_REG8(0x9E27), 0x94 }, + { CCI_REG8(0x9E28), 0x00 }, + { CCI_REG8(0x9E29), 0x96 },
/* CNR parameter setting */ - {0x69DB, 0x01}, + { CCI_REG8(0x69DB), 0x01 },
/* Moire reduction */ - {0x6957, 0x01}, + { CCI_REG8(0x6957), 0x01 },
/* image enhancement */ - {0x6987, 0x17}, - {0x698A, 0x03}, - {0x698B, 0x03}, + { CCI_REG8(0x6987), 0x17 }, + { CCI_REG8(0x698A), 0x03 }, + { CCI_REG8(0x698B), 0x03 },
/* white balanace */ - {0x0B8E, 0x01}, - {0x0B8F, 0x00}, - {0x0B90, 0x01}, - {0x0B91, 0x00}, - {0x0B92, 0x01}, - {0x0B93, 0x00}, - {0x0B94, 0x01}, - {0x0B95, 0x00}, + { CCI_REG8(0x0B8E), 0x01 }, + { CCI_REG8(0x0B8F), 0x00 }, + { CCI_REG8(0x0B90), 0x01 }, + { CCI_REG8(0x0B91), 0x00 }, + { CCI_REG8(0x0B92), 0x01 }, + { CCI_REG8(0x0B93), 0x00 }, + { CCI_REG8(0x0B94), 0x01 }, + { CCI_REG8(0x0B95), 0x00 },
/* ATR setting */ - {0x6E50, 0x00}, - {0x6E51, 0x32}, - {0x9340, 0x00}, - {0x9341, 0x3C}, - {0x9342, 0x03}, - {0x9343, 0xFF}, - {IMX214_TABLE_END, 0x00} + { CCI_REG8(0x6E50), 0x00 }, + { CCI_REG8(0x6E51), 0x32 }, + { CCI_REG8(0x9340), 0x00 }, + { CCI_REG8(0x9341), 0x3C }, + { CCI_REG8(0x9342), 0x03 }, + { CCI_REG8(0x9343), 0xFF }, };
/* @@ -419,16 +399,19 @@ static const struct reg_8 mode_table_common[] = { static const struct imx214_mode { u32 width; u32 height; - const struct reg_8 *reg_table; + unsigned int num_of_regs; + const struct cci_reg_sequence *reg_table; } imx214_modes[] = { { .width = 4096, .height = 2304, + .num_of_regs = ARRAY_SIZE(mode_4096x2304), .reg_table = mode_4096x2304, }, { .width = 1920, .height = 1080, + .num_of_regs = ARRAY_SIZE(mode_1920x1080), .reg_table = mode_1920x1080, }, }; @@ -630,7 +613,6 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl) { struct imx214 *imx214 = container_of(ctrl->handler, struct imx214, ctrls); - u8 vals[2]; int ret;
/* @@ -642,12 +624,7 @@ static int imx214_set_ctrl(struct v4l2_ctrl *ctrl)
switch (ctrl->id) { case V4L2_CID_EXPOSURE: - vals[1] = ctrl->val; - vals[0] = ctrl->val >> 8; - ret = regmap_bulk_write(imx214->regmap, IMX214_REG_EXPOSURE, vals, 2); - if (ret < 0) - dev_err(imx214->dev, "Error %d\n", ret); - ret = 0; + cci_write(imx214->regmap, IMX214_REG_EXPOSURE, ctrl->val, &ret); break;
default: @@ -733,40 +710,6 @@ static int imx214_ctrls_init(struct imx214 *imx214) return 0; };
-#define MAX_CMD 4 -static int imx214_write_table(struct imx214 *imx214, - const struct reg_8 table[]) -{ - u8 vals[MAX_CMD]; - int i; - int ret; - - for (; table->addr != IMX214_TABLE_END ; table++) { - if (table->addr == IMX214_TABLE_WAIT_MS) { - usleep_range(table->val * 1000, - table->val * 1000 + 500); - continue; - } - - for (i = 0; i < MAX_CMD; i++) { - if (table[i].addr != (table[0].addr + i)) - break; - vals[i] = table[i].val; - } - - ret = regmap_bulk_write(imx214->regmap, table->addr, vals, i); - - if (ret) { - dev_err(imx214->dev, "write_table error: %d\n", ret); - return ret; - } - - table += i - 1; - } - - return 0; -} - static int imx214_start_streaming(struct imx214 *imx214) { const struct v4l2_mbus_framefmt *fmt; @@ -774,7 +717,8 @@ static int imx214_start_streaming(struct imx214 *imx214) const struct imx214_mode *mode; int ret;
- ret = imx214_write_table(imx214, mode_table_common); + ret = cci_multi_reg_write(imx214->regmap, mode_table_common, + ARRAY_SIZE(mode_table_common), NULL); if (ret < 0) { dev_err(imx214->dev, "could not sent common table %d\n", ret); return ret; @@ -784,17 +728,24 @@ static int imx214_start_streaming(struct imx214 *imx214) fmt = v4l2_subdev_state_get_format(state, 0); mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes), width, height, fmt->width, fmt->height); - ret = imx214_write_table(imx214, mode->reg_table); + ret = cci_multi_reg_write(imx214->regmap, mode->reg_table, + mode->num_of_regs, NULL); if (ret < 0) { dev_err(imx214->dev, "could not sent mode table %d\n", ret); return ret; } + + usleep_range(10000, 10500); + + cci_write(imx214->regmap, CCI_REG8(0x0138), 0x01, NULL); + ret = __v4l2_ctrl_handler_setup(&imx214->ctrls); if (ret < 0) { dev_err(imx214->dev, "could not sync v4l2 controls\n"); return ret; } - ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STREAMING); + ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT, + IMX214_MODE_STREAMING, NULL); if (ret < 0) dev_err(imx214->dev, "could not sent start table %d\n", ret);
@@ -805,7 +756,8 @@ static int imx214_stop_streaming(struct imx214 *imx214) { int ret;
- ret = regmap_write(imx214->regmap, IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY); + ret = cci_write(imx214->regmap, IMX214_REG_MODE_SELECT, + IMX214_MODE_STANDBY, NULL); if (ret < 0) dev_err(imx214->dev, "could not sent stop table %d\n", ret);
@@ -906,12 +858,6 @@ static const struct v4l2_subdev_internal_ops imx214_internal_ops = { .init_state = imx214_entity_init_state, };
-static const struct regmap_config sensor_regmap_config = { - .reg_bits = 16, - .val_bits = 8, - .cache_type = REGCACHE_MAPLE, -}; - static int imx214_get_regulators(struct device *dev, struct imx214 *imx214) { unsigned int i; @@ -995,10 +941,10 @@ static int imx214_probe(struct i2c_client *client) return dev_err_probe(dev, PTR_ERR(imx214->enable_gpio), "failed to get enable gpio\n");
- imx214->regmap = devm_regmap_init_i2c(client, &sensor_regmap_config); + imx214->regmap = devm_cci_regmap_init_i2c(client, 16); if (IS_ERR(imx214->regmap)) return dev_err_probe(dev, PTR_ERR(imx214->regmap), - "regmap init failed\n"); + "failed to initialize CCI\n");
v4l2_i2c_subdev_init(&imx214->sd, client, &imx214_subdev_ops); imx214->sd.internal_ops = &imx214_internal_ops;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Apitzsch git@apitzsch.eu
[ Upstream commit 341a133beb43f9009ebdde9eff276dfacbac114a ]
Define macros for all the known registers used in the register arrays, and use them to replace the numerical addresses. This improves readability.
Acked-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: André Apitzsch git@apitzsch.eu Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx214.c | 407 +++++++++++++++++++++---------------- 1 file changed, 236 insertions(+), 171 deletions(-)
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 20d1ebebf13af..8bac5a1f1cb18 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -24,18 +24,141 @@ #define IMX214_MODE_STANDBY 0x00 #define IMX214_MODE_STREAMING 0x01
+#define IMX214_REG_FAST_STANDBY_CTRL CCI_REG8(0x0106) + #define IMX214_DEFAULT_CLK_FREQ 24000000 #define IMX214_DEFAULT_LINK_FREQ 480000000 #define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10) #define IMX214_FPS 30 #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10
+/* V-TIMING internal */ +#define IMX214_REG_FRM_LENGTH_LINES CCI_REG16(0x0340) + /* Exposure control */ #define IMX214_REG_EXPOSURE CCI_REG16(0x0202) #define IMX214_EXPOSURE_MIN 0 #define IMX214_EXPOSURE_MAX 3184 #define IMX214_EXPOSURE_STEP 1 #define IMX214_EXPOSURE_DEFAULT 3184 +#define IMX214_REG_EXPOSURE_RATIO CCI_REG8(0x0222) +#define IMX214_REG_SHORT_EXPOSURE CCI_REG16(0x0224) + +/* Analog gain control */ +#define IMX214_REG_ANALOG_GAIN CCI_REG16(0x0204) +#define IMX214_REG_SHORT_ANALOG_GAIN CCI_REG16(0x0216) + +/* Digital gain control */ +#define IMX214_REG_DIG_GAIN_GREENR CCI_REG16(0x020e) +#define IMX214_REG_DIG_GAIN_RED CCI_REG16(0x0210) +#define IMX214_REG_DIG_GAIN_BLUE CCI_REG16(0x0212) +#define IMX214_REG_DIG_GAIN_GREENB CCI_REG16(0x0214) + +#define IMX214_REG_ORIENTATION CCI_REG8(0x0101) + +#define IMX214_REG_MASK_CORR_FRAMES CCI_REG8(0x0105) +#define IMX214_CORR_FRAMES_TRANSMIT 0 +#define IMX214_CORR_FRAMES_MASK 1 + +#define IMX214_REG_CSI_DATA_FORMAT CCI_REG16(0x0112) +#define IMX214_CSI_DATA_FORMAT_RAW8 0x0808 +#define IMX214_CSI_DATA_FORMAT_RAW10 0x0A0A +#define IMX214_CSI_DATA_FORMAT_COMP6 0x0A06 +#define IMX214_CSI_DATA_FORMAT_COMP8 0x0A08 + +#define IMX214_REG_CSI_LANE_MODE CCI_REG8(0x0114) +#define IMX214_CSI_2_LANE_MODE 1 +#define IMX214_CSI_4_LANE_MODE 3 + +#define IMX214_REG_EXCK_FREQ CCI_REG16(0x0136) +#define IMX214_EXCK_FREQ(n) ((n) * 256) /* n expressed in MHz */ + +#define IMX214_REG_TEMP_SENSOR_CONTROL CCI_REG8(0x0138) + +#define IMX214_REG_HDR_MODE CCI_REG8(0x0220) +#define IMX214_HDR_MODE_OFF 0 +#define IMX214_HDR_MODE_ON 1 + +#define IMX214_REG_HDR_RES_REDUCTION CCI_REG8(0x0221) +#define IMX214_HDR_RES_REDU_THROUGH 0x11 +#define IMX214_HDR_RES_REDU_2_BINNING 0x22 + +/* PLL settings */ +#define IMX214_REG_VTPXCK_DIV CCI_REG8(0x0301) +#define IMX214_REG_VTSYCK_DIV CCI_REG8(0x0303) +#define IMX214_REG_PREPLLCK_VT_DIV CCI_REG8(0x0305) +#define IMX214_REG_PLL_VT_MPY CCI_REG16(0x0306) +#define IMX214_REG_OPPXCK_DIV CCI_REG8(0x0309) +#define IMX214_REG_OPSYCK_DIV CCI_REG8(0x030b) +#define IMX214_REG_PLL_MULT_DRIV CCI_REG8(0x0310) +#define IMX214_PLL_SINGLE 0 +#define IMX214_PLL_DUAL 1 + +#define IMX214_REG_LINE_LENGTH_PCK CCI_REG16(0x0342) +#define IMX214_REG_X_ADD_STA CCI_REG16(0x0344) +#define IMX214_REG_Y_ADD_STA CCI_REG16(0x0346) +#define IMX214_REG_X_ADD_END CCI_REG16(0x0348) +#define IMX214_REG_Y_ADD_END CCI_REG16(0x034a) +#define IMX214_REG_X_OUTPUT_SIZE CCI_REG16(0x034c) +#define IMX214_REG_Y_OUTPUT_SIZE CCI_REG16(0x034e) +#define IMX214_REG_X_EVEN_INC CCI_REG8(0x0381) +#define IMX214_REG_X_ODD_INC CCI_REG8(0x0383) +#define IMX214_REG_Y_EVEN_INC CCI_REG8(0x0385) +#define IMX214_REG_Y_ODD_INC CCI_REG8(0x0387) + +#define IMX214_REG_SCALE_MODE CCI_REG8(0x0401) +#define IMX214_SCALE_NONE 0 +#define IMX214_SCALE_HORIZONTAL 1 +#define IMX214_SCALE_FULL 2 +#define IMX214_REG_SCALE_M CCI_REG16(0x0404) + +#define IMX214_REG_DIG_CROP_X_OFFSET CCI_REG16(0x0408) +#define IMX214_REG_DIG_CROP_Y_OFFSET CCI_REG16(0x040a) +#define IMX214_REG_DIG_CROP_WIDTH CCI_REG16(0x040c) +#define IMX214_REG_DIG_CROP_HEIGHT CCI_REG16(0x040e) + +#define IMX214_REG_REQ_LINK_BIT_RATE CCI_REG32(0x0820) +#define IMX214_LINK_BIT_RATE_MBPS(n) ((n) << 16) + +/* Binning mode */ +#define IMX214_REG_BINNING_MODE CCI_REG8(0x0900) +#define IMX214_BINNING_NONE 0 +#define IMX214_BINNING_ENABLE 1 +#define IMX214_REG_BINNING_TYPE CCI_REG8(0x0901) +#define IMX214_REG_BINNING_WEIGHTING CCI_REG8(0x0902) +#define IMX214_BINNING_AVERAGE 0x00 +#define IMX214_BINNING_SUMMED 0x01 +#define IMX214_BINNING_BAYER 0x02 + +#define IMX214_REG_SING_DEF_CORR_EN CCI_REG8(0x0b06) +#define IMX214_SING_DEF_CORR_OFF 0 +#define IMX214_SING_DEF_CORR_ON 1 + +/* AWB control */ +#define IMX214_REG_ABS_GAIN_GREENR CCI_REG16(0x0b8e) +#define IMX214_REG_ABS_GAIN_RED CCI_REG16(0x0b90) +#define IMX214_REG_ABS_GAIN_BLUE CCI_REG16(0x0b92) +#define IMX214_REG_ABS_GAIN_GREENB CCI_REG16(0x0b94) + +#define IMX214_REG_RMSC_NR_MODE CCI_REG8(0x3001) +#define IMX214_REG_STATS_OUT_EN CCI_REG8(0x3013) +#define IMX214_STATS_OUT_OFF 0 +#define IMX214_STATS_OUT_ON 1 + +/* Chroma noise reduction */ +#define IMX214_REG_NML_NR_EN CCI_REG8(0x30a2) +#define IMX214_NML_NR_OFF 0 +#define IMX214_NML_NR_ON 1 + +#define IMX214_REG_EBD_SIZE_V CCI_REG8(0x5041) +#define IMX214_EBD_NO 0 +#define IMX214_EBD_4_LINE 4 + +#define IMX214_REG_RG_STATS_LMT CCI_REG16(0x6d12) +#define IMX214_RG_STATS_LMT_10_BIT 0x03FF +#define IMX214_RG_STATS_LMT_14_BIT 0x3FFF + +#define IMX214_REG_ATR_FAST_MOVE CCI_REG8(0x9300)
/* IMX214 native and active pixel array size */ #define IMX214_NATIVE_WIDTH 4224U @@ -74,96 +197,70 @@ struct imx214 {
/*From imx214_mode_tbls.h*/ static const struct cci_reg_sequence mode_4096x2304[] = { - { CCI_REG8(0x0114), 0x03 }, - { CCI_REG8(0x0220), 0x00 }, - { CCI_REG8(0x0221), 0x11 }, - { CCI_REG8(0x0222), 0x01 }, - { CCI_REG8(0x0340), 0x0C }, - { CCI_REG8(0x0341), 0x7A }, - { CCI_REG8(0x0342), 0x13 }, - { CCI_REG8(0x0343), 0x90 }, - { CCI_REG8(0x0344), 0x00 }, - { CCI_REG8(0x0345), 0x38 }, - { CCI_REG8(0x0346), 0x01 }, - { CCI_REG8(0x0347), 0x98 }, - { CCI_REG8(0x0348), 0x10 }, - { CCI_REG8(0x0349), 0x37 }, - { CCI_REG8(0x034A), 0x0A }, - { CCI_REG8(0x034B), 0x97 }, - { CCI_REG8(0x0381), 0x01 }, - { CCI_REG8(0x0383), 0x01 }, - { CCI_REG8(0x0385), 0x01 }, - { CCI_REG8(0x0387), 0x01 }, - { CCI_REG8(0x0900), 0x00 }, - { CCI_REG8(0x0901), 0x00 }, - { CCI_REG8(0x0902), 0x00 }, + { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE }, + { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF }, + { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH }, + { IMX214_REG_EXPOSURE_RATIO, 1 }, + { IMX214_REG_FRM_LENGTH_LINES, 3194 }, + { IMX214_REG_LINE_LENGTH_PCK, 5008 }, + { IMX214_REG_X_ADD_STA, 56 }, + { IMX214_REG_Y_ADD_STA, 408 }, + { IMX214_REG_X_ADD_END, 4151 }, + { IMX214_REG_Y_ADD_END, 2711 }, + { IMX214_REG_X_EVEN_INC, 1 }, + { IMX214_REG_X_ODD_INC, 1 }, + { IMX214_REG_Y_EVEN_INC, 1 }, + { IMX214_REG_Y_ODD_INC, 1 }, + { IMX214_REG_BINNING_MODE, IMX214_BINNING_NONE }, + { IMX214_REG_BINNING_TYPE, 0 }, + { IMX214_REG_BINNING_WEIGHTING, IMX214_BINNING_AVERAGE }, { CCI_REG8(0x3000), 0x35 }, { CCI_REG8(0x3054), 0x01 }, { CCI_REG8(0x305C), 0x11 },
- { CCI_REG8(0x0112), 0x0A }, - { CCI_REG8(0x0113), 0x0A }, - { CCI_REG8(0x034C), 0x10 }, - { CCI_REG8(0x034D), 0x00 }, - { CCI_REG8(0x034E), 0x09 }, - { CCI_REG8(0x034F), 0x00 }, - { CCI_REG8(0x0401), 0x00 }, - { CCI_REG8(0x0404), 0x00 }, - { CCI_REG8(0x0405), 0x10 }, - { CCI_REG8(0x0408), 0x00 }, - { CCI_REG8(0x0409), 0x00 }, - { CCI_REG8(0x040A), 0x00 }, - { CCI_REG8(0x040B), 0x00 }, - { CCI_REG8(0x040C), 0x10 }, - { CCI_REG8(0x040D), 0x00 }, - { CCI_REG8(0x040E), 0x09 }, - { CCI_REG8(0x040F), 0x00 }, - - { CCI_REG8(0x0301), 0x05 }, - { CCI_REG8(0x0303), 0x02 }, - { CCI_REG8(0x0305), 0x03 }, - { CCI_REG8(0x0306), 0x00 }, - { CCI_REG8(0x0307), 0x96 }, - { CCI_REG8(0x0309), 0x0A }, - { CCI_REG8(0x030B), 0x01 }, - { CCI_REG8(0x0310), 0x00 }, - - { CCI_REG8(0x0820), 0x12 }, - { CCI_REG8(0x0821), 0xC0 }, - { CCI_REG8(0x0822), 0x00 }, - { CCI_REG8(0x0823), 0x00 }, + { IMX214_REG_CSI_DATA_FORMAT, IMX214_CSI_DATA_FORMAT_RAW10 }, + { IMX214_REG_X_OUTPUT_SIZE, 4096 }, + { IMX214_REG_Y_OUTPUT_SIZE, 2304 }, + { IMX214_REG_SCALE_MODE, IMX214_SCALE_NONE }, + { IMX214_REG_SCALE_M, 2 }, + { IMX214_REG_DIG_CROP_X_OFFSET, 0 }, + { IMX214_REG_DIG_CROP_Y_OFFSET, 0 }, + { IMX214_REG_DIG_CROP_WIDTH, 4096 }, + { IMX214_REG_DIG_CROP_HEIGHT, 2304 }, + + { IMX214_REG_VTPXCK_DIV, 5 }, + { IMX214_REG_VTSYCK_DIV, 2 }, + { IMX214_REG_PREPLLCK_VT_DIV, 3 }, + { IMX214_REG_PLL_VT_MPY, 150 }, + { IMX214_REG_OPPXCK_DIV, 10 }, + { IMX214_REG_OPSYCK_DIV, 1 }, + { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE }, + + { IMX214_REG_REQ_LINK_BIT_RATE, IMX214_LINK_BIT_RATE_MBPS(4800) },
{ CCI_REG8(0x3A03), 0x09 }, { CCI_REG8(0x3A04), 0x50 }, { CCI_REG8(0x3A05), 0x01 },
- { CCI_REG8(0x0B06), 0x01 }, - { CCI_REG8(0x30A2), 0x00 }, + { IMX214_REG_SING_DEF_CORR_EN, IMX214_SING_DEF_CORR_ON }, + { IMX214_REG_NML_NR_EN, IMX214_NML_NR_OFF },
{ CCI_REG8(0x30B4), 0x00 },
{ CCI_REG8(0x3A02), 0xFF },
{ CCI_REG8(0x3011), 0x00 }, - { CCI_REG8(0x3013), 0x01 }, - - { CCI_REG8(0x0202), 0x0C }, - { CCI_REG8(0x0203), 0x70 }, - { CCI_REG8(0x0224), 0x01 }, - { CCI_REG8(0x0225), 0xF4 }, - - { CCI_REG8(0x0204), 0x00 }, - { CCI_REG8(0x0205), 0x00 }, - { CCI_REG8(0x020E), 0x01 }, - { CCI_REG8(0x020F), 0x00 }, - { CCI_REG8(0x0210), 0x01 }, - { CCI_REG8(0x0211), 0x00 }, - { CCI_REG8(0x0212), 0x01 }, - { CCI_REG8(0x0213), 0x00 }, - { CCI_REG8(0x0214), 0x01 }, - { CCI_REG8(0x0215), 0x00 }, - { CCI_REG8(0x0216), 0x00 }, - { CCI_REG8(0x0217), 0x00 }, + { IMX214_REG_STATS_OUT_EN, IMX214_STATS_OUT_ON }, + + { IMX214_REG_EXPOSURE, IMX214_EXPOSURE_DEFAULT }, + { IMX214_REG_SHORT_EXPOSURE, 500 }, + + { IMX214_REG_ANALOG_GAIN, 0 }, + { IMX214_REG_DIG_GAIN_GREENR, 256 }, + { IMX214_REG_DIG_GAIN_RED, 256 }, + { IMX214_REG_DIG_GAIN_BLUE, 256 }, + { IMX214_REG_DIG_GAIN_GREENB, 256 }, + { IMX214_REG_SHORT_ANALOG_GAIN, 0 },
{ CCI_REG8(0x4170), 0x00 }, { CCI_REG8(0x4171), 0x10 }, @@ -174,96 +271,70 @@ static const struct cci_reg_sequence mode_4096x2304[] = { };
static const struct cci_reg_sequence mode_1920x1080[] = { - { CCI_REG8(0x0114), 0x03 }, - { CCI_REG8(0x0220), 0x00 }, - { CCI_REG8(0x0221), 0x11 }, - { CCI_REG8(0x0222), 0x01 }, - { CCI_REG8(0x0340), 0x0C }, - { CCI_REG8(0x0341), 0x7A }, - { CCI_REG8(0x0342), 0x13 }, - { CCI_REG8(0x0343), 0x90 }, - { CCI_REG8(0x0344), 0x04 }, - { CCI_REG8(0x0345), 0x78 }, - { CCI_REG8(0x0346), 0x03 }, - { CCI_REG8(0x0347), 0xFC }, - { CCI_REG8(0x0348), 0x0B }, - { CCI_REG8(0x0349), 0xF7 }, - { CCI_REG8(0x034A), 0x08 }, - { CCI_REG8(0x034B), 0x33 }, - { CCI_REG8(0x0381), 0x01 }, - { CCI_REG8(0x0383), 0x01 }, - { CCI_REG8(0x0385), 0x01 }, - { CCI_REG8(0x0387), 0x01 }, - { CCI_REG8(0x0900), 0x00 }, - { CCI_REG8(0x0901), 0x00 }, - { CCI_REG8(0x0902), 0x00 }, + { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE }, + { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF }, + { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH }, + { IMX214_REG_EXPOSURE_RATIO, 1 }, + { IMX214_REG_FRM_LENGTH_LINES, 3194 }, + { IMX214_REG_LINE_LENGTH_PCK, 5008 }, + { IMX214_REG_X_ADD_STA, 1144 }, + { IMX214_REG_Y_ADD_STA, 1020 }, + { IMX214_REG_X_ADD_END, 3063 }, + { IMX214_REG_Y_ADD_END, 2099 }, + { IMX214_REG_X_EVEN_INC, 1 }, + { IMX214_REG_X_ODD_INC, 1 }, + { IMX214_REG_Y_EVEN_INC, 1 }, + { IMX214_REG_Y_ODD_INC, 1 }, + { IMX214_REG_BINNING_MODE, IMX214_BINNING_NONE }, + { IMX214_REG_BINNING_TYPE, 0 }, + { IMX214_REG_BINNING_WEIGHTING, IMX214_BINNING_AVERAGE }, { CCI_REG8(0x3000), 0x35 }, { CCI_REG8(0x3054), 0x01 }, { CCI_REG8(0x305C), 0x11 },
- { CCI_REG8(0x0112), 0x0A }, - { CCI_REG8(0x0113), 0x0A }, - { CCI_REG8(0x034C), 0x07 }, - { CCI_REG8(0x034D), 0x80 }, - { CCI_REG8(0x034E), 0x04 }, - { CCI_REG8(0x034F), 0x38 }, - { CCI_REG8(0x0401), 0x00 }, - { CCI_REG8(0x0404), 0x00 }, - { CCI_REG8(0x0405), 0x10 }, - { CCI_REG8(0x0408), 0x00 }, - { CCI_REG8(0x0409), 0x00 }, - { CCI_REG8(0x040A), 0x00 }, - { CCI_REG8(0x040B), 0x00 }, - { CCI_REG8(0x040C), 0x07 }, - { CCI_REG8(0x040D), 0x80 }, - { CCI_REG8(0x040E), 0x04 }, - { CCI_REG8(0x040F), 0x38 }, - - { CCI_REG8(0x0301), 0x05 }, - { CCI_REG8(0x0303), 0x02 }, - { CCI_REG8(0x0305), 0x03 }, - { CCI_REG8(0x0306), 0x00 }, - { CCI_REG8(0x0307), 0x96 }, - { CCI_REG8(0x0309), 0x0A }, - { CCI_REG8(0x030B), 0x01 }, - { CCI_REG8(0x0310), 0x00 }, - - { CCI_REG8(0x0820), 0x12 }, - { CCI_REG8(0x0821), 0xC0 }, - { CCI_REG8(0x0822), 0x00 }, - { CCI_REG8(0x0823), 0x00 }, + { IMX214_REG_CSI_DATA_FORMAT, IMX214_CSI_DATA_FORMAT_RAW10 }, + { IMX214_REG_X_OUTPUT_SIZE, 1920 }, + { IMX214_REG_Y_OUTPUT_SIZE, 1080 }, + { IMX214_REG_SCALE_MODE, IMX214_SCALE_NONE }, + { IMX214_REG_SCALE_M, 2 }, + { IMX214_REG_DIG_CROP_X_OFFSET, 0 }, + { IMX214_REG_DIG_CROP_Y_OFFSET, 0 }, + { IMX214_REG_DIG_CROP_WIDTH, 1920 }, + { IMX214_REG_DIG_CROP_HEIGHT, 1080 }, + + { IMX214_REG_VTPXCK_DIV, 5 }, + { IMX214_REG_VTSYCK_DIV, 2 }, + { IMX214_REG_PREPLLCK_VT_DIV, 3 }, + { IMX214_REG_PLL_VT_MPY, 150 }, + { IMX214_REG_OPPXCK_DIV, 10 }, + { IMX214_REG_OPSYCK_DIV, 1 }, + { IMX214_REG_PLL_MULT_DRIV, IMX214_PLL_SINGLE }, + + { IMX214_REG_REQ_LINK_BIT_RATE, IMX214_LINK_BIT_RATE_MBPS(4800) },
{ CCI_REG8(0x3A03), 0x04 }, { CCI_REG8(0x3A04), 0xF8 }, { CCI_REG8(0x3A05), 0x02 },
- { CCI_REG8(0x0B06), 0x01 }, - { CCI_REG8(0x30A2), 0x00 }, + { IMX214_REG_SING_DEF_CORR_EN, IMX214_SING_DEF_CORR_ON }, + { IMX214_REG_NML_NR_EN, IMX214_NML_NR_OFF },
{ CCI_REG8(0x30B4), 0x00 },
{ CCI_REG8(0x3A02), 0xFF },
{ CCI_REG8(0x3011), 0x00 }, - { CCI_REG8(0x3013), 0x01 }, - - { CCI_REG8(0x0202), 0x0C }, - { CCI_REG8(0x0203), 0x70 }, - { CCI_REG8(0x0224), 0x01 }, - { CCI_REG8(0x0225), 0xF4 }, - - { CCI_REG8(0x0204), 0x00 }, - { CCI_REG8(0x0205), 0x00 }, - { CCI_REG8(0x020E), 0x01 }, - { CCI_REG8(0x020F), 0x00 }, - { CCI_REG8(0x0210), 0x01 }, - { CCI_REG8(0x0211), 0x00 }, - { CCI_REG8(0x0212), 0x01 }, - { CCI_REG8(0x0213), 0x00 }, - { CCI_REG8(0x0214), 0x01 }, - { CCI_REG8(0x0215), 0x00 }, - { CCI_REG8(0x0216), 0x00 }, - { CCI_REG8(0x0217), 0x00 }, + { IMX214_REG_STATS_OUT_EN, IMX214_STATS_OUT_ON }, + + { IMX214_REG_EXPOSURE, IMX214_EXPOSURE_DEFAULT }, + { IMX214_REG_SHORT_EXPOSURE, 500 }, + + { IMX214_REG_ANALOG_GAIN, 0 }, + { IMX214_REG_DIG_GAIN_GREENR, 256 }, + { IMX214_REG_DIG_GAIN_RED, 256 }, + { IMX214_REG_DIG_GAIN_BLUE, 256 }, + { IMX214_REG_DIG_GAIN_GREENB, 256 }, + { IMX214_REG_SHORT_ANALOG_GAIN, 0 },
{ CCI_REG8(0x4170), 0x00 }, { CCI_REG8(0x4171), 0x10 }, @@ -277,20 +348,19 @@ static const struct cci_reg_sequence mode_table_common[] = { /* software reset */
/* software standby settings */ - { CCI_REG8(0x0100), 0x00 }, + { IMX214_REG_MODE_SELECT, IMX214_MODE_STANDBY },
/* ATR setting */ - { CCI_REG8(0x9300), 0x02 }, + { IMX214_REG_ATR_FAST_MOVE, 2 },
/* external clock setting */ - { CCI_REG8(0x0136), 0x18 }, - { CCI_REG8(0x0137), 0x00 }, + { IMX214_REG_EXCK_FREQ, IMX214_EXCK_FREQ(IMX214_DEFAULT_CLK_FREQ / 1000000) },
/* global setting */ /* basic config */ - { CCI_REG8(0x0101), 0x00 }, - { CCI_REG8(0x0105), 0x01 }, - { CCI_REG8(0x0106), 0x01 }, + { IMX214_REG_ORIENTATION, 0 }, + { IMX214_REG_MASK_CORR_FRAMES, IMX214_CORR_FRAMES_MASK }, + { IMX214_REG_FAST_STANDBY_CTRL, 1 }, { CCI_REG8(0x4550), 0x02 }, { CCI_REG8(0x4601), 0x00 }, { CCI_REG8(0x4642), 0x05 }, @@ -335,18 +405,17 @@ static const struct cci_reg_sequence mode_table_common[] = { { CCI_REG8(0x4A87), 0xFF },
/* embedded data */ - { CCI_REG8(0x5041), 0x04 }, + { IMX214_REG_EBD_SIZE_V, IMX214_EBD_4_LINE }, { CCI_REG8(0x583C), 0x04 }, { CCI_REG8(0x620E), 0x04 }, { CCI_REG8(0x6EB2), 0x01 }, { CCI_REG8(0x6EB3), 0x00 }, - { CCI_REG8(0x9300), 0x02 }, + { IMX214_REG_ATR_FAST_MOVE, 2 },
/* imagequality */ /* HDR setting */ - { CCI_REG8(0x3001), 0x07 }, - { CCI_REG8(0x6D12), 0x3F }, - { CCI_REG8(0x6D13), 0xFF }, + { IMX214_REG_RMSC_NR_MODE, 0x07 }, + { IMX214_REG_RG_STATS_LMT, IMX214_RG_STATS_LMT_14_BIT }, { CCI_REG8(0x9344), 0x03 }, { CCI_REG8(0x9706), 0x10 }, { CCI_REG8(0x9707), 0x03 }, @@ -374,14 +443,10 @@ static const struct cci_reg_sequence mode_table_common[] = { { CCI_REG8(0x698B), 0x03 },
/* white balanace */ - { CCI_REG8(0x0B8E), 0x01 }, - { CCI_REG8(0x0B8F), 0x00 }, - { CCI_REG8(0x0B90), 0x01 }, - { CCI_REG8(0x0B91), 0x00 }, - { CCI_REG8(0x0B92), 0x01 }, - { CCI_REG8(0x0B93), 0x00 }, - { CCI_REG8(0x0B94), 0x01 }, - { CCI_REG8(0x0B95), 0x00 }, + { IMX214_REG_ABS_GAIN_GREENR, 0x0100 }, + { IMX214_REG_ABS_GAIN_RED, 0x0100 }, + { IMX214_REG_ABS_GAIN_BLUE, 0x0100 }, + { IMX214_REG_ABS_GAIN_GREENB, 0x0100 },
/* ATR setting */ { CCI_REG8(0x6E50), 0x00 }, @@ -737,7 +802,7 @@ static int imx214_start_streaming(struct imx214 *imx214)
usleep_range(10000, 10500);
- cci_write(imx214->regmap, CCI_REG8(0x0138), 0x01, NULL); + cci_write(imx214->regmap, IMX214_REG_TEMP_SENSOR_CONTROL, 0x01, NULL);
ret = __v4l2_ctrl_handler_setup(&imx214->ctrls); if (ret < 0) {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Apitzsch git@apitzsch.eu
[ Upstream commit 3d55f4eb03fce69f3a72615fe9c5ca171f7b846b ]
The imx214 camera is capable of either two-lane or four-lane operation.
Currently only the four-lane mode is supported, as proper pixel rates and link frequences for the two-lane mode are unknown.
Acked-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: André Apitzsch git@apitzsch.eu Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: acc294519f17 ("media: i2c: imx214: Fix link frequency validation") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx214.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index 8bac5a1f1cb18..fdc2dfb4ebcdd 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -197,7 +197,6 @@ struct imx214 {
/*From imx214_mode_tbls.h*/ static const struct cci_reg_sequence mode_4096x2304[] = { - { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE }, { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF }, { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH }, { IMX214_REG_EXPOSURE_RATIO, 1 }, @@ -271,7 +270,6 @@ static const struct cci_reg_sequence mode_4096x2304[] = { };
static const struct cci_reg_sequence mode_1920x1080[] = { - { IMX214_REG_CSI_LANE_MODE, IMX214_CSI_4_LANE_MODE }, { IMX214_REG_HDR_MODE, IMX214_HDR_MODE_OFF }, { IMX214_REG_HDR_RES_REDUCTION, IMX214_HDR_RES_REDU_THROUGH }, { IMX214_REG_EXPOSURE_RATIO, 1 }, @@ -789,6 +787,13 @@ static int imx214_start_streaming(struct imx214 *imx214) return ret; }
+ ret = cci_write(imx214->regmap, IMX214_REG_CSI_LANE_MODE, + IMX214_CSI_4_LANE_MODE, NULL); + if (ret) { + dev_err(imx214->dev, "failed to configure lanes\n"); + return ret; + } + state = v4l2_subdev_get_locked_active_state(&imx214->sd); fmt = v4l2_subdev_state_get_format(state, 0); mode = v4l2_find_nearest_size(imx214_modes, ARRAY_SIZE(imx214_modes), @@ -953,6 +958,13 @@ static int imx214_parse_fwnode(struct device *dev) goto done; }
+ /* Check the number of MIPI CSI2 data lanes */ + if (bus_cfg.bus.mipi_csi2.num_data_lanes != 4) { + ret = dev_err_probe(dev, -EINVAL, + "only 4 data lanes are currently supported\n"); + goto done; + } + for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) if (bus_cfg.link_frequencies[i] == IMX214_DEFAULT_LINK_FREQ) break;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: André Apitzsch git@apitzsch.eu
[ Upstream commit acc294519f1749041e1b8c74d46bbf6c57d8b061 ]
The driver defines IMX214_DEFAULT_LINK_FREQ 480000000, and then IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10), which works out as 384MPix/s. (The 8 is 4 lanes and DDR.)
Parsing the PLL registers with the defined 24MHz input. We're in single PLL mode, so MIPI frequency is directly linked to pixel rate. VTCK ends up being 1200MHz, and VTPXCK and OPPXCK both are 120MHz. Section 5.3 "Frame rate calculation formula" says "Pixel rate [pixels/s] = VTPXCK [MHz] * 4", so 120 * 4 = 480MPix/s, which basically agrees with my number above.
3.1.4. MIPI global timing setting says "Output bitrate = OPPXCK * reg 0x113[7:0]", so 120MHz * 10, or 1200Mbit/s. That would be a link frequency of 600MHz due to DDR. That also matches to 480MPix/s * 10bpp / 4 lanes / 2 for DDR.
Keep the previous link frequency for backward compatibility.
Acked-by: Ricardo Ribalda ribalda@chromium.org Signed-off-by: André Apitzsch git@apitzsch.eu Fixes: 436190596241 ("media: imx214: Add imx214 camera sensor driver") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/imx214.c | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-)
diff --git a/drivers/media/i2c/imx214.c b/drivers/media/i2c/imx214.c index fdc2dfb4ebcdd..bdf2396c2482b 100644 --- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -27,7 +27,9 @@ #define IMX214_REG_FAST_STANDBY_CTRL CCI_REG8(0x0106)
#define IMX214_DEFAULT_CLK_FREQ 24000000 -#define IMX214_DEFAULT_LINK_FREQ 480000000 +#define IMX214_DEFAULT_LINK_FREQ 600000000 +/* Keep wrong link frequency for backward compatibility */ +#define IMX214_DEFAULT_LINK_FREQ_LEGACY 480000000 #define IMX214_DEFAULT_PIXEL_RATE ((IMX214_DEFAULT_LINK_FREQ * 8LL) / 10) #define IMX214_FPS 30 #define IMX214_MBUS_CODE MEDIA_BUS_FMT_SRGGB10_1X10 @@ -965,18 +967,26 @@ static int imx214_parse_fwnode(struct device *dev) goto done; }
- for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) + if (bus_cfg.nr_of_link_frequencies != 1) + dev_warn(dev, "Only one link-frequency supported, please review your DT. Continuing anyway\n"); + + for (i = 0; i < bus_cfg.nr_of_link_frequencies; i++) { if (bus_cfg.link_frequencies[i] == IMX214_DEFAULT_LINK_FREQ) break; - - if (i == bus_cfg.nr_of_link_frequencies) { - dev_err_probe(dev, -EINVAL, - "link-frequencies %d not supported, Please review your DT\n", - IMX214_DEFAULT_LINK_FREQ); - ret = -EINVAL; - goto done; + if (bus_cfg.link_frequencies[i] == + IMX214_DEFAULT_LINK_FREQ_LEGACY) { + dev_warn(dev, + "link-frequencies %d not supported, please review your DT. Continuing anyway\n", + IMX214_DEFAULT_LINK_FREQ); + break; + } }
+ if (i == bus_cfg.nr_of_link_frequencies) + ret = dev_err_probe(dev, -EINVAL, + "link-frequencies %d not supported, please review your DT\n", + IMX214_DEFAULT_LINK_FREQ); + done: v4l2_fwnode_endpoint_free(&bus_cfg); fwnode_handle_put(endpoint);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 7a39639e448f070cbe37317ac922886b6080ff43 ]
Move the ov08x40_identify_module() function to above ov08x40_set_stream() this is a preparation patch for adding a missing ov08x40_identify_module() call to ov08x40_set_stream().
No functional changes, just moving code around.
Tested-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Hans de Goede hdegoede@redhat.com Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Stable-dep-of: ebf185efadb7 ("media: ov08x40: Add missing ov08x40_identify_module() call on stream-start") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/ov08x40.c | 52 ++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-)
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 83b49cf114acc..580d902977b68 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -1937,6 +1937,32 @@ static int ov08x40_stop_streaming(struct ov08x40 *ov08x) OV08X40_REG_VALUE_08BIT, OV08X40_MODE_STANDBY); }
+/* Verify chip ID */ +static int ov08x40_identify_module(struct ov08x40 *ov08x) +{ + struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd); + int ret; + u32 val; + + if (ov08x->identified) + return 0; + + ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID, + OV08X40_REG_VALUE_24BIT, &val); + if (ret) + return ret; + + if (val != OV08X40_CHIP_ID) { + dev_err(&client->dev, "chip id mismatch: %x!=%x\n", + OV08X40_CHIP_ID, val); + return -ENXIO; + } + + ov08x->identified = true; + + return 0; +} + static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable) { struct ov08x40 *ov08x = to_ov08x40(sd); @@ -1974,32 +2000,6 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable) return ret; }
-/* Verify chip ID */ -static int ov08x40_identify_module(struct ov08x40 *ov08x) -{ - struct i2c_client *client = v4l2_get_subdevdata(&ov08x->sd); - int ret; - u32 val; - - if (ov08x->identified) - return 0; - - ret = ov08x40_read_reg(ov08x, OV08X40_REG_CHIP_ID, - OV08X40_REG_VALUE_24BIT, &val); - if (ret) - return ret; - - if (val != OV08X40_CHIP_ID) { - dev_err(&client->dev, "chip id mismatch: %x!=%x\n", - OV08X40_CHIP_ID, val); - return -ENXIO; - } - - ov08x->identified = true; - - return 0; -} - static const struct v4l2_subdev_video_ops ov08x40_video_ops = { .s_stream = ov08x40_set_stream, };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit ebf185efadb71bd5344877be683895b6b18d7edf ]
The driver might skip the ov08x40_identify_module() on probe() based on the acpi_dev_state_d0() check done in probe().
If the ov08x40_identify_module() call is skipped on probe() it should be done on the first stream start. Add the missing call.
Note ov08x40_identify_module() will only do something on its first call, subsequent calls are no-ops.
Tested-by: Bryan O'Donoghue bryan.odonoghue@linaro.org Signed-off-by: Hans de Goede hdegoede@redhat.com Fixes: b1a42fde6e07 ("media: ov08x40: Avoid sensor probing in D0 state") Cc: stable@vger.kernel.org Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/media/i2c/ov08x40.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/media/i2c/ov08x40.c b/drivers/media/i2c/ov08x40.c index 580d902977b68..625fbcd39068e 100644 --- a/drivers/media/i2c/ov08x40.c +++ b/drivers/media/i2c/ov08x40.c @@ -1976,6 +1976,10 @@ static int ov08x40_set_stream(struct v4l2_subdev *sd, int enable) if (ret < 0) goto err_unlock;
+ ret = ov08x40_identify_module(ov08x); + if (ret) + goto err_rpm_put; + /* * Apply default & customized values * and then start streaming.
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron Jonathan.Cameron@huawei.com
[ Upstream commit 0af1c801a15225304a6328258efbf2bee245c654 ]
The data used is all in local variables so there is no advantage in setting *val = ret with the direct mode claim held. Move it later to after error check.
Reviewed-by: Nuno Sá nuno.sa@analog.com Link: https://patch.msgid.link/20250217141630.897334-13-jic23@kernel.org Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Stable-dep-of: 8236644f5ecb ("iio: adc: ad7768-1: Fix conversion result sign") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7768-1.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c index 6f8816483f1a0..c78243a68b6e0 100644 --- a/drivers/iio/adc/ad7768-1.c +++ b/drivers/iio/adc/ad7768-1.c @@ -370,12 +370,11 @@ static int ad7768_read_raw(struct iio_dev *indio_dev, return ret;
ret = ad7768_scan_direct(indio_dev); - if (ret >= 0) - *val = ret;
iio_device_release_direct_mode(indio_dev); if (ret < 0) return ret; + *val = ret;
return IIO_VAL_INT;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergiu Cuciurean sergiu.cuciurean@analog.com
[ Upstream commit 8236644f5ecb180e80ad92d691c22bc509b747bb ]
The ad7768-1 ADC output code is two's complement, meaning that the voltage conversion result is a signed value.. Since the value is a 24 bit one, stored in a 32 bit variable, the sign should be extended in order to get the correct representation.
Also the channel description has been updated to signed representation, to match the ADC specifications.
Fixes: a5f8c7da3dbe ("iio: adc: Add AD7768-1 ADC basic support") Reviewed-by: David Lechner dlechner@baylibre.com Reviewed-by: Marcelo Schmitt marcelo.schmitt@analog.com Signed-off-by: Sergiu Cuciurean sergiu.cuciurean@analog.com Signed-off-by: Jonathan Santos Jonathan.Santos@analog.com Cc: Stable@vger.kernel.org Link: https://patch.msgid.link/505994d3b71c2aa38ba714d909a68e021f12124c.1741268122... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad7768-1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iio/adc/ad7768-1.c b/drivers/iio/adc/ad7768-1.c index c78243a68b6e0..157a0df97f971 100644 --- a/drivers/iio/adc/ad7768-1.c +++ b/drivers/iio/adc/ad7768-1.c @@ -142,7 +142,7 @@ static const struct iio_chan_spec ad7768_channels[] = { .channel = 0, .scan_index = 0, .scan_type = { - .sign = 'u', + .sign = 's', .realbits = 24, .storagebits = 32, .shift = 8, @@ -374,7 +374,7 @@ static int ad7768_read_raw(struct iio_dev *indio_dev, iio_device_release_direct_mode(indio_dev); if (ret < 0) return ret; - *val = ret; + *val = sign_extend32(ret, chan->scan_type.realbits - 1);
return IIO_VAL_INT;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring (Arm) robh@kernel.org
[ Upstream commit 5275e8b5293f65cc82a5ee5eab02dd573b911d6e ]
Use the __free() cleanup to simplify of_resolve_phandles() and remove all the goto's.
Signed-off-by: Rob Herring (Arm) robh@kernel.org Stable-dep-of: a46a0805635d ("of: resolver: Fix device node refcount leakage in of_resolve_phandles()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/resolver.c | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-)
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index 779db058c42f5..c871e35d49217 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -250,24 +250,20 @@ static int adjust_local_phandle_references(const struct device_node *local_fixup int of_resolve_phandles(struct device_node *overlay) { struct device_node *child, *local_fixups, *refnode; - struct device_node *tree_symbols, *overlay_fixups; + struct device_node *overlay_fixups; struct property *prop; const char *refpath; phandle phandle, phandle_delta; int err;
- tree_symbols = NULL; - if (!overlay) { pr_err("null overlay\n"); - err = -EINVAL; - goto out; + return -EINVAL; }
if (!of_node_check_flag(overlay, OF_DETACHED)) { pr_err("overlay not detached\n"); - err = -EINVAL; - goto out; + return -EINVAL; }
phandle_delta = live_tree_max_phandle() + 1; @@ -279,7 +275,7 @@ int of_resolve_phandles(struct device_node *overlay)
err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta); if (err) - goto out; + return err;
overlay_fixups = NULL;
@@ -288,16 +284,13 @@ int of_resolve_phandles(struct device_node *overlay) overlay_fixups = child; }
- if (!overlay_fixups) { - err = 0; - goto out; - } + if (!overlay_fixups) + return 0;
- tree_symbols = of_find_node_by_path("/__symbols__"); + struct device_node __free(device_node) *tree_symbols = of_find_node_by_path("/__symbols__"); if (!tree_symbols) { pr_err("no symbols in root of device tree.\n"); - err = -EINVAL; - goto out; + return -EINVAL; }
for_each_property_of_node(overlay_fixups, prop) { @@ -311,14 +304,12 @@ int of_resolve_phandles(struct device_node *overlay) if (err) { pr_err("node label '%s' not found in live devicetree symbols table\n", prop->name); - goto out; + return err; }
refnode = of_find_node_by_path(refpath); - if (!refnode) { - err = -ENOENT; - goto out; - } + if (!refnode) + return -ENOENT;
phandle = refnode->phandle; of_node_put(refnode); @@ -328,11 +319,8 @@ int of_resolve_phandles(struct device_node *overlay) break; }
-out: if (err) pr_err("overlay phandle fixup failed: %d\n", err); - of_node_put(tree_symbols); - return err; } EXPORT_SYMBOL_GPL(of_resolve_phandles);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zijun Hu quic_zijuhu@quicinc.com
[ Upstream commit a46a0805635d07de50c2ac71588345323c13b2f9 ]
In of_resolve_phandles(), refcount of device node @local_fixups will be increased if the for_each_child_of_node() exits early, but nowhere to decrease the refcount, so cause refcount leakage for the node.
Fix by using __free() on @local_fixups.
Fixes: da56d04c806a ("of/resolver: Switch to new local fixups format.") Cc: stable@vger.kernel.org Signed-off-by: Zijun Hu quic_zijuhu@quicinc.com Link: https://lore.kernel.org/r/20250209-of_irq_fix-v2-9-93e3a2659aa7@quicinc.com [robh: Use __free() instead] Signed-off-by: Rob Herring (Arm) robh@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/of/resolver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c index c871e35d49217..2caad365a665c 100644 --- a/drivers/of/resolver.c +++ b/drivers/of/resolver.c @@ -249,8 +249,9 @@ static int adjust_local_phandle_references(const struct device_node *local_fixup */ int of_resolve_phandles(struct device_node *overlay) { - struct device_node *child, *local_fixups, *refnode; + struct device_node *child, *refnode; struct device_node *overlay_fixups; + struct device_node __free(device_node) *local_fixups = NULL; struct property *prop; const char *refpath; phandle phandle, phandle_delta;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tudor Ambarus tudor.ambarus@linaro.org
[ Upstream commit ded40f32b55f7f2f4ed9627dd3c37a1fe89ed8c6 ]
The driver leaks the device reference taken with of_find_device_by_node(). Fix the leak by using devm_of_qcom_ice_get().
Fixes: 56541c7c4468 ("scsi: ufs: ufs-qcom: Switch to the new ICE API") Cc: stable@vger.kernel.org Signed-off-by: Tudor Ambarus tudor.ambarus@linaro.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Abel Vesa abel.vesa@linaro.org Acked-by: Martin K. Petersen martin.petersen@oracle.com # SCSI Reviewed-by: Manivannan Sadhasivam manivannan.sadhasivam@linaro.org Link: https://lore.kernel.org/r/20250117-qcom-ice-fix-dev-leak-v2-3-1ffa5b6884cb@l... Signed-off-by: Bjorn Andersson andersson@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/host/ufs-qcom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 23b9f6efa0475..a455a95f65fc6 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -125,7 +125,7 @@ static int ufs_qcom_ice_init(struct ufs_qcom_host *host) int err; int i;
- ice = of_qcom_ice_get(dev); + ice = devm_of_qcom_ice_get(dev); if (ice == ERR_PTR(-EOPNOTSUPP)) { dev_warn(dev, "Disabling inline encryption support\n"); ice = NULL;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Schnelle schnelle@linux.ibm.com
[ Upstream commit aa9f168d55dc47c0de564f7dfe0e90467c9fee71 ]
So far s390 does not allow mmap() of PCI resources to user-space via the usual mechanisms, though it does use it for RDMA. For the PCI sysfs resource files and /proc/bus/pci it defines neither HAVE_PCI_MMAP nor ARCH_GENERIC_PCI_MMAP_RESOURCE. For vfio-pci s390 previously relied on disabled VFIO_PCI_MMAP and now relies on setting pdev->non_mappable_bars for all devices.
This is partly because access to mapped PCI resources from user-space requires special PCI load/store memory-I/O (MIO) instructions, or the special MMIO syscalls when these are not available. Still, such access is possible and useful not just for RDMA, in fact not being able to mmap() PCI resources has previously caused extra work when testing devices.
One thing that doesn't work with PCI resources mapped to user-space though is the s390 specific virtual ISM device. Not only because the BAR size of 256 TiB prevents mapping the whole BAR but also because access requires use of the legacy PCI instructions which are not accessible to user-space on systems with the newer MIO PCI instructions.
Now with the pdev->non_mappable_bars flag ISM can be excluded from mapping its resources while making this functionality available for all other PCI devices. To this end introduce a minimal implementation of PCI_QUIRKS and use that to set pdev->non_mappable_bars for ISM devices only. Then also set ARCH_GENERIC_PCI_MMAP_RESOURCE to take advantage of the generic implementation of pci_mmap_resource_range() enabling only the newer sysfs mmap() interface. This follows the recommendation in Documentation/PCI/sysfs-pci.rst.
Link: https://lore.kernel.org/r/20250226-vfio_pci_mmap-v7-3-c5c0f1d26efd@linux.ibm... Signed-off-by: Niklas Schnelle schnelle@linux.ibm.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/Kconfig | 4 +--- arch/s390/include/asm/pci.h | 3 +++ arch/s390/pci/Makefile | 2 +- arch/s390/pci/pci_fixup.c | 23 +++++++++++++++++++++++ drivers/s390/net/ism_drv.c | 1 - include/linux/pci_ids.h | 1 + 6 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 arch/s390/pci/pci_fixup.c
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 9c9ec08d78c71..e48741e001476 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -41,9 +41,6 @@ config AUDIT_ARCH config NO_IOPORT_MAP def_bool y
-config PCI_QUIRKS - def_bool n - config ARCH_SUPPORTS_UPROBES def_bool y
@@ -258,6 +255,7 @@ config S390 select PCI_DOMAINS if PCI select PCI_MSI if PCI select PCI_MSI_ARCH_FALLBACKS if PCI_MSI + select PCI_QUIRKS if PCI select SPARSE_IRQ select SWIOTLB select SYSCTL_EXCEPTION_TRACE diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h index 474e1f8d1d3c2..d2086af3434c0 100644 --- a/arch/s390/include/asm/pci.h +++ b/arch/s390/include/asm/pci.h @@ -11,6 +11,9 @@ #include <asm/pci_insn.h> #include <asm/sclp.h>
+#define ARCH_GENERIC_PCI_MMAP_RESOURCE 1 +#define arch_can_pci_mmap_wc() 1 + #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000
diff --git a/arch/s390/pci/Makefile b/arch/s390/pci/Makefile index df73c5182990a..1810e0944a4ed 100644 --- a/arch/s390/pci/Makefile +++ b/arch/s390/pci/Makefile @@ -5,6 +5,6 @@
obj-$(CONFIG_PCI) += pci.o pci_irq.o pci_clp.o \ pci_event.o pci_debug.o pci_insn.o pci_mmio.o \ - pci_bus.o pci_kvm_hook.o pci_report.o + pci_bus.o pci_kvm_hook.o pci_report.o pci_fixup.o obj-$(CONFIG_PCI_IOV) += pci_iov.o obj-$(CONFIG_SYSFS) += pci_sysfs.o diff --git a/arch/s390/pci/pci_fixup.c b/arch/s390/pci/pci_fixup.c new file mode 100644 index 0000000000000..35688b6450983 --- /dev/null +++ b/arch/s390/pci/pci_fixup.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Exceptions for specific devices, + * + * Copyright IBM Corp. 2025 + * + * Author(s): + * Niklas Schnelle schnelle@linux.ibm.com + */ +#include <linux/pci.h> + +static void zpci_ism_bar_no_mmap(struct pci_dev *pdev) +{ + /* + * ISM's BAR is special. Drivers written for ISM know + * how to handle this but others need to be aware of their + * special nature e.g. to prevent attempts to mmap() it. + */ + pdev->non_mappable_bars = 1; +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_IBM, + PCI_DEVICE_ID_IBM_ISM, + zpci_ism_bar_no_mmap); diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index 2f34761e64135..60ed70a39d2cc 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -20,7 +20,6 @@ MODULE_DESCRIPTION("ISM driver for s390"); MODULE_LICENSE("GPL");
-#define PCI_DEVICE_ID_IBM_ISM 0x04ED #define DRV_NAME "ism"
static const struct pci_device_id ism_device_table[] = { diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 2a9ca3dbaa0e9..5bd122a9afdc6 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -518,6 +518,7 @@ #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251 #define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM_PCIE 0x0361 #define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252 +#define PCI_DEVICE_ID_IBM_ISM 0x04ed
#define PCI_SUBVENDOR_ID_IBM 0x1014 #define PCI_SUBDEVICE_ID_IBM_SATURN_SERIAL_ONE_PORT 0x03d4
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Pau Monne roger.pau@citrix.com
[ Upstream commit c3164d2e0d181027da8fc94f8179d8607c3d440f ]
Setting pci_msi_ignore_mask inhibits the toggling of the mask bit for both MSI and MSI-X entries globally, regardless of the IRQ chip they are using. Only Xen sets the pci_msi_ignore_mask when routing physical interrupts over event channels, to prevent PCI code from attempting to toggle the maskbit, as it's Xen that controls the bit.
However, the pci_msi_ignore_mask being global will affect devices that use MSI interrupts but are not routing those interrupts over event channels (not using the Xen pIRQ chip). One example is devices behind a VMD PCI bridge. In that scenario the VMD bridge configures MSI(-X) using the normal IRQ chip (the pIRQ one in the Xen case), and devices behind the bridge configure the MSI entries using indexes into the VMD bridge MSI table. The VMD bridge then demultiplexes such interrupts and delivers to the destination device(s). Having pci_msi_ignore_mask set in that scenario prevents (un)masking of MSI entries for devices behind the VMD bridge.
Move the signaling of no entry masking into the MSI domain flags, as that allows setting it on a per-domain basis. Set it for the Xen MSI domain that uses the pIRQ chip, while leaving it unset for the rest of the cases.
Remove pci_msi_ignore_mask at once, since it was only used by Xen code, and with Xen dropping usage the variable is unneeded.
This fixes using devices behind a VMD bridge on Xen PV hardware domains.
Albeit Devices behind a VMD bridge are not known to Xen, that doesn't mean Linux cannot use them. By inhibiting the usage of VMD_FEAT_CAN_BYPASS_MSI_REMAP and the removal of the pci_msi_ignore_mask bodge devices behind a VMD bridge do work fine when use from a Linux Xen hardware domain. That's the whole point of the series.
Signed-off-by: Roger Pau Monné roger.pau@citrix.com Reviewed-by: Thomas Gleixner tglx@linutronix.de Acked-by: Juergen Gross jgross@suse.com Acked-by: Bjorn Helgaas bhelgaas@google.com Message-ID: 20250219092059.90850-4-roger.pau@citrix.com Signed-off-by: Juergen Gross jgross@suse.com Stable-dep-of: cf761e3dacc6 ("PCI/MSI: Add an option to write MSIX ENTRY_DATA before any reads") Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/pci/xen.c | 8 ++------ drivers/pci/msi/msi.c | 37 +++++++++++++++++++++---------------- include/linux/msi.h | 3 ++- kernel/irq/msi.c | 2 +- 4 files changed, 26 insertions(+), 24 deletions(-)
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index 0f2fe524f60dc..b8755cde24199 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c @@ -436,7 +436,8 @@ static struct msi_domain_ops xen_pci_msi_domain_ops = { };
static struct msi_domain_info xen_pci_msi_domain_info = { - .flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS, + .flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | + MSI_FLAG_DEV_SYSFS | MSI_FLAG_NO_MASK, .ops = &xen_pci_msi_domain_ops, };
@@ -484,11 +485,6 @@ static __init void xen_setup_pci_msi(void) * in allocating the native domain and never use it. */ x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain; - /* - * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely - * controlled by the hypervisor. - */ - pci_msi_ignore_mask = 1; }
#else /* CONFIG_PCI_MSI */ diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 2f647cac4cae3..4c8c2b57b5f61 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -10,12 +10,12 @@ #include <linux/err.h> #include <linux/export.h> #include <linux/irq.h> +#include <linux/irqdomain.h>
#include "../pci.h" #include "msi.h"
int pci_msi_enable = 1; -int pci_msi_ignore_mask;
/** * pci_msi_supported - check whether MSI may be enabled on a device @@ -285,6 +285,8 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable) static int msi_setup_msi_desc(struct pci_dev *dev, int nvec, struct irq_affinity_desc *masks) { + const struct irq_domain *d = dev_get_msi_domain(&dev->dev); + const struct msi_domain_info *info = d->host_data; struct msi_desc desc; u16 control;
@@ -295,8 +297,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec, /* Lies, damned lies, and MSIs */ if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING) control |= PCI_MSI_FLAGS_MASKBIT; - /* Respect XEN's mask disabling */ - if (pci_msi_ignore_mask) + if (info->flags & MSI_FLAG_NO_MASK) control &= ~PCI_MSI_FLAGS_MASKBIT;
desc.nvec_used = nvec; @@ -604,12 +605,15 @@ static void __iomem *msix_map_region(struct pci_dev *dev, */ void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc) { + const struct irq_domain *d = dev_get_msi_domain(&dev->dev); + const struct msi_domain_info *info = d->host_data; + desc->nvec_used = 1; desc->pci.msi_attrib.is_msix = 1; desc->pci.msi_attrib.is_64 = 1; desc->pci.msi_attrib.default_irq = dev->irq; desc->pci.mask_base = dev->msix_base; - desc->pci.msi_attrib.can_mask = !pci_msi_ignore_mask && + desc->pci.msi_attrib.can_mask = !(info->flags & MSI_FLAG_NO_MASK) && !desc->pci.msi_attrib.is_virtual;
if (desc->pci.msi_attrib.can_mask) { @@ -659,9 +663,6 @@ static void msix_mask_all(void __iomem *base, int tsize) u32 ctrl = PCI_MSIX_ENTRY_CTRL_MASKBIT; int i;
- if (pci_msi_ignore_mask) - return; - for (i = 0; i < tsize; i++, base += PCI_MSIX_ENTRY_SIZE) writel(ctrl, base + PCI_MSIX_ENTRY_VECTOR_CTRL); } @@ -714,6 +715,8 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec, struct irq_affinity *affd) { + const struct irq_domain *d = dev_get_msi_domain(&dev->dev); + const struct msi_domain_info *info = d->host_data; int ret, tsize; u16 control;
@@ -744,15 +747,17 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, /* Disable INTX */ pci_intx_for_msi(dev, 0);
- /* - * Ensure that all table entries are masked to prevent - * stale entries from firing in a crash kernel. - * - * Done late to deal with a broken Marvell NVME device - * which takes the MSI-X mask bits into account even - * when MSI-X is disabled, which prevents MSI delivery. - */ - msix_mask_all(dev->msix_base, tsize); + if (!(info->flags & MSI_FLAG_NO_MASK)) { + /* + * Ensure that all table entries are masked to prevent + * stale entries from firing in a crash kernel. + * + * Done late to deal with a broken Marvell NVME device + * which takes the MSI-X mask bits into account even + * when MSI-X is disabled, which prevents MSI delivery. + */ + msix_mask_all(dev->msix_base, tsize); + } pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
pcibios_free_irq(dev); diff --git a/include/linux/msi.h b/include/linux/msi.h index b10093c4d00ea..59a421fc42bf0 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -73,7 +73,6 @@ struct msi_msg { }; };
-extern int pci_msi_ignore_mask; /* Helper functions */ struct msi_desc; struct pci_dev; @@ -556,6 +555,8 @@ enum { MSI_FLAG_PCI_MSIX_ALLOC_DYN = (1 << 20), /* PCI MSIs cannot be steered separately to CPU cores */ MSI_FLAG_NO_AFFINITY = (1 << 21), + /* Inhibit usage of entry masking */ + MSI_FLAG_NO_MASK = (1 << 22), };
/** diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c index 396a067a8a56b..7682c36cbccc6 100644 --- a/kernel/irq/msi.c +++ b/kernel/irq/msi.c @@ -1143,7 +1143,7 @@ static bool msi_check_reservation_mode(struct irq_domain *domain, if (!(info->flags & MSI_FLAG_MUST_REACTIVATE)) return false;
- if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_ignore_mask) + if (info->flags & MSI_FLAG_NO_MASK) return false;
/*
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner tglx@linutronix.de
[ Upstream commit 3ece3e8e5976c49c3f887e5923f998eabd54ff40 ]
The conversion of the XEN specific global variable pci_msi_ignore_mask to a MSI domain flag, missed the facts that:
1) Legacy architectures do not provide a interrupt domain 2) Parent MSI domains do not necessarily have a domain info attached
Both cases result in an unconditional NULL pointer dereference. This was unfortunatly missed in review and testing revealed it late.
Cure this by using the existing pci_msi_domain_supports() helper, which handles all possible cases correctly.
Fixes: c3164d2e0d18 ("PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag") Reported-by: Daniel Gomez da.gomez@kernel.org Reported-by: Borislav Petkov bp@alien8.de Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Juergen Gross jgross@suse.com Tested-by: Marek Szyprowski m.szyprowski@samsung.com Tested-by: Borislav Petkov bp@alien8.de Tested-by: Daniel Gomez da.gomez@kernel.org Link: https://lore.kernel.org/all/87iknwyp2o.ffs@tglx Closes: https://lore.kernel.org/all/qn7fzggcj6qe6r6gdbwcz23pzdz2jx64aldccmsuheabhmjg... Stable-dep-of: cf761e3dacc6 ("PCI/MSI: Add an option to write MSIX ENTRY_DATA before any reads") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/msi/msi.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-)
diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 4c8c2b57b5f61..6569ba3577fe6 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -285,8 +285,6 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable) static int msi_setup_msi_desc(struct pci_dev *dev, int nvec, struct irq_affinity_desc *masks) { - const struct irq_domain *d = dev_get_msi_domain(&dev->dev); - const struct msi_domain_info *info = d->host_data; struct msi_desc desc; u16 control;
@@ -297,7 +295,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec, /* Lies, damned lies, and MSIs */ if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING) control |= PCI_MSI_FLAGS_MASKBIT; - if (info->flags & MSI_FLAG_NO_MASK) + if (pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY)) control &= ~PCI_MSI_FLAGS_MASKBIT;
desc.nvec_used = nvec; @@ -605,20 +603,18 @@ static void __iomem *msix_map_region(struct pci_dev *dev, */ void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc) { - const struct irq_domain *d = dev_get_msi_domain(&dev->dev); - const struct msi_domain_info *info = d->host_data; - desc->nvec_used = 1; desc->pci.msi_attrib.is_msix = 1; desc->pci.msi_attrib.is_64 = 1; desc->pci.msi_attrib.default_irq = dev->irq; desc->pci.mask_base = dev->msix_base; - desc->pci.msi_attrib.can_mask = !(info->flags & MSI_FLAG_NO_MASK) && - !desc->pci.msi_attrib.is_virtual;
- if (desc->pci.msi_attrib.can_mask) { + + if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY) && + !desc->pci.msi_attrib.is_virtual) { void __iomem *addr = pci_msix_desc_addr(desc);
+ desc->pci.msi_attrib.can_mask = 1; desc->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); } } @@ -715,8 +711,6 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec, struct irq_affinity *affd) { - const struct irq_domain *d = dev_get_msi_domain(&dev->dev); - const struct msi_domain_info *info = d->host_data; int ret, tsize; u16 control;
@@ -747,7 +741,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, /* Disable INTX */ pci_intx_for_msi(dev, 0);
- if (!(info->flags & MSI_FLAG_NO_MASK)) { + if (!pci_msi_domain_supports(dev, MSI_FLAG_NO_MASK, DENY_LEGACY)) { /* * Ensure that all table entries are masked to prevent * stale entries from firing in a crash kernel.
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Currier dullfire@yahoo.com
[ Upstream commit cf761e3dacc6ad5f65a4886d00da1f9681e6805a ]
Commit 7d5ec3d36123 ("PCI/MSI: Mask all unused MSI-X entries") introduced a readl() from ENTRY_VECTOR_CTRL before the writel() to ENTRY_DATA.
This is correct, however some hardware, like the Sun Neptune chips, the NIU module, will cause an error and/or fatal trap if any MSIX table entry is read before the corresponding ENTRY_DATA field is written to.
Add an optional early writel() in msix_prepare_msi_desc().
Fixes: 7d5ec3d36123 ("PCI/MSI: Mask all unused MSI-X entries") Signed-off-by: Jonathan Currier dullfire@yahoo.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20241117234843.19236-2-dullfire@yahoo.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pci/msi/msi.c | 3 +++ include/linux/pci.h | 2 ++ 2 files changed, 5 insertions(+)
diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 6569ba3577fe6..8b88487886184 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -615,6 +615,9 @@ void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc) void __iomem *addr = pci_msix_desc_addr(desc);
desc->pci.msi_attrib.can_mask = 1; + /* Workaround for SUN NIU insanity, which requires write before read */ + if (dev->dev_flags & PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST) + writel(0, addr + PCI_MSIX_ENTRY_DATA); desc->pci.msix_ctrl = readl(addr + PCI_MSIX_ENTRY_VECTOR_CTRL); } } diff --git a/include/linux/pci.h b/include/linux/pci.h index 47b31ad724fa5..8e028620642f3 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -245,6 +245,8 @@ enum pci_dev_flags { PCI_DEV_FLAGS_NO_RELAXED_ORDERING = (__force pci_dev_flags_t) (1 << 11), /* Device does honor MSI masking despite saying otherwise */ PCI_DEV_FLAGS_HAS_MSI_MASKING = (__force pci_dev_flags_t) (1 << 12), + /* Device requires write to PCI_MSIX_ENTRY_DATA before any MSIX reads */ + PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST = (__force pci_dev_flags_t) (1 << 13), };
enum pci_irq_reroute_variant {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit f5de95438834a3bc3ad747f67c9da93cd08e5008 ]
Use devm_add_action_or_reset() for calling put_device in error path of rzv2h_icu_init() to simplify the code by using the recently added devm_* helpers.
Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Philipp Zabel p.zabel@pengutronix.de Link: https://lore.kernel.org/all/20250224131253.134199-5-biju.das.jz@bp.renesas.c... Stable-dep-of: 28e89cdac648 ("irqchip/renesas-rzv2h: Prevent TINT spurious interrupt") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-renesas-rzv2h.c | 37 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c index f6363246a71a0..6be38aa86f9b8 100644 --- a/drivers/irqchip/irq-renesas-rzv2h.c +++ b/drivers/irqchip/irq-renesas-rzv2h.c @@ -421,6 +421,11 @@ static int rzv2h_icu_parse_interrupts(struct rzv2h_icu_priv *priv, struct device return 0; }
+static void rzv2h_icu_put_device(void *data) +{ + put_device(data); +} + static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) { struct irq_domain *irq_domain, *parent_domain; @@ -433,43 +438,41 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) if (!pdev) return -ENODEV;
+ ret = devm_add_action_or_reset(&pdev->dev, rzv2h_icu_put_device, + &pdev->dev); + if (ret < 0) + return ret; + parent_domain = irq_find_host(parent); if (!parent_domain) { dev_err(&pdev->dev, "cannot find parent domain\n"); - ret = -ENODEV; - goto put_dev; + return -ENODEV; }
rzv2h_icu_data = devm_kzalloc(&pdev->dev, sizeof(*rzv2h_icu_data), GFP_KERNEL); - if (!rzv2h_icu_data) { - ret = -ENOMEM; - goto put_dev; - } + if (!rzv2h_icu_data) + return -ENOMEM;
rzv2h_icu_data->irqchip = &rzv2h_icu_chip;
rzv2h_icu_data->base = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); - if (IS_ERR(rzv2h_icu_data->base)) { - ret = PTR_ERR(rzv2h_icu_data->base); - goto put_dev; - } + if (IS_ERR(rzv2h_icu_data->base)) + return PTR_ERR(rzv2h_icu_data->base);
ret = rzv2h_icu_parse_interrupts(rzv2h_icu_data, node); if (ret) { dev_err(&pdev->dev, "cannot parse interrupts: %d\n", ret); - goto put_dev; + return ret; }
resetn = devm_reset_control_get_exclusive(&pdev->dev, NULL); - if (IS_ERR(resetn)) { - ret = PTR_ERR(resetn); - goto put_dev; - } + if (IS_ERR(resetn)) + return PTR_ERR(resetn);
ret = reset_control_deassert(resetn); if (ret) { dev_err(&pdev->dev, "failed to deassert resetn pin, %d\n", ret); - goto put_dev; + return ret; }
pm_runtime_enable(&pdev->dev); @@ -500,8 +503,6 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) pm_disable: pm_runtime_disable(&pdev->dev); reset_control_assert(resetn); -put_dev: - put_device(&pdev->dev);
return ret; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit 0a9d6ef64e5e917f93db98935cd09bac38507ebf ]
The ICU block on the RZ/G3E SoC is almost identical to the one found on the RZ/V2H SoC, with the following differences:
- The TINT register base offset is 0x800 instead of zero. - The number of GPIO interrupts for TINT selection is 141 instead of 86. - The pin index and TINT selection index are not in the 1:1 map - The number of TSSR registers is 16 instead of 8 - Each TSSR register can program 2 TINTs instead of 4 TINTs
Introduce struct rzv2h_hw_info to describe the SoC properties and refactor the code by moving rzv2h_icu_init() into rzv2h_icu_init_common() and pass the variable containing hw difference to support both these SoCs.
As a first step add t_offs to the new struct and replace the hardcoded constants in the code.
Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Reviewed-by: Fabrizio Castro fabrizio.castro.jz@renesas.com Reviewed-by: Tommaso Merciai tommaso.merciai.xr@bp.renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/all/20250224131253.134199-8-biju.das.jz@bp.renesas.c... Stable-dep-of: 28e89cdac648 ("irqchip/renesas-rzv2h: Prevent TINT spurious interrupt") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-renesas-rzv2h.c | 46 +++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 12 deletions(-)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c index 6be38aa86f9b8..5fcc6ed4086cd 100644 --- a/drivers/irqchip/irq-renesas-rzv2h.c +++ b/drivers/irqchip/irq-renesas-rzv2h.c @@ -80,18 +80,28 @@ #define ICU_TINT_EXTRACT_GPIOINT(x) FIELD_GET(GENMASK(31, 16), (x)) #define ICU_PB5_TINT 0x55
+/** + * struct rzv2h_hw_info - Interrupt Control Unit controller hardware info structure. + * @t_offs: TINT offset + */ +struct rzv2h_hw_info { + u16 t_offs; +}; + /** * struct rzv2h_icu_priv - Interrupt Control Unit controller private data structure. * @base: Controller's base address * @irqchip: Pointer to struct irq_chip * @fwspec: IRQ firmware specific data * @lock: Lock to serialize access to hardware registers + * @info: Pointer to struct rzv2h_hw_info */ struct rzv2h_icu_priv { void __iomem *base; const struct irq_chip *irqchip; struct irq_fwspec fwspec[ICU_NUM_IRQ]; raw_spinlock_t lock; + const struct rzv2h_hw_info *info; };
static inline struct rzv2h_icu_priv *irq_data_to_priv(struct irq_data *data) @@ -111,7 +121,7 @@ static void rzv2h_icu_eoi(struct irq_data *d) tintirq_nr = hw_irq - ICU_TINT_START; bit = BIT(tintirq_nr); if (!irqd_is_level_type(d)) - writel_relaxed(bit, priv->base + ICU_TSCLR); + writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR); } else if (hw_irq >= ICU_IRQ_START) { tintirq_nr = hw_irq - ICU_IRQ_START; bit = BIT(tintirq_nr); @@ -139,12 +149,12 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable) tssel_n = ICU_TSSR_TSSEL_N(tint_nr);
guard(raw_spinlock)(&priv->lock); - tssr = readl_relaxed(priv->base + ICU_TSSR(k)); + tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(k)); if (enable) tssr |= ICU_TSSR_TIEN(tssel_n); else tssr &= ~ICU_TSSR_TIEN(tssel_n); - writel_relaxed(tssr, priv->base + ICU_TSSR(k)); + writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k)); }
static void rzv2h_icu_irq_disable(struct irq_data *d) @@ -247,8 +257,8 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq u32 bit = BIT(tint_nr); int k = tint_nr / 16;
- tsctr = readl_relaxed(priv->base + ICU_TSCTR); - titsr = readl_relaxed(priv->base + ICU_TITSR(k)); + tsctr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSCTR); + titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(k)); titsel = ICU_TITSR_TITSEL_GET(titsr, titsel_n);
/* @@ -257,7 +267,7 @@ static void rzv2h_clear_tint_int(struct rzv2h_icu_priv *priv, unsigned int hwirq */ if ((tsctr & bit) && ((titsel == ICU_TINT_EDGE_RISING) || (titsel == ICU_TINT_EDGE_FALLING))) - writel_relaxed(bit, priv->base + ICU_TSCLR); + writel_relaxed(bit, priv->base + priv->info->t_offs + ICU_TSCLR); }
static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type) @@ -308,21 +318,21 @@ static int rzv2h_tint_set_type(struct irq_data *d, unsigned int type)
guard(raw_spinlock)(&priv->lock);
- tssr = readl_relaxed(priv->base + ICU_TSSR(tssr_k)); + tssr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TSSR(tssr_k)); tssr &= ~(ICU_TSSR_TSSEL_MASK(tssel_n) | tien); tssr |= ICU_TSSR_TSSEL_PREP(tint, tssel_n);
- writel_relaxed(tssr, priv->base + ICU_TSSR(tssr_k)); + writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
- titsr = readl_relaxed(priv->base + ICU_TITSR(titsr_k)); + titsr = readl_relaxed(priv->base + priv->info->t_offs + ICU_TITSR(titsr_k)); titsr &= ~ICU_TITSR_TITSEL_MASK(titsel_n); titsr |= ICU_TITSR_TITSEL_PREP(sense, titsel_n);
- writel_relaxed(titsr, priv->base + ICU_TITSR(titsr_k)); + writel_relaxed(titsr, priv->base + priv->info->t_offs + ICU_TITSR(titsr_k));
rzv2h_clear_tint_int(priv, hwirq);
- writel_relaxed(tssr | tien, priv->base + ICU_TSSR(tssr_k)); + writel_relaxed(tssr | tien, priv->base + priv->info->t_offs + ICU_TSSR(tssr_k));
return 0; } @@ -426,7 +436,8 @@ static void rzv2h_icu_put_device(void *data) put_device(data); }
-static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) +static int rzv2h_icu_init_common(struct device_node *node, struct device_node *parent, + const struct rzv2h_hw_info *hw_info) { struct irq_domain *irq_domain, *parent_domain; struct rzv2h_icu_priv *rzv2h_icu_data; @@ -492,6 +503,8 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) goto pm_put; }
+ rzv2h_icu_data->info = hw_info; + /* * coccicheck complains about a missing put_device call before returning, but it's a false * positive. We still need &pdev->dev after successfully returning from this function. @@ -507,6 +520,15 @@ static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) return ret; }
+static const struct rzv2h_hw_info rzv2h_hw_params = { + .t_offs = 0, +}; + +static int rzv2h_icu_init(struct device_node *node, struct device_node *parent) +{ + return rzv2h_icu_init_common(node, parent, &rzv2h_hw_params); +} + IRQCHIP_PLATFORM_DRIVER_BEGIN(rzv2h_icu) IRQCHIP_MATCH("renesas,r9a09g057-icu", rzv2h_icu_init) IRQCHIP_PLATFORM_DRIVER_END(rzv2h_icu)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit 28e89cdac6482f3c980df3e2e245db7366269124 ]
A spurious TINT interrupt is seen during boot on RZ/G3E SMARC EVK.
A glitch in the edge detection circuit can cause a spurious interrupt.
Clear the status flag after setting the ICU_TSSRk registers, which is recommended in the hardware manual as a countermeasure.
Fixes: 0d7605e75ac2 ("irqchip: Add RZ/V2H(P) Interrupt Control Unit (ICU) driver") Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/irqchip/irq-renesas-rzv2h.c | 8 ++++++++ 1 file changed, 8 insertions(+)
diff --git a/drivers/irqchip/irq-renesas-rzv2h.c b/drivers/irqchip/irq-renesas-rzv2h.c index 5fcc6ed4086cd..21d01ce2da5cf 100644 --- a/drivers/irqchip/irq-renesas-rzv2h.c +++ b/drivers/irqchip/irq-renesas-rzv2h.c @@ -155,6 +155,14 @@ static void rzv2h_tint_irq_endisable(struct irq_data *d, bool enable) else tssr &= ~ICU_TSSR_TIEN(tssel_n); writel_relaxed(tssr, priv->base + priv->info->t_offs + ICU_TSSR(k)); + + /* + * A glitch in the edge detection circuit can cause a spurious + * interrupt. Clear the status flag after setting the ICU_TSSRk + * registers, which is recommended by the hardware manual as a + * countermeasure. + */ + writel_relaxed(BIT(tint_nr), priv->base + priv->info->t_offs + ICU_TSCLR); }
static void rzv2h_icu_irq_disable(struct irq_data *d)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Currier dullfire@yahoo.com
[ Upstream commit fbb429ddff5c8e479edcc7dde5a542c9295944e6 ]
Fix niu_try_msix() to not cause a fatal trap on sparc systems.
Set PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST on the struct pci_dev to work around a bug in the hardware or firmware.
For each vector entry in the msix table, niu chips will cause a fatal trap if any registers in that entry are read before that entries' ENTRY_DATA register is written to. Testing indicates writes to other registers are not sufficient to prevent the fatal trap, however the value does not appear to matter. This only needs to happen once after power up, so simply rebooting into a kernel lacking this fix will NOT cause the trap.
NON-RESUMABLE ERROR: Reporting on cpu 64 NON-RESUMABLE ERROR: TPC [0x00000000005f6900] <msix_prepare_msi_desc+0x90/0xa0> NON-RESUMABLE ERROR: RAW [4010000000000016:00000e37f93e32ff:0000000202000080:ffffffffffffffff NON-RESUMABLE ERROR: 0000000800000000:0000000000000000:0000000000000000:0000000000000000] NON-RESUMABLE ERROR: handle [0x4010000000000016] stick [0x00000e37f93e32ff] NON-RESUMABLE ERROR: type [precise nonresumable] NON-RESUMABLE ERROR: attrs [0x02000080] < ASI sp-faulted priv > NON-RESUMABLE ERROR: raddr [0xffffffffffffffff] NON-RESUMABLE ERROR: insn effective address [0x000000c50020000c] NON-RESUMABLE ERROR: size [0x8] NON-RESUMABLE ERROR: asi [0x00] CPU: 64 UID: 0 PID: 745 Comm: kworker/64:1 Not tainted 6.11.5 #63 Workqueue: events work_for_cpu_fn TSTATE: 0000000011001602 TPC: 00000000005f6900 TNPC: 00000000005f6904 Y: 00000000 Not tainted TPC: <msix_prepare_msi_desc+0x90/0xa0> g0: 00000000000002e9 g1: 000000000000000c g2: 000000c50020000c g3: 0000000000000100 g4: ffff8000470307c0 g5: ffff800fec5be000 g6: ffff800047a08000 g7: 0000000000000000 o0: ffff800014feb000 o1: ffff800047a0b620 o2: 0000000000000011 o3: ffff800047a0b620 o4: 0000000000000080 o5: 0000000000000011 sp: ffff800047a0ad51 ret_pc: 00000000005f7128 RPC: <__pci_enable_msix_range+0x3cc/0x460> l0: 000000000000000d l1: 000000000000c01f l2: ffff800014feb0a8 l3: 0000000000000020 l4: 000000000000c000 l5: 0000000000000001 l6: 0000000020000000 l7: ffff800047a0b734 i0: ffff800014feb000 i1: ffff800047a0b730 i2: 0000000000000001 i3: 000000000000000d i4: 0000000000000000 i5: 0000000000000000 i6: ffff800047a0ae81 i7: 00000000101888b0 I7: <niu_try_msix.constprop.0+0xc0/0x130 [niu]> Call Trace: [<00000000101888b0>] niu_try_msix.constprop.0+0xc0/0x130 [niu] [<000000001018f840>] niu_get_invariants+0x183c/0x207c [niu] [<00000000101902fc>] niu_pci_init_one+0x27c/0x2fc [niu] [<00000000005ef3e4>] local_pci_probe+0x28/0x74 [<0000000000469240>] work_for_cpu_fn+0x8/0x1c [<000000000046b008>] process_scheduled_works+0x144/0x210 [<000000000046b518>] worker_thread+0x13c/0x1c0 [<00000000004710e0>] kthread+0xb8/0xc8 [<00000000004060c8>] ret_from_fork+0x1c/0x2c [<0000000000000000>] 0x0 Kernel panic - not syncing: Non-resumable error.
Fixes: 7d5ec3d36123 ("PCI/MSI: Mask all unused MSI-X entries") Signed-off-by: Jonathan Currier dullfire@yahoo.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Cc: stable@vger.kernel.org Link: https://lore.kernel.org/all/20241117234843.19236-3-dullfire@yahoo.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/sun/niu.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index 72177fea1cfb3..edc3165f00774 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c @@ -9064,6 +9064,8 @@ static void niu_try_msix(struct niu *np, u8 *ldg_num_map) msi_vec[i].entry = i; }
+ pdev->dev_flags |= PCI_DEV_FLAGS_MSIX_TOUCH_ENTRY_DATA_FIRST; + num_irqs = pci_enable_msix_range(pdev, msi_vec, 1, num_irqs); if (num_irqs < 0) { np->flags &= ~NIU_FLAGS_MSIX;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nirmoy Das nirmoy.das@intel.com
[ Upstream commit 92029e0baa5313ba208103f90086f59070bbf93b ]
Enable WMTP for the BTD kernel to address Wa14023061436 by setting the proper TDL Chicken Bit.
v2: Apply it on engine_was[] as this register is not part of LRC(Matt) Apply it for first_render_or_compute in case this gets extended to compute only platforms(Matt).
Cc: Gustavo Sousa gustavo.sousa@intel.com Cc: Matt Roper matthew.d.roper@intel.com Reviewed-by: Matt Roper matthew.d.roper@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20250108141323.311601-1-nirmoy... Signed-off-by: Nirmoy Das nirmoy.das@intel.com Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 3 +++ drivers/gpu/drm/xe/xe_wa.c | 5 +++++ 2 files changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index 162f18e975dae..b4283ac030f41 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -500,6 +500,9 @@ #define LSC_L1_FLUSH_CTL_3D_DATAPORT_FLUSH_EVENTS_MASK REG_GENMASK(13, 11) #define DIS_ATOMIC_CHAINING_TYPED_WRITES REG_BIT(3)
+#define TDL_CHICKEN XE_REG_MCR(0xe5f4, XE_REG_OPTION_MASKED) +#define QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE REG_BIT(12) + #define LSC_CHICKEN_BIT_0 XE_REG_MCR(0xe7c8) #define DISABLE_D8_D16_COASLESCE REG_BIT(30) #define WR_REQ_CHAINING_DIS REG_BIT(26) diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index 2553accf8c517..ac471e2454d34 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -613,6 +613,11 @@ static const struct xe_rtp_entry_sr engine_was[] = { XE_RTP_ACTIONS(FIELD_SET(SAMPLER_MODE, SMP_WAIT_FETCH_MERGING_COUNTER, SMP_FORCE_128B_OVERFETCH)) }, + { XE_RTP_NAME("14023061436"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001), + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(TDL_CHICKEN, QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE)) + },
{} };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejas Upadhyay tejas.upadhyay@intel.com
[ Upstream commit 2399bcc07c01189737858e0a88ac4ffdd1d4b03d ]
Wa_13012615864 applies to xe3lpg
Reviewed-by: Matt Roper matthew.d.roper@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20250221112200.388612-1-tejas.... Signed-off-by: Tejas Upadhyay tejas.upadhyay@intel.com Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/regs/xe_gt_regs.h | 1 + drivers/gpu/drm/xe/xe_wa.c | 5 +++++ 2 files changed, 6 insertions(+)
diff --git a/drivers/gpu/drm/xe/regs/xe_gt_regs.h b/drivers/gpu/drm/xe/regs/xe_gt_regs.h index b4283ac030f41..d0ea8a55fd9c2 100644 --- a/drivers/gpu/drm/xe/regs/xe_gt_regs.h +++ b/drivers/gpu/drm/xe/regs/xe_gt_regs.h @@ -475,6 +475,7 @@ #define TDL_TSL_CHICKEN XE_REG_MCR(0xe4c4, XE_REG_OPTION_MASKED) #define STK_ID_RESTRICT REG_BIT(12) #define SLM_WMTP_RESTORE REG_BIT(11) +#define RES_CHK_SPR_DIS REG_BIT(6)
#define ROW_CHICKEN XE_REG_MCR(0xe4f0, XE_REG_OPTION_MASKED) #define UGM_BACKUP_MODE REG_BIT(13) diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index ac471e2454d34..db99663963010 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -618,6 +618,11 @@ static const struct xe_rtp_entry_sr engine_was[] = { FUNC(xe_rtp_match_first_render_or_compute)), XE_RTP_ACTIONS(SET(TDL_CHICKEN, QID_WAIT_FOR_THREAD_NOT_RUN_DISABLE)) }, + { XE_RTP_NAME("13012615864"), + XE_RTP_RULES(GRAPHICS_VERSION_RANGE(3000, 3001), + FUNC(xe_rtp_match_first_render_or_compute)), + XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS)) + },
{} };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tvrtko Ursulin tvrtko.ursulin@igalia.com
[ Upstream commit 067a974fd8a9ea43f97ca184e2768b583f2f8c44 ]
Add a list of active tunings to debugfs, analogous to the existing list of workarounds.
Rationale being that it seems to make sense to either have both or none.
Signed-off-by: Tvrtko Ursulin tvrtko.ursulin@igalia.com Cc: Lucas De Marchi lucas.demarchi@intel.com Cc: Matt Roper matthew.d.roper@intel.com Reviewed-by: Lucas De Marchi lucas.demarchi@intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20250227101304.46660-6-tvrtko.... Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_gt.c | 4 ++ drivers/gpu/drm/xe/xe_gt_debugfs.c | 11 ++++++ drivers/gpu/drm/xe/xe_gt_types.h | 10 +++++ drivers/gpu/drm/xe/xe_tuning.c | 59 ++++++++++++++++++++++++++++++ drivers/gpu/drm/xe/xe_tuning.h | 3 ++ 5 files changed, 87 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_gt.c b/drivers/gpu/drm/xe/xe_gt.c index 8a20e6744836c..94eed1315b0f1 100644 --- a/drivers/gpu/drm/xe/xe_gt.c +++ b/drivers/gpu/drm/xe/xe_gt.c @@ -381,6 +381,10 @@ int xe_gt_init_early(struct xe_gt *gt) if (err) return err;
+ err = xe_tuning_init(gt); + if (err) + return err; + xe_wa_process_oob(gt);
xe_force_wake_init_gt(gt, gt_to_fw(gt)); diff --git a/drivers/gpu/drm/xe/xe_gt_debugfs.c b/drivers/gpu/drm/xe/xe_gt_debugfs.c index e7792858b1e46..2d63a69cbfa38 100644 --- a/drivers/gpu/drm/xe/xe_gt_debugfs.c +++ b/drivers/gpu/drm/xe/xe_gt_debugfs.c @@ -30,6 +30,7 @@ #include "xe_reg_sr.h" #include "xe_reg_whitelist.h" #include "xe_sriov.h" +#include "xe_tuning.h" #include "xe_uc_debugfs.h" #include "xe_wa.h"
@@ -217,6 +218,15 @@ static int workarounds(struct xe_gt *gt, struct drm_printer *p) return 0; }
+static int tunings(struct xe_gt *gt, struct drm_printer *p) +{ + xe_pm_runtime_get(gt_to_xe(gt)); + xe_tuning_dump(gt, p); + xe_pm_runtime_put(gt_to_xe(gt)); + + return 0; +} + static int pat(struct xe_gt *gt, struct drm_printer *p) { xe_pm_runtime_get(gt_to_xe(gt)); @@ -300,6 +310,7 @@ static const struct drm_info_list debugfs_list[] = { {"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info}, {"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore}, {"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds}, + {"tunings", .show = xe_gt_debugfs_simple_show, .data = tunings}, {"pat", .show = xe_gt_debugfs_simple_show, .data = pat}, {"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs}, {"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data = rcs_default_lrc}, diff --git a/drivers/gpu/drm/xe/xe_gt_types.h b/drivers/gpu/drm/xe/xe_gt_types.h index 6e66bf0e8b3f7..dd2969a1846dd 100644 --- a/drivers/gpu/drm/xe/xe_gt_types.h +++ b/drivers/gpu/drm/xe/xe_gt_types.h @@ -413,6 +413,16 @@ struct xe_gt { bool oob_initialized; } wa_active;
+ /** @tuning_active: keep track of active tunings */ + struct { + /** @tuning_active.gt: bitmap with active GT tunings */ + unsigned long *gt; + /** @tuning_active.engine: bitmap with active engine tunings */ + unsigned long *engine; + /** @tuning_active.lrc: bitmap with active LRC tunings */ + unsigned long *lrc; + } tuning_active; + /** @user_engines: engines present in GT and available to userspace */ struct { /** diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index 3c78f3d715591..23c46dd85e149 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -7,6 +7,8 @@
#include <kunit/visibility.h>
+#include <drm/drm_managed.h> + #include "regs/xe_gt_regs.h" #include "xe_gt_types.h" #include "xe_platform_types.h" @@ -135,10 +137,44 @@ static const struct xe_rtp_entry_sr lrc_tunings[] = { {} };
+/** + * xe_tuning_init - initialize gt with tunings bookkeeping + * @gt: GT instance to initialize + * + * Returns 0 for success, negative error code otherwise. + */ +int xe_tuning_init(struct xe_gt *gt) +{ + struct xe_device *xe = gt_to_xe(gt); + size_t n_lrc, n_engine, n_gt, total; + unsigned long *p; + + n_gt = BITS_TO_LONGS(ARRAY_SIZE(gt_tunings)); + n_engine = BITS_TO_LONGS(ARRAY_SIZE(engine_tunings)); + n_lrc = BITS_TO_LONGS(ARRAY_SIZE(lrc_tunings)); + total = n_gt + n_engine + n_lrc; + + p = drmm_kzalloc(&xe->drm, sizeof(*p) * total, GFP_KERNEL); + if (!p) + return -ENOMEM; + + gt->tuning_active.gt = p; + p += n_gt; + gt->tuning_active.engine = p; + p += n_engine; + gt->tuning_active.lrc = p; + + return 0; +} +ALLOW_ERROR_INJECTION(xe_tuning_init, ERRNO); /* See xe_pci_probe() */ + void xe_tuning_process_gt(struct xe_gt *gt) { struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(gt);
+ xe_rtp_process_ctx_enable_active_tracking(&ctx, + gt->tuning_active.gt, + ARRAY_SIZE(gt_tunings)); xe_rtp_process_to_sr(&ctx, gt_tunings, >->reg_sr); } EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt); @@ -147,6 +183,9 @@ void xe_tuning_process_engine(struct xe_hw_engine *hwe) { struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
+ xe_rtp_process_ctx_enable_active_tracking(&ctx, + hwe->gt->tuning_active.engine, + ARRAY_SIZE(engine_tunings)); xe_rtp_process_to_sr(&ctx, engine_tunings, &hwe->reg_sr); } EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_engine); @@ -163,5 +202,25 @@ void xe_tuning_process_lrc(struct xe_hw_engine *hwe) { struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
+ xe_rtp_process_ctx_enable_active_tracking(&ctx, + hwe->gt->tuning_active.lrc, + ARRAY_SIZE(lrc_tunings)); xe_rtp_process_to_sr(&ctx, lrc_tunings, &hwe->reg_lrc); } + +void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p) +{ + size_t idx; + + drm_printf(p, "GT Tunings\n"); + for_each_set_bit(idx, gt->tuning_active.gt, ARRAY_SIZE(gt_tunings)) + drm_printf_indent(p, 1, "%s\n", gt_tunings[idx].name); + + drm_printf(p, "\nEngine Tunings\n"); + for_each_set_bit(idx, gt->tuning_active.engine, ARRAY_SIZE(engine_tunings)) + drm_printf_indent(p, 1, "%s\n", engine_tunings[idx].name); + + drm_printf(p, "\nLRC Tunings\n"); + for_each_set_bit(idx, gt->tuning_active.lrc, ARRAY_SIZE(lrc_tunings)) + drm_printf_indent(p, 1, "%s\n", lrc_tunings[idx].name); +} diff --git a/drivers/gpu/drm/xe/xe_tuning.h b/drivers/gpu/drm/xe/xe_tuning.h index 4f9c3ac3b5162..dd0d3ccc9c654 100644 --- a/drivers/gpu/drm/xe/xe_tuning.h +++ b/drivers/gpu/drm/xe/xe_tuning.h @@ -6,11 +6,14 @@ #ifndef _XE_TUNING_ #define _XE_TUNING_
+struct drm_printer; struct xe_gt; struct xe_hw_engine;
+int xe_tuning_init(struct xe_gt *gt); void xe_tuning_process_gt(struct xe_gt *gt); void xe_tuning_process_engine(struct xe_hw_engine *hwe); void xe_tuning_process_lrc(struct xe_hw_engine *hwe); +void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p);
#endif
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lucas De Marchi lucas.demarchi@intel.com
[ Upstream commit cedf23842d7433eb32cb782a637bb870fb096a3b ]
There's a mismatch on API: while xe_rtp_process_to_sr() processes entries until an entry without name, the active tracking with xe_rtp_process_ctx_enable_active_tracking() needs to use the number of elements. The number of elements is taken everywhere using ARRAY_SIZE(), but that will have one entry too many. This leads to the following warning, as reported by lkp:
drivers/gpu/drm/xe/xe_tuning.c: In function 'xe_tuning_dump':
include/drm/drm_print.h:228:31: warning: '%s' directive argument is null [-Wformat-overflow=]
228 | drm_printf((printer), "%.*s" fmt, (indent), "\t\t\t\t\tX", ##__VA_ARGS__) | ^~~~~~ drivers/gpu/drm/xe/xe_tuning.c:226:17: note: in expansion of macro 'drm_printf_indent' 226 | drm_printf_indent(p, 1, "%s\n", engine_tunings[idx].name); | ^~~~~~~~~~~~~~~~~
That's because it will still process the last entry when tracking the active tunings. The same issue exists in the WAs. Change xe_rtp_process_to_sr() to also take the number of elements so the empty entry can be removed and the warning should go away. Fixing on the active-tracking side would more fragile as the it would need a `- 1` everywhere and continue to use a different approach for number of elements.
Aside from the warning, it's a non-issue as there would always be enough bits allocated and the last entry would never be active since xe_rtp_process_to_sr() stops on the sentinel.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202503021906.P2MwAvyK-lkp@intel.com/ Cc: Tvrtko Ursulin tvrtko.ursulin@igalia.com Reviewed-by: Tvrtko Ursulin tvrtko.ursulin@igalia.com Link: https://patchwork.freedesktop.org/patch/msgid/20250306-fix-print-warning-v1-... Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com (cherry picked from commit 8aa8c2d4214e1771c32101d70740002662d31bb7) Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com Stable-dep-of: 262de94a3a7e ("drm/xe: Ensure fixed_slice_mode gets set after ccs_mode change") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/tests/xe_rtp_test.c | 2 +- drivers/gpu/drm/xe/xe_hw_engine.c | 6 ++---- drivers/gpu/drm/xe/xe_reg_whitelist.c | 4 ++-- drivers/gpu/drm/xe/xe_rtp.c | 6 +++++- drivers/gpu/drm/xe/xe_rtp.h | 2 +- drivers/gpu/drm/xe/xe_tuning.c | 12 ++++-------- drivers/gpu/drm/xe/xe_wa.c | 12 +++--------- 7 files changed, 18 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/xe/tests/xe_rtp_test.c b/drivers/gpu/drm/xe/tests/xe_rtp_test.c index 36a3b5420fef6..b0254b014fe45 100644 --- a/drivers/gpu/drm/xe/tests/xe_rtp_test.c +++ b/drivers/gpu/drm/xe/tests/xe_rtp_test.c @@ -320,7 +320,7 @@ static void xe_rtp_process_to_sr_tests(struct kunit *test) count_rtp_entries++;
xe_rtp_process_ctx_enable_active_tracking(&ctx, &active, count_rtp_entries); - xe_rtp_process_to_sr(&ctx, param->entries, reg_sr); + xe_rtp_process_to_sr(&ctx, param->entries, count_rtp_entries, reg_sr);
xa_for_each(®_sr->xa, idx, sre) { if (idx == param->expected_reg.addr) diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index fc447751fe786..223b95de388cb 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -400,10 +400,9 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe) PREEMPT_GPGPU_THREAD_GROUP_LEVEL)), XE_RTP_ENTRY_FLAG(FOREACH_ENGINE) }, - {} };
- xe_rtp_process_to_sr(&ctx, lrc_setup, &hwe->reg_lrc); + xe_rtp_process_to_sr(&ctx, lrc_setup, ARRAY_SIZE(lrc_setup), &hwe->reg_lrc); }
static void @@ -459,10 +458,9 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe) XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), CS_PRIORITY_MEM_READ, XE_RTP_ACTION_FLAG(ENGINE_BASE))) }, - {} };
- xe_rtp_process_to_sr(&ctx, engine_entries, &hwe->reg_sr); + xe_rtp_process_to_sr(&ctx, engine_entries, ARRAY_SIZE(engine_entries), &hwe->reg_sr); }
static const struct engine_info *find_engine_info(enum xe_engine_class class, int instance) diff --git a/drivers/gpu/drm/xe/xe_reg_whitelist.c b/drivers/gpu/drm/xe/xe_reg_whitelist.c index edab5d4e3ba5e..23f6c81d99946 100644 --- a/drivers/gpu/drm/xe/xe_reg_whitelist.c +++ b/drivers/gpu/drm/xe/xe_reg_whitelist.c @@ -88,7 +88,6 @@ static const struct xe_rtp_entry_sr register_whitelist[] = { RING_FORCE_TO_NONPRIV_ACCESS_RD | RING_FORCE_TO_NONPRIV_RANGE_4)) }, - {} };
static void whitelist_apply_to_hwe(struct xe_hw_engine *hwe) @@ -137,7 +136,8 @@ void xe_reg_whitelist_process_engine(struct xe_hw_engine *hwe) { struct xe_rtp_process_ctx ctx = XE_RTP_PROCESS_CTX_INITIALIZER(hwe);
- xe_rtp_process_to_sr(&ctx, register_whitelist, &hwe->reg_whitelist); + xe_rtp_process_to_sr(&ctx, register_whitelist, ARRAY_SIZE(register_whitelist), + &hwe->reg_whitelist); whitelist_apply_to_hwe(hwe); }
diff --git a/drivers/gpu/drm/xe/xe_rtp.c b/drivers/gpu/drm/xe/xe_rtp.c index 7a1c78fdfc92e..13bb62d3e615e 100644 --- a/drivers/gpu/drm/xe/xe_rtp.c +++ b/drivers/gpu/drm/xe/xe_rtp.c @@ -237,6 +237,7 @@ static void rtp_mark_active(struct xe_device *xe, * the save-restore argument. * @ctx: The context for processing the table, with one of device, gt or hwe * @entries: Table with RTP definitions + * @n_entries: Number of entries to process, usually ARRAY_SIZE(entries) * @sr: Save-restore struct where matching rules execute the action. This can be * viewed as the "coalesced view" of multiple the tables. The bits for each * register set are expected not to collide with previously added entries @@ -247,6 +248,7 @@ static void rtp_mark_active(struct xe_device *xe, */ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx, const struct xe_rtp_entry_sr *entries, + size_t n_entries, struct xe_reg_sr *sr) { const struct xe_rtp_entry_sr *entry; @@ -259,7 +261,9 @@ void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx, if (IS_SRIOV_VF(xe)) return;
- for (entry = entries; entry && entry->name; entry++) { + xe_assert(xe, entries); + + for (entry = entries; entry - entries < n_entries; entry++) { bool match = false;
if (entry->flags & XE_RTP_ENTRY_FLAG_FOREACH_ENGINE) { diff --git a/drivers/gpu/drm/xe/xe_rtp.h b/drivers/gpu/drm/xe/xe_rtp.h index 38b9f13bba5e5..4fe736a11c42b 100644 --- a/drivers/gpu/drm/xe/xe_rtp.h +++ b/drivers/gpu/drm/xe/xe_rtp.h @@ -430,7 +430,7 @@ void xe_rtp_process_ctx_enable_active_tracking(struct xe_rtp_process_ctx *ctx,
void xe_rtp_process_to_sr(struct xe_rtp_process_ctx *ctx, const struct xe_rtp_entry_sr *entries, - struct xe_reg_sr *sr); + size_t n_entries, struct xe_reg_sr *sr);
void xe_rtp_process(struct xe_rtp_process_ctx *ctx, const struct xe_rtp_entry *entries); diff --git a/drivers/gpu/drm/xe/xe_tuning.c b/drivers/gpu/drm/xe/xe_tuning.c index 23c46dd85e149..a61a2917590fe 100644 --- a/drivers/gpu/drm/xe/xe_tuning.c +++ b/drivers/gpu/drm/xe/xe_tuning.c @@ -85,8 +85,6 @@ static const struct xe_rtp_entry_sr gt_tunings[] = { XE_RTP_RULES(MEDIA_VERSION(2000)), XE_RTP_ACTIONS(SET(XE2LPM_SCRATCH3_LBCF, RWFLUSHALLEN)) }, - - {} };
static const struct xe_rtp_entry_sr engine_tunings[] = { @@ -95,7 +93,6 @@ static const struct xe_rtp_entry_sr engine_tunings[] = { ENGINE_CLASS(RENDER)), XE_RTP_ACTIONS(SET(SAMPLER_MODE, INDIRECT_STATE_BASE_ADDR_OVERRIDE)) }, - {} };
static const struct xe_rtp_entry_sr lrc_tunings[] = { @@ -133,8 +130,6 @@ static const struct xe_rtp_entry_sr lrc_tunings[] = { XE_RTP_ACTIONS(FIELD_SET(FF_MODE, VS_HIT_MAX_VALUE_MASK, REG_FIELD_PREP(VS_HIT_MAX_VALUE_MASK, 0x3f))) }, - - {} };
/** @@ -175,7 +170,7 @@ void xe_tuning_process_gt(struct xe_gt *gt) xe_rtp_process_ctx_enable_active_tracking(&ctx, gt->tuning_active.gt, ARRAY_SIZE(gt_tunings)); - xe_rtp_process_to_sr(&ctx, gt_tunings, >->reg_sr); + xe_rtp_process_to_sr(&ctx, gt_tunings, ARRAY_SIZE(gt_tunings), >->reg_sr); } EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_gt);
@@ -186,7 +181,8 @@ void xe_tuning_process_engine(struct xe_hw_engine *hwe) xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->tuning_active.engine, ARRAY_SIZE(engine_tunings)); - xe_rtp_process_to_sr(&ctx, engine_tunings, &hwe->reg_sr); + xe_rtp_process_to_sr(&ctx, engine_tunings, ARRAY_SIZE(engine_tunings), + &hwe->reg_sr); } EXPORT_SYMBOL_IF_KUNIT(xe_tuning_process_engine);
@@ -205,7 +201,7 @@ void xe_tuning_process_lrc(struct xe_hw_engine *hwe) xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->tuning_active.lrc, ARRAY_SIZE(lrc_tunings)); - xe_rtp_process_to_sr(&ctx, lrc_tunings, &hwe->reg_lrc); + xe_rtp_process_to_sr(&ctx, lrc_tunings, ARRAY_SIZE(lrc_tunings), &hwe->reg_lrc); }
void xe_tuning_dump(struct xe_gt *gt, struct drm_printer *p) diff --git a/drivers/gpu/drm/xe/xe_wa.c b/drivers/gpu/drm/xe/xe_wa.c index db99663963010..65bfb2f894d00 100644 --- a/drivers/gpu/drm/xe/xe_wa.c +++ b/drivers/gpu/drm/xe/xe_wa.c @@ -279,8 +279,6 @@ static const struct xe_rtp_entry_sr gt_was[] = { XE_RTP_ACTIONS(SET(VDBOX_CGCTL3F10(0), RAMDFTUNIT_CLKGATE_DIS)), XE_RTP_ENTRY_FLAG(FOREACH_ENGINE), }, - - {} };
static const struct xe_rtp_entry_sr engine_was[] = { @@ -623,8 +621,6 @@ static const struct xe_rtp_entry_sr engine_was[] = { FUNC(xe_rtp_match_first_render_or_compute)), XE_RTP_ACTIONS(SET(TDL_TSL_CHICKEN, RES_CHK_SPR_DIS)) }, - - {} };
static const struct xe_rtp_entry_sr lrc_was[] = { @@ -817,8 +813,6 @@ static const struct xe_rtp_entry_sr lrc_was[] = { DIS_PARTIAL_AUTOSTRIP | DIS_AUTOSTRIP)) }, - - {} };
static __maybe_unused const struct xe_rtp_entry oob_was[] = { @@ -860,7 +854,7 @@ void xe_wa_process_gt(struct xe_gt *gt)
xe_rtp_process_ctx_enable_active_tracking(&ctx, gt->wa_active.gt, ARRAY_SIZE(gt_was)); - xe_rtp_process_to_sr(&ctx, gt_was, >->reg_sr); + xe_rtp_process_to_sr(&ctx, gt_was, ARRAY_SIZE(gt_was), >->reg_sr); } EXPORT_SYMBOL_IF_KUNIT(xe_wa_process_gt);
@@ -878,7 +872,7 @@ void xe_wa_process_engine(struct xe_hw_engine *hwe)
xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.engine, ARRAY_SIZE(engine_was)); - xe_rtp_process_to_sr(&ctx, engine_was, &hwe->reg_sr); + xe_rtp_process_to_sr(&ctx, engine_was, ARRAY_SIZE(engine_was), &hwe->reg_sr); }
/** @@ -895,7 +889,7 @@ void xe_wa_process_lrc(struct xe_hw_engine *hwe)
xe_rtp_process_ctx_enable_active_tracking(&ctx, hwe->gt->wa_active.lrc, ARRAY_SIZE(lrc_was)); - xe_rtp_process_to_sr(&ctx, lrc_was, &hwe->reg_lrc); + xe_rtp_process_to_sr(&ctx, lrc_was, ARRAY_SIZE(lrc_was), &hwe->reg_lrc); }
/**
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niranjana Vishwanathapura niranjana.vishwanathapura@intel.com
[ Upstream commit 262de94a3a7ef23c326534b3d9483602b7af841e ]
The RCU_MODE_FIXED_SLICE_CCS_MODE setting is not getting invoked in the gt reset path after the ccs_mode setting by the user. Add it to engine register update list (in hw_engine_setup_default_state()) which ensures it gets set in the gt reset and engine reset paths.
v2: Add register update to engine list to ensure it gets updated after engine reset also.
Fixes: 0d97ecce16bd ("drm/xe: Enable Fixed CCS mode setting") Cc: stable@vger.kernel.org Signed-off-by: Niranjana Vishwanathapura niranjana.vishwanathapura@intel.com Reviewed-by: Matt Roper matthew.d.roper@intel.com Signed-off-by: Matthew Brost matthew.brost@intel.com Link: https://lore.kernel.org/r/20250327185604.18230-1-niranjana.vishwanathapura@i... (cherry picked from commit 12468e519f98e4d93370712e3607fab61df9dae9) Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_hw_engine.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_hw_engine.c b/drivers/gpu/drm/xe/xe_hw_engine.c index 223b95de388cb..b26b6fb5cdb5d 100644 --- a/drivers/gpu/drm/xe/xe_hw_engine.c +++ b/drivers/gpu/drm/xe/xe_hw_engine.c @@ -386,12 +386,6 @@ xe_hw_engine_setup_default_lrc_state(struct xe_hw_engine *hwe) blit_cctl_val, XE_RTP_ACTION_FLAG(ENGINE_BASE))) }, - /* Use Fixed slice CCS mode */ - { XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"), - XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)), - XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE, - RCU_MODE_FIXED_SLICE_CCS_MODE)) - }, /* Disable WMTP if HW doesn't support it */ { XE_RTP_NAME("DISABLE_WMTP_ON_UNSUPPORTED_HW"), XE_RTP_RULES(FUNC(xe_rtp_cfeg_wmtp_disabled)), @@ -458,6 +452,12 @@ hw_engine_setup_default_state(struct xe_hw_engine *hwe) XE_RTP_ACTIONS(SET(CSFE_CHICKEN1(0), CS_PRIORITY_MEM_READ, XE_RTP_ACTION_FLAG(ENGINE_BASE))) }, + /* Use Fixed slice CCS mode */ + { XE_RTP_NAME("RCU_MODE_FIXED_SLICE_CCS_MODE"), + XE_RTP_RULES(FUNC(xe_hw_engine_match_fixed_cslice_mode)), + XE_RTP_ACTIONS(FIELD_SET(RCU_MODE, RCU_MODE_FIXED_SLICE_CCS_MODE, + RCU_MODE_FIXED_SLICE_CCS_MODE)) + }, };
xe_rtp_process_to_sr(&ctx, engine_entries, ARRAY_SIZE(engine_entries), &hwe->reg_sr);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor nathan@kernel.org
commit cdc2e1d9d929d7f7009b3a5edca52388a2b0891f upstream.
CONFIG_UBSAN_INTEGER_WRAP is 'default UBSAN', which is problematic for a couple of reasons.
The first is that this sanitizer is under active development on the compiler side to come up with a solution that is maintainable on the compiler side and usable on the kernel side. As a result of this, there are many warnings when the sanitizer is enabled that have no clear path to resolution yet but users may see them and report them in the meantime.
The second is that this option was renamed from CONFIG_UBSAN_SIGNED_WRAP, meaning that if a configuration has CONFIG_UBSAN=y but CONFIG_UBSAN_SIGNED_WRAP=n and it is upgraded via olddefconfig (common in non-interactive scenarios such as CI), CONFIG_UBSAN_INTEGER_WRAP will be silently enabled again.
Remove 'default UBSAN' from CONFIG_UBSAN_INTEGER_WRAP until it is ready for regular usage and testing from a broader community than the folks actively working on the feature.
Cc: stable@vger.kernel.org Fixes: 557f8c582a9b ("ubsan: Reintroduce signed overflow sanitizer") Signed-off-by: Nathan Chancellor nathan@kernel.org Link: https://lore.kernel.org/r/20250414-drop-default-ubsan-integer-wrap-v1-1-3925... Signed-off-by: Kees Cook kees@kernel.org [nathan: Fix conflict due to lack of rename from ed2b548f1017 in stable] Signed-off-by: Nathan Chancellor nathan@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/Kconfig.ubsan | 1 - 1 file changed, 1 deletion(-)
diff --git a/lib/Kconfig.ubsan b/lib/Kconfig.ubsan index 1d4aa7a83b3a5..37655f58b8554 100644 --- a/lib/Kconfig.ubsan +++ b/lib/Kconfig.ubsan @@ -118,7 +118,6 @@ config UBSAN_UNREACHABLE
config UBSAN_SIGNED_WRAP bool "Perform checking for signed arithmetic wrap-around" - default UBSAN depends on !COMPILE_TEST # The no_sanitize attribute was introduced in GCC with version 8. depends on !CC_IS_GCC || GCC_VERSION >= 80000
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells dhowells@redhat.com
[ Upstream commit f452a2204614fc10e2c3b85904c4bd300c2789dc ]
In ceph, in fill_fscrypt_truncate(), the end flush position is calculated by:
loff_t lend = orig_pos + CEPH_FSCRYPT_BLOCK_SHIFT - 1;
but that's using the block shift not the block size.
Fix this to use the block size instead.
Fixes: 5c64737d2536 ("ceph: add truncate size handling support for fscrypt") Signed-off-by: David Howells dhowells@redhat.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/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 7dd6c2275085b..e3ab07797c850 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c @@ -2362,7 +2362,7 @@ static int fill_fscrypt_truncate(struct inode *inode,
/* Try to writeback the dirty pagecaches */ if (issued & (CEPH_CAP_FILE_BUFFER)) { - loff_t lend = orig_pos + CEPH_FSCRYPT_BLOCK_SHIFT - 1; + loff_t lend = orig_pos + CEPH_FSCRYPT_BLOCK_SIZE - 1;
ret = filemap_write_and_wait_range(inode->i_mapping, orig_pos, lend);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andre Przywara andre.przywara@arm.com
[ Upstream commit 14c8a418159e541d70dbf8fc71225d1623beaf0f ]
A KASAN enabled kernel reports an out-of-bounds access when handling the nvmem cell in the sun50i cpufreq driver: ================================================================== BUG: KASAN: slab-out-of-bounds in sun50i_cpufreq_nvmem_probe+0x180/0x3d4 Read of size 4 at addr ffff000006bf31e0 by task kworker/u16:1/38
This is because the DT specifies the nvmem cell as covering only two bytes, but we use a u32 pointer to read the value. DTs for other SoCs indeed specify 4 bytes, so we cannot just shorten the variable to a u16.
Fortunately nvmem_cell_read() allows to return the length of the nvmem cell, in bytes, so we can use that information to only access the valid portion of the data. To cover multiple cell sizes, use memcpy() to copy the information into a zeroed u32 buffer, then also make sure we always read the data in little endian fashion, as this is how the data is stored in the SID efuses.
Fixes: 6cc4bcceff9a ("cpufreq: sun50i: Refactor speed bin decoding") Reported-by: Jernej Skrabec jernej.skrabec@gmail.com Signed-off-by: Andre Przywara andre.przywara@arm.com Reviewed-by: Jernej Škrabec jernej.skrabec@gmail.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/sun50i-cpufreq-nvmem.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/drivers/cpufreq/sun50i-cpufreq-nvmem.c b/drivers/cpufreq/sun50i-cpufreq-nvmem.c index 47d6840b34899..744312a44279c 100644 --- a/drivers/cpufreq/sun50i-cpufreq-nvmem.c +++ b/drivers/cpufreq/sun50i-cpufreq-nvmem.c @@ -194,7 +194,9 @@ static int sun50i_cpufreq_get_efuse(void) struct nvmem_cell *speedbin_nvmem; const struct of_device_id *match; struct device *cpu_dev; - u32 *speedbin; + void *speedbin_ptr; + u32 speedbin = 0; + size_t len; int ret;
cpu_dev = get_cpu_device(0); @@ -217,14 +219,18 @@ static int sun50i_cpufreq_get_efuse(void) return dev_err_probe(cpu_dev, PTR_ERR(speedbin_nvmem), "Could not get nvmem cell\n");
- speedbin = nvmem_cell_read(speedbin_nvmem, NULL); + speedbin_ptr = nvmem_cell_read(speedbin_nvmem, &len); nvmem_cell_put(speedbin_nvmem); - if (IS_ERR(speedbin)) - return PTR_ERR(speedbin); + if (IS_ERR(speedbin_ptr)) + return PTR_ERR(speedbin_ptr);
- ret = opp_data->efuse_xlate(*speedbin); + if (len <= 4) + memcpy(&speedbin, speedbin_ptr, len); + speedbin = le32_to_cpu(speedbin);
- kfree(speedbin); + ret = opp_data->efuse_xlate(speedbin); + + kfree(speedbin_ptr);
return ret; };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit d7b98ae5221007d3f202746903d4c21c7caf7ea9 ]
When building with W=1, this variable is unused for configs with CONFIG_CMA_SIZE_SEL_PERCENTAGE=y:
kernel/dma/contiguous.c:67:26: error: 'size_bytes' defined but not used [-Werror=unused-const-variable=]
Change this to a macro to avoid the warning.
Fixes: c64be2bb1c6e ("drivers: add Contiguous Memory Allocator") Signed-off-by: Arnd Bergmann arnd@arndb.de Signed-off-by: Marek Szyprowski m.szyprowski@samsung.com Link: https://lore.kernel.org/r/20250409151557.3890443-1-arnd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/dma/contiguous.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c index 055da410ac71d..8df0dfaaca18e 100644 --- a/kernel/dma/contiguous.c +++ b/kernel/dma/contiguous.c @@ -64,8 +64,7 @@ struct cma *dma_contiguous_default_area; * Users, who want to set the size of global CMA area for their system * should use cma= kernel parameter. */ -static const phys_addr_t size_bytes __initconst = - (phys_addr_t)CMA_SIZE_MBYTES * SZ_1M; +#define size_bytes ((phys_addr_t)CMA_SIZE_MBYTES * SZ_1M) static phys_addr_t size_cmdline __initdata = -1; static phys_addr_t base_cmdline __initdata; static phys_addr_t limit_cmdline __initdata;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin bsdhenrymartin@gmail.com
[ Upstream commit 9992649f6786921873a9b89dafa5e04d8c5fef2b ]
cpufreq_cpu_get_raw() can return NULL when the target CPU is not present in the policy->cpus mask. apple_soc_cpufreq_get_rate() does not check for this case, which results in a NULL pointer dereference.
Fixes: 6286bbb40576 ("cpufreq: apple-soc: Add new driver to control Apple SoC CPU P-states") Signed-off-by: Henry Martin bsdhenrymartin@gmail.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/apple-soc-cpufreq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/apple-soc-cpufreq.c b/drivers/cpufreq/apple-soc-cpufreq.c index 269b18c62d040..82007f6a24d2a 100644 --- a/drivers/cpufreq/apple-soc-cpufreq.c +++ b/drivers/cpufreq/apple-soc-cpufreq.c @@ -134,11 +134,17 @@ static const struct of_device_id apple_soc_cpufreq_of_match[] __maybe_unused = {
static unsigned int apple_soc_cpufreq_get_rate(unsigned int cpu) { - struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); - struct apple_cpu_priv *priv = policy->driver_data; + struct cpufreq_policy *policy; + struct apple_cpu_priv *priv; struct cpufreq_frequency_table *p; unsigned int pstate;
+ policy = cpufreq_cpu_get_raw(cpu); + if (unlikely(!policy)) + return 0; + + priv = policy->driver_data; + if (priv->info->cur_pstate_mask) { u32 reg = readl_relaxed(priv->reg_base + APPLE_DVFS_STATUS);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin bsdhenrymartin@gmail.com
[ Upstream commit 484d3f15cc6cbaa52541d6259778e715b2c83c54 ]
cpufreq_cpu_get_raw() can return NULL when the target CPU is not present in the policy->cpus mask. scmi_cpufreq_get_rate() does not check for this case, which results in a NULL pointer dereference.
Add NULL check after cpufreq_cpu_get_raw() to prevent this issue.
Fixes: 99d6bdf33877 ("cpufreq: add support for CPU DVFS based on SCMI message protocol") Signed-off-by: Henry Martin bsdhenrymartin@gmail.com Acked-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/scmi-cpufreq.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index 914bf2c940a03..9c6eb1238f1be 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -37,11 +37,17 @@ static struct cpufreq_driver scmi_cpufreq_driver;
static unsigned int scmi_cpufreq_get_rate(unsigned int cpu) { - struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); - struct scmi_data *priv = policy->driver_data; + struct cpufreq_policy *policy; + struct scmi_data *priv; unsigned long rate; int ret;
+ policy = cpufreq_cpu_get_raw(cpu); + if (unlikely(!policy)) + return 0; + + priv = policy->driver_data; + ret = perf_ops->freq_get(ph, priv->domain_id, &rate, false); if (ret) return 0;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin bsdhenrymartin@gmail.com
[ Upstream commit 73b24dc731731edf762f9454552cb3a5b7224949 ]
cpufreq_cpu_get_raw() can return NULL when the target CPU is not present in the policy->cpus mask. scpi_cpufreq_get_rate() does not check for this case, which results in a NULL pointer dereference.
Fixes: 343a8d17fa8d ("cpufreq: scpi: remove arm_big_little dependency") Signed-off-by: Henry Martin bsdhenrymartin@gmail.com Acked-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/scpi-cpufreq.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/cpufreq/scpi-cpufreq.c b/drivers/cpufreq/scpi-cpufreq.c index 1f97b949763fa..9118856e17365 100644 --- a/drivers/cpufreq/scpi-cpufreq.c +++ b/drivers/cpufreq/scpi-cpufreq.c @@ -29,9 +29,16 @@ static struct scpi_ops *scpi_ops;
static unsigned int scpi_cpufreq_get_rate(unsigned int cpu) { - struct cpufreq_policy *policy = cpufreq_cpu_get_raw(cpu); - struct scpi_data *priv = policy->driver_data; - unsigned long rate = clk_get_rate(priv->clk); + struct cpufreq_policy *policy; + struct scpi_data *priv; + unsigned long rate; + + policy = cpufreq_cpu_get_raw(cpu); + if (unlikely(!policy)) + return 0; + + priv = policy->driver_data; + rate = clk_get_rate(priv->clk);
return rate / 1000; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang chenyuan0y@gmail.com
[ Upstream commit 4c324085062919d4e21c69e5e78456dcec0052fe ]
A race can occur between the MCQ completion path and the abort handler: once a request completes, __blk_mq_free_request() sets rq->mq_hctx to NULL, meaning the subsequent ufshcd_mcq_req_to_hwq() call in ufshcd_mcq_abort() can return a NULL pointer. If this NULL pointer is dereferenced, the kernel will crash.
Add a NULL check for the returned hwq pointer. If hwq is NULL, log an error and return FAILED, preventing a potential NULL-pointer dereference. As suggested by Bart, the ufshcd_cmd_inflight() check is removed.
This is similar to the fix in commit 74736103fb41 ("scsi: ufs: core: Fix ufshcd_abort_one racing issue").
This is found by our static analysis tool KNighter.
Signed-off-by: Chenyuan Yang chenyuan0y@gmail.com Link: https://lore.kernel.org/r/20250410001320.2219341-1-chenyuan0y@gmail.com Fixes: f1304d442077 ("scsi: ufs: mcq: Added ufshcd_mcq_abort()") Reviewed-by: Bart Van Assche bvanassche@acm.org Reviewed-by: Peter Wang peter.wang@mediatek.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ufs/core/ufs-mcq.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c index 240ce135bbfbc..f1294c29f4849 100644 --- a/drivers/ufs/core/ufs-mcq.c +++ b/drivers/ufs/core/ufs-mcq.c @@ -677,13 +677,6 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd) unsigned long flags; int err;
- if (!ufshcd_cmd_inflight(lrbp->cmd)) { - dev_err(hba->dev, - "%s: skip abort. cmd at tag %d already completed.\n", - __func__, tag); - return FAILED; - } - /* Skip task abort in case previous aborts failed and report failure */ if (lrbp->req_abort_skip) { dev_err(hba->dev, "%s: skip abort. tag %d failed earlier\n", @@ -692,6 +685,11 @@ int ufshcd_mcq_abort(struct scsi_cmnd *cmd) }
hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd)); + if (!hwq) { + dev_err(hba->dev, "%s: skip abort. cmd at tag %d already completed.\n", + __func__, tag); + return FAILED; + }
if (ufshcd_mcq_sqe_search(hba, hwq, tag)) { /*
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Jurgens danielj@nvidia.com
[ Upstream commit 16c22c56d4282584742022a37d4f79a46ca6094a ]
Section 2.12.1.2 of v1.4 of the VirtIO spec states:
The device and driver capabilities commands are currently defined for self group type. 1. VIRTIO_ADMIN_CMD_CAP_ID_LIST_QUERY 2. VIRTIO_ADMIN_CMD_DEVICE_CAP_GET 3. VIRTIO_ADMIN_CMD_DRIVER_CAP_SET
Fixes: bfcad518605d ("virtio: Manage device and driver capabilities via the admin commands") Signed-off-by: Daniel Jurgens danielj@nvidia.com Reviewed-by: Parav Pandit parav@nvidia.com Message-Id: 20250304161442.90700-1-danielj@nvidia.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/virtio/virtio_pci_modern.c | 4 ++-- include/uapi/linux/virtio_pci.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 5eaade7578606..d50fe030d8253 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -247,7 +247,7 @@ virtio_pci_admin_cmd_dev_parts_objects_enable(struct virtio_device *virtio_dev) sg_init_one(&data_sg, get_data, sizeof(*get_data)); sg_init_one(&result_sg, result, sizeof(*result)); cmd.opcode = cpu_to_le16(VIRTIO_ADMIN_CMD_DEVICE_CAP_GET); - cmd.group_type = cpu_to_le16(VIRTIO_ADMIN_GROUP_TYPE_SRIOV); + cmd.group_type = cpu_to_le16(VIRTIO_ADMIN_GROUP_TYPE_SELF); cmd.data_sg = &data_sg; cmd.result_sg = &result_sg; ret = vp_modern_admin_cmd_exec(virtio_dev, &cmd); @@ -305,7 +305,7 @@ static void virtio_pci_admin_cmd_cap_init(struct virtio_device *virtio_dev)
sg_init_one(&result_sg, data, sizeof(*data)); cmd.opcode = cpu_to_le16(VIRTIO_ADMIN_CMD_CAP_ID_LIST_QUERY); - cmd.group_type = cpu_to_le16(VIRTIO_ADMIN_GROUP_TYPE_SRIOV); + cmd.group_type = cpu_to_le16(VIRTIO_ADMIN_GROUP_TYPE_SELF); cmd.result_sg = &result_sg;
ret = vp_modern_admin_cmd_exec(virtio_dev, &cmd); diff --git a/include/uapi/linux/virtio_pci.h b/include/uapi/linux/virtio_pci.h index 8549d45712571..c691ac210ce2e 100644 --- a/include/uapi/linux/virtio_pci.h +++ b/include/uapi/linux/virtio_pci.h @@ -246,6 +246,7 @@ struct virtio_pci_cfg_cap { #define VIRTIO_ADMIN_CMD_LIST_USE 0x1
/* Admin command group type. */ +#define VIRTIO_ADMIN_GROUP_TYPE_SELF 0x0 #define VIRTIO_ADMIN_GROUP_TYPE_SRIOV 0x1
/* Transitional device admin command. */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Zyngier maz@kernel.org
[ Upstream commit 2b8e6b58889c672e1ae3601d9b2b070be4dc2fbc ]
Returning a negative error code in a function with an unsigned return type is a pretty bad idea. It is probably worse when the justification for the change is "our static analisys tool found it".
Fixes: cf7de25878a1 ("cppc_cpufreq: Fix possible null pointer dereference") Signed-off-by: Marc Zyngier maz@kernel.org Cc: "Rafael J. Wysocki" rafael@kernel.org Cc: Viresh Kumar viresh.kumar@linaro.org Reviewed-by: Lifeng Zheng zhenglifeng1@huawei.com Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/cppc_cpufreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index 8f512448382f4..ba7c16c0e4756 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -749,7 +749,7 @@ static unsigned int cppc_cpufreq_get_rate(unsigned int cpu) int ret;
if (!policy) - return -ENODEV; + return 0;
cpu_data = policy->driver_data;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org
[ Upstream commit d4f610a9bafdec8e3210789aa19335367da696ea ]
Enabling the compile test should not cause automatic enabling of all drivers.
Signed-off-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Stable-dep-of: a374f28700ab ("cpufreq: fix compile-test defaults") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/Kconfig.arm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 4f9cb943d945c..d4d625ded285f 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -76,7 +76,7 @@ config ARM_VEXPRESS_SPC_CPUFREQ config ARM_BRCMSTB_AVS_CPUFREQ tristate "Broadcom STB AVS CPUfreq driver" depends on (ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ) || COMPILE_TEST - default y + default ARCH_BRCMSTB help Some Broadcom STB SoCs use a co-processor running proprietary firmware ("AVS") to handle voltage and frequency scaling. This driver provides @@ -181,7 +181,7 @@ config ARM_RASPBERRYPI_CPUFREQ config ARM_S3C64XX_CPUFREQ bool "Samsung S3C64XX" depends on CPU_S3C6410 || COMPILE_TEST - default y + default CPU_S3C6410 help This adds the CPUFreq driver for Samsung S3C6410 SoC.
@@ -190,7 +190,7 @@ config ARM_S3C64XX_CPUFREQ config ARM_S5PV210_CPUFREQ bool "Samsung S5PV210 and S5PC110" depends on CPU_S5PV210 || COMPILE_TEST - default y + default CPU_S5PV210 help This adds the CPUFreq driver for Samsung S5PV210 and S5PC110 SoCs. @@ -214,7 +214,7 @@ config ARM_SCMI_CPUFREQ config ARM_SPEAR_CPUFREQ bool "SPEAr CPUFreq support" depends on PLAT_SPEAR || COMPILE_TEST - default y + default PLAT_SPEAR help This adds the CPUFreq driver support for SPEAr SOCs.
@@ -233,7 +233,7 @@ config ARM_TEGRA20_CPUFREQ tristate "Tegra20/30 CPUFreq support" depends on ARCH_TEGRA || COMPILE_TEST depends on CPUFREQ_DT - default y + default ARCH_TEGRA help This adds the CPUFreq driver support for Tegra20/30 SOCs.
@@ -241,7 +241,7 @@ config ARM_TEGRA124_CPUFREQ bool "Tegra124 CPUFreq support" depends on ARCH_TEGRA || COMPILE_TEST depends on CPUFREQ_DT - default y + default ARCH_TEGRA help This adds the CPUFreq driver support for Tegra124 SOCs.
@@ -256,14 +256,14 @@ config ARM_TEGRA194_CPUFREQ tristate "Tegra194 CPUFreq support" depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || (64BIT && COMPILE_TEST) depends on TEGRA_BPMP - default y + default ARCH_TEGRA help This adds CPU frequency driver support for Tegra194 SOCs.
config ARM_TI_CPUFREQ bool "Texas Instruments CPUFreq support" depends on ARCH_OMAP2PLUS || ARCH_K3 || COMPILE_TEST - default y + default ARCH_OMAP2PLUS || ARCH_K3 help This driver enables valid OPPs on the running platform based on values contained within the SoC in use. Enable this in order to
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold johan+linaro@kernel.org
[ Upstream commit a374f28700abd20e8a7d026f89aa26f759445918 ]
Commit 3f66425a4fc8 ("cpufreq: Enable COMPILE_TEST on Arm drivers") enabled compile testing of most Arm CPUFreq drivers but left the existing default values unchanged so that many drivers are enabled by default whenever COMPILE_TEST is selected.
This specifically results in the S3C64XX CPUFreq driver being enabled and initialised during boot of non-S3C64XX platforms with the following error logged:
cpufreq: Unable to obtain ARMCLK: -2
Commit d4f610a9bafd ("cpufreq: Do not enable by default during compile testing") recently fixed most of the default values, but two entries were missed and two could use a more specific default condition.
Fix the default values for drivers that can be compile tested and that should be enabled by default when not compile testing.
Fixes: 3f66425a4fc8 ("cpufreq: Enable COMPILE_TEST on Arm drivers") Cc: Rob Herring (Arm) robh@kernel.org Signed-off-by: Johan Hovold johan+linaro@kernel.org Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Signed-off-by: Viresh Kumar viresh.kumar@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/cpufreq/Kconfig.arm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index d4d625ded285f..0d46402e30942 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -76,7 +76,7 @@ config ARM_VEXPRESS_SPC_CPUFREQ config ARM_BRCMSTB_AVS_CPUFREQ tristate "Broadcom STB AVS CPUfreq driver" depends on (ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ) || COMPILE_TEST - default ARCH_BRCMSTB + default y if ARCH_BRCMSTB && !ARM_SCMI_CPUFREQ help Some Broadcom STB SoCs use a co-processor running proprietary firmware ("AVS") to handle voltage and frequency scaling. This driver provides @@ -88,7 +88,7 @@ config ARM_HIGHBANK_CPUFREQ tristate "Calxeda Highbank-based" depends on ARCH_HIGHBANK || COMPILE_TEST depends on CPUFREQ_DT && REGULATOR && PL320_MBOX - default m + default m if ARCH_HIGHBANK help This adds the CPUFreq driver for Calxeda Highbank SoC based boards. @@ -133,7 +133,7 @@ config ARM_MEDIATEK_CPUFREQ config ARM_MEDIATEK_CPUFREQ_HW tristate "MediaTek CPUFreq HW driver" depends on ARCH_MEDIATEK || COMPILE_TEST - default m + default m if ARCH_MEDIATEK help Support for the CPUFreq HW driver. Some MediaTek chipsets have a HW engine to offload the steps @@ -256,7 +256,7 @@ config ARM_TEGRA194_CPUFREQ tristate "Tegra194 CPUFreq support" depends on ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC || (64BIT && COMPILE_TEST) depends on TEGRA_BPMP - default ARCH_TEGRA + default ARCH_TEGRA_194_SOC || ARCH_TEGRA_234_SOC help This adds CPU frequency driver support for Tegra194 SOCs.
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo wqu@suse.com
[ Upstream commit bc2dbc4983afedd198490cca043798f57c93e9bf ]
[BUG] When running btrfs/004 with 4K fs block size and 64K page size, sometimes fsstress workload can take 100% CPU for a while, but not long enough to trigger a 120s hang warning.
[CAUSE] When such 100% CPU usage happens, btrfs_punch_hole_lock_range() is always in the call trace.
One example when this problem happens, the function btrfs_punch_hole_lock_range() got the following parameters:
lock_start = 4096, lockend = 20469
Then we calculate @page_lockstart by rounding up lock_start to page boundary, which is 64K (page size is 64K).
For @page_lockend, we round down the value towards page boundary, which result 0. Then since we need to pass an inclusive end to filemap_range_has_page(), we subtract 1 from the rounded down value, resulting in (u64)-1.
In the above case, the range is inside the same page, and we do not even need to call filemap_range_has_page(), not to mention to call it with (u64)-1 at the end.
This behavior will cause btrfs_punch_hole_lock_range() to busy loop waiting for irrelevant range to have its pages dropped.
[FIX] Calculate @page_lockend by just rounding down @lockend, without decreasing the value by one. So @page_lockend will no longer overflow.
Then exit early if @page_lockend is no larger than @page_lockstart. As it means either the range is inside the same page, or the two pages are adjacent already.
Finally only decrease @page_lockend when calling filemap_range_has_page().
Fixes: 0528476b6ac7 ("btrfs: fix the filemap_range_has_page() call in btrfs_punch_hole_lock_range()") Reviewed-by: Filipe Manana fdmanana@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/file.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 0b568c8d24cbc..a92997a583bd2 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -2104,15 +2104,20 @@ static void btrfs_punch_hole_lock_range(struct inode *inode, * will always return true. * So here we need to do extra page alignment for * filemap_range_has_page(). + * + * And do not decrease page_lockend right now, as it can be 0. */ const u64 page_lockstart = round_up(lockstart, PAGE_SIZE); - const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE) - 1; + const u64 page_lockend = round_down(lockend + 1, PAGE_SIZE);
while (1) { truncate_pagecache_range(inode, lockstart, lockend);
lock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend, cached_state); + /* The same page or adjacent pages. */ + if (page_lockend <= page_lockstart) + break; /* * We can't have ordered extents in the range, nor dirty/writeback * pages, because we have locked the inode's VFS lock in exclusive @@ -2124,7 +2129,7 @@ static void btrfs_punch_hole_lock_range(struct inode *inode, * we do, unlock the range and retry. */ if (!filemap_range_has_page(inode->i_mapping, page_lockstart, - page_lockend)) + page_lockend - 1)) break;
unlock_extent(&BTRFS_I(inode)->io_tree, lockstart, lockend,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Thumshirn johannes.thumshirn@wdc.com
[ Upstream commit b0c26f47992672661340dd6ea931240213016609 ]
There was a bug report about a NULL pointer dereference in __btrfs_add_free_space_zoned() that ultimately happens because a conversion from the default metadata profile DUP to a RAID1 profile on two disks.
The stack trace has the following signature:
BTRFS error (device sdc): zoned: write pointer offset mismatch of zones in raid1 profile BUG: kernel NULL pointer dereference, address: 0000000000000058 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] PREEMPT SMP NOPTI RIP: 0010:__btrfs_add_free_space_zoned.isra.0+0x61/0x1a0 RSP: 0018:ffffa236b6f3f6d0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff96c8132f3400 RCX: 0000000000000001 RDX: 0000000010000000 RSI: 0000000000000000 RDI: ffff96c8132f3410 RBP: 0000000010000000 R08: 0000000000000003 R09: 0000000000000000 R10: 0000000000000000 R11: 00000000ffffffff R12: 0000000000000000 R13: ffff96c758f65a40 R14: 0000000000000001 R15: 000011aac0000000 FS: 00007fdab1cb2900(0000) GS:ffff96e60ca00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000058 CR3: 00000001a05ae000 CR4: 0000000000350ef0 Call Trace: <TASK> ? __die_body.cold+0x19/0x27 ? page_fault_oops+0x15c/0x2f0 ? exc_page_fault+0x7e/0x180 ? asm_exc_page_fault+0x26/0x30 ? __btrfs_add_free_space_zoned.isra.0+0x61/0x1a0 btrfs_add_free_space_async_trimmed+0x34/0x40 btrfs_add_new_free_space+0x107/0x120 btrfs_make_block_group+0x104/0x2b0 btrfs_create_chunk+0x977/0xf20 btrfs_chunk_alloc+0x174/0x510 ? srso_return_thunk+0x5/0x5f btrfs_inc_block_group_ro+0x1b1/0x230 btrfs_relocate_block_group+0x9e/0x410 btrfs_relocate_chunk+0x3f/0x130 btrfs_balance+0x8ac/0x12b0 ? srso_return_thunk+0x5/0x5f ? srso_return_thunk+0x5/0x5f ? __kmalloc_cache_noprof+0x14c/0x3e0 btrfs_ioctl+0x2686/0x2a80 ? srso_return_thunk+0x5/0x5f ? ioctl_has_perm.constprop.0.isra.0+0xd2/0x120 __x64_sys_ioctl+0x97/0xc0 do_syscall_64+0x82/0x160 ? srso_return_thunk+0x5/0x5f ? __memcg_slab_free_hook+0x11a/0x170 ? srso_return_thunk+0x5/0x5f ? kmem_cache_free+0x3f0/0x450 ? srso_return_thunk+0x5/0x5f ? srso_return_thunk+0x5/0x5f ? syscall_exit_to_user_mode+0x10/0x210 ? srso_return_thunk+0x5/0x5f ? do_syscall_64+0x8e/0x160 ? sysfs_emit+0xaf/0xc0 ? srso_return_thunk+0x5/0x5f ? srso_return_thunk+0x5/0x5f ? seq_read_iter+0x207/0x460 ? srso_return_thunk+0x5/0x5f ? vfs_read+0x29c/0x370 ? srso_return_thunk+0x5/0x5f ? srso_return_thunk+0x5/0x5f ? syscall_exit_to_user_mode+0x10/0x210 ? srso_return_thunk+0x5/0x5f ? do_syscall_64+0x8e/0x160 ? srso_return_thunk+0x5/0x5f ? exc_page_fault+0x7e/0x180 entry_SYSCALL_64_after_hwframe+0x76/0x7e RIP: 0033:0x7fdab1e0ca6d RSP: 002b:00007ffeb2b60c80 EFLAGS: 00000246 ORIG_RAX: 0000000000000010 RAX: ffffffffffffffda RBX: 0000000000000003 RCX: 00007fdab1e0ca6d RDX: 00007ffeb2b60d80 RSI: 00000000c4009420 RDI: 0000000000000003 RBP: 00007ffeb2b60cd0 R08: 0000000000000000 R09: 0000000000000013 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 R13: 00007ffeb2b6343b R14: 00007ffeb2b60d80 R15: 0000000000000001 </TASK> CR2: 0000000000000058 ---[ end trace 0000000000000000 ]---
The 1st line is the most interesting here:
BTRFS error (device sdc): zoned: write pointer offset mismatch of zones in raid1 profile
When a RAID1 block-group is created and a write pointer mismatch between the disks in the RAID set is detected, btrfs sets the alloc_offset to the length of the block group marking it as full. Afterwards the code expects that a balance operation will evacuate the data in this block-group and repair the problems.
But before this is possible, the new space of this block-group will be accounted in the free space cache. But in __btrfs_add_free_space_zoned() it is being checked if it is a initial creation of a block group and if not a reclaim decision will be made. But the decision if a block-group's free space accounting is done for an initial creation depends on if the size of the added free space is the whole length of the block-group and the allocation offset is 0.
But as btrfs_load_block_group_zone_info() sets the allocation offset to the zone capacity (i.e. marking the block-group as full) this initial decision is not met, and the space_info pointer in the 'struct btrfs_block_group' has not yet been assigned.
Fail creation of the block group and rely on manual user intervention to re-balance the filesystem.
Afterwards the filesystem can be unmounted, mounted in degraded mode and the missing device can be removed after a full balance of the filesystem.
Reported-by: 西木野羰基 yanqiyu01@gmail.com Link: https://lore.kernel.org/linux-btrfs/CAB_b4sBhDe3tscz=duVyhc9hNE+gu=B8CrgLO15... Fixes: b1934cd60695 ("btrfs: zoned: handle broken write pointer on zones") Reviewed-by: Anand Jain anand.jain@oracle.com Signed-off-by: Johannes Thumshirn johannes.thumshirn@wdc.com Signed-off-by: David Sterba dsterba@suse.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/btrfs/zoned.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c index aaf925897fdda..978a57da8b4f5 100644 --- a/fs/btrfs/zoned.c +++ b/fs/btrfs/zoned.c @@ -1659,7 +1659,6 @@ int btrfs_load_block_group_zone_info(struct btrfs_block_group *cache, bool new) * stripe. */ cache->alloc_offset = cache->zone_capacity; - ret = 0; }
out:
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: T.J. Mercier tjmercier@google.com
[ Upstream commit 1bf67c8fdbda21fadd564a12dbe2b13c1ea5eda7 ]
Android has mounted the v1 cpuset controller using filesystem type "cpuset" (not "cgroup") since 2015 [1], and depends on the resulting behavior where the controller name is not added as a prefix for cgroupfs files. [2]
Later, a problem was discovered where cpu hotplug onlining did not affect the cpuset/cpus files, which Android carried an out-of-tree patch to address for a while. An attempt was made to upstream this patch, but the recommendation was to use the "cpuset_v2_mode" mount option instead. [3]
An effort was made to do so, but this fails with "cgroup: Unknown parameter 'cpuset_v2_mode'" because commit e1cba4b85daa ("cgroup: Add mount flag to enable cpuset to use v2 behavior in v1 cgroup") did not update the special cased cpuset_mount(), and only the cgroup (v1) filesystem type was updated.
Add parameter parsing to the cpuset filesystem type so that cpuset_v2_mode works like the cgroup filesystem type:
$ mkdir /dev/cpuset $ mount -t cpuset -ocpuset_v2_mode none /dev/cpuset $ mount|grep cpuset none on /dev/cpuset type cgroup (rw,relatime,cpuset,noprefix,cpuset_v2_mode,release_agent=/sbin/cpuset_release_agent)
[1] https://cs.android.com/android/_/android/platform/system/core/+/b769c8d24fd7... [2] https://cs.android.com/android/platform/superproject/main/+/main:system/core... [3] https://lore.kernel.org/lkml/f795f8be-a184-408a-0b5a-553d26061385@redhat.com...
Fixes: e1cba4b85daa ("cgroup: Add mount flag to enable cpuset to use v2 behavior in v1 cgroup") Signed-off-by: T.J. Mercier tjmercier@google.com Acked-by: Waiman Long longman@redhat.com Reviewed-by: Kamalesh Babulal kamalesh.babulal@oracle.com Acked-by: Michal Koutný mkoutny@suse.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/cgroup/cgroup.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+)
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 81f078c059e86..68d58753c75c3 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c @@ -2339,9 +2339,37 @@ static struct file_system_type cgroup2_fs_type = { };
#ifdef CONFIG_CPUSETS_V1 +enum cpuset_param { + Opt_cpuset_v2_mode, +}; + +static const struct fs_parameter_spec cpuset_fs_parameters[] = { + fsparam_flag ("cpuset_v2_mode", Opt_cpuset_v2_mode), + {} +}; + +static int cpuset_parse_param(struct fs_context *fc, struct fs_parameter *param) +{ + struct cgroup_fs_context *ctx = cgroup_fc2context(fc); + struct fs_parse_result result; + int opt; + + opt = fs_parse(fc, cpuset_fs_parameters, param, &result); + if (opt < 0) + return opt; + + switch (opt) { + case Opt_cpuset_v2_mode: + ctx->flags |= CGRP_ROOT_CPUSET_V2_MODE; + return 0; + } + return -EINVAL; +} + static const struct fs_context_operations cpuset_fs_context_ops = { .get_tree = cgroup1_get_tree, .free = cgroup_fs_context_free, + .parse_param = cpuset_parse_param, };
/* @@ -2378,6 +2406,7 @@ static int cpuset_init_fs_context(struct fs_context *fc) static struct file_system_type cpuset_fs_type = { .name = "cpuset", .init_fs_context = cpuset_init_fs_context, + .parameters = cpuset_fs_parameters, .fs_flags = FS_USERNS_MOUNT, }; #endif
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Christie michael.christie@oracle.com
[ Upstream commit 3ca51662f8186b569b8fb282242c20ccbb3993c2 ]
If we can't allocate mem to map in data for a request or can't find a tag for a command, we currently drop the command. This leads to the error handler running to clean it up. Instead of dropping the command this has us return an error telling the initiator that it queued more commands than we can handle. The initiator will then reduce how many commands it will send us and retry later.
Signed-off-by: Mike Christie michael.christie@oracle.com Message-Id: 20241203191705.19431-4-michael.christie@oracle.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Acked-by: Stefan Hajnoczi stefanha@redhat.com Stable-dep-of: b18268713547 ("vhost-scsi: Fix vhost_scsi_send_bad_target()") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vhost/scsi.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 7aeff435c1d87..ad7fa5bc0f5fc 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -630,7 +630,7 @@ vhost_scsi_get_cmd(struct vhost_virtqueue *vq, struct vhost_scsi_tpg *tpg,
tag = sbitmap_get(&svq->scsi_tags); if (tag < 0) { - pr_err("Unable to obtain tag for vhost_scsi_cmd\n"); + pr_warn_once("Guest sent too many cmds. Returning TASK_SET_FULL.\n"); return ERR_PTR(-ENOMEM); }
@@ -929,6 +929,24 @@ static void vhost_scsi_target_queue_cmd(struct vhost_scsi_cmd *cmd) target_submit(se_cmd); }
+static void +vhost_scsi_send_status(struct vhost_scsi *vs, struct vhost_virtqueue *vq, + int head, unsigned int out, u8 status) +{ + struct virtio_scsi_cmd_resp __user *resp; + struct virtio_scsi_cmd_resp rsp; + int ret; + + memset(&rsp, 0, sizeof(rsp)); + rsp.status = status; + resp = vq->iov[out].iov_base; + ret = __copy_to_user(resp, &rsp, sizeof(rsp)); + if (!ret) + vhost_add_used_and_signal(&vs->dev, vq, head, 0); + else + pr_err("Faulted on virtio_scsi_cmd_resp\n"); +} + static void vhost_scsi_send_bad_target(struct vhost_scsi *vs, struct vhost_virtqueue *vq, @@ -1216,8 +1234,8 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) exp_data_len + prot_bytes, data_direction); if (IS_ERR(cmd)) { - vq_err(vq, "vhost_scsi_get_cmd failed %ld\n", - PTR_ERR(cmd)); + ret = PTR_ERR(cmd); + vq_err(vq, "vhost_scsi_get_tag failed %dd\n", ret); goto err; } cmd->tvc_vhost = vs; @@ -1254,11 +1272,15 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) * EINVAL: Invalid response buffer, drop the request * EIO: Respond with bad target * EAGAIN: Pending request + * ENOMEM: Could not allocate resources for request */ if (ret == -ENXIO) break; else if (ret == -EIO) vhost_scsi_send_bad_target(vs, vq, vc.head, vc.out); + else if (ret == -ENOMEM) + vhost_scsi_send_status(vs, vq, vc.head, vc.out, + SAM_STAT_TASK_SET_FULL); } while (likely(!vhost_exceeds_weight(vq, ++c, 0))); out: mutex_unlock(&vq->mutex);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dongli Zhang dongli.zhang@oracle.com
[ Upstream commit b182687135474d7ed905a07cc6cb2734b359e13e ]
Although the support of VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 was signaled by the commit 664ed90e621c ("vhost/scsi: Set VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 feature bits"), vhost_scsi_send_bad_target() still assumes the response in a single descriptor.
In addition, although vhost_scsi_send_bad_target() is used by both I/O queue and control queue, the response header is always virtio_scsi_cmd_resp. It is required to use virtio_scsi_ctrl_tmf_resp or virtio_scsi_ctrl_an_resp for control queue.
Fixes: 664ed90e621c ("vhost/scsi: Set VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 feature bits") Signed-off-by: Dongli Zhang dongli.zhang@oracle.com Acked-by: Jason Wang jasowang@redhat.com Reviewed-by: Mike Christie michael.christie@oracle.com Message-Id: 20250403063028.16045-3-dongli.zhang@oracle.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vhost/scsi.c | 48 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index ad7fa5bc0f5fc..7bfe5e5865fe9 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -947,23 +947,46 @@ vhost_scsi_send_status(struct vhost_scsi *vs, struct vhost_virtqueue *vq, pr_err("Faulted on virtio_scsi_cmd_resp\n"); }
+#define TYPE_IO_CMD 0 +#define TYPE_CTRL_TMF 1 +#define TYPE_CTRL_AN 2 + static void vhost_scsi_send_bad_target(struct vhost_scsi *vs, struct vhost_virtqueue *vq, - int head, unsigned out) + struct vhost_scsi_ctx *vc, int type) { - struct virtio_scsi_cmd_resp __user *resp; - struct virtio_scsi_cmd_resp rsp; + union { + struct virtio_scsi_cmd_resp cmd; + struct virtio_scsi_ctrl_tmf_resp tmf; + struct virtio_scsi_ctrl_an_resp an; + } rsp; + struct iov_iter iov_iter; + size_t rsp_size; int ret;
memset(&rsp, 0, sizeof(rsp)); - rsp.response = VIRTIO_SCSI_S_BAD_TARGET; - resp = vq->iov[out].iov_base; - ret = __copy_to_user(resp, &rsp, sizeof(rsp)); - if (!ret) - vhost_add_used_and_signal(&vs->dev, vq, head, 0); + + if (type == TYPE_IO_CMD) { + rsp_size = sizeof(struct virtio_scsi_cmd_resp); + rsp.cmd.response = VIRTIO_SCSI_S_BAD_TARGET; + } else if (type == TYPE_CTRL_TMF) { + rsp_size = sizeof(struct virtio_scsi_ctrl_tmf_resp); + rsp.tmf.response = VIRTIO_SCSI_S_BAD_TARGET; + } else { + rsp_size = sizeof(struct virtio_scsi_ctrl_an_resp); + rsp.an.response = VIRTIO_SCSI_S_BAD_TARGET; + } + + iov_iter_init(&iov_iter, ITER_DEST, &vq->iov[vc->out], vc->in, + rsp_size); + + ret = copy_to_iter(&rsp, rsp_size, &iov_iter); + + if (likely(ret == rsp_size)) + vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); else - pr_err("Faulted on virtio_scsi_cmd_resp\n"); + pr_err("Faulted on virtio scsi type=%d\n", type); }
static int @@ -1277,7 +1300,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) if (ret == -ENXIO) break; else if (ret == -EIO) - vhost_scsi_send_bad_target(vs, vq, vc.head, vc.out); + vhost_scsi_send_bad_target(vs, vq, &vc, TYPE_IO_CMD); else if (ret == -ENOMEM) vhost_scsi_send_status(vs, vq, vc.head, vc.out, SAM_STAT_TASK_SET_FULL); @@ -1510,7 +1533,10 @@ vhost_scsi_ctl_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) if (ret == -ENXIO) break; else if (ret == -EIO) - vhost_scsi_send_bad_target(vs, vq, vc.head, vc.out); + vhost_scsi_send_bad_target(vs, vq, &vc, + v_req.type == VIRTIO_SCSI_T_TMF ? + TYPE_CTRL_TMF : + TYPE_CTRL_AN); } while (likely(!vhost_exceeds_weight(vq, ++c, 0))); out: mutex_unlock(&vq->mutex);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dongli Zhang dongli.zhang@oracle.com
[ Upstream commit 58465d86071b61415e25fb054201f61e83d21465 ]
Although the support of VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 was signaled by the commit 664ed90e621c ("vhost/scsi: Set VIRTIO_F_ANY_LAYOUT + VIRTIO_F_VERSION_1 feature bits"), vhost_scsi_send_bad_target() still assumes the response in a single descriptor.
Similar issue in vhost_scsi_send_bad_target() has been fixed in previous commit. In addition, similar issue for vhost_scsi_complete_cmd_work() has been fixed by the commit 6dd88fd59da8 ("vhost-scsi: unbreak any layout for response").
Fixes: 3ca51662f818 ("vhost-scsi: Add better resource allocation failure handling") Signed-off-by: Dongli Zhang dongli.zhang@oracle.com Acked-by: Jason Wang jasowang@redhat.com Reviewed-by: Mike Christie michael.christie@oracle.com Message-Id: 20250403063028.16045-4-dongli.zhang@oracle.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/vhost/scsi.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c index 7bfe5e5865fe9..35a03306d1345 100644 --- a/drivers/vhost/scsi.c +++ b/drivers/vhost/scsi.c @@ -931,18 +931,22 @@ static void vhost_scsi_target_queue_cmd(struct vhost_scsi_cmd *cmd)
static void vhost_scsi_send_status(struct vhost_scsi *vs, struct vhost_virtqueue *vq, - int head, unsigned int out, u8 status) + struct vhost_scsi_ctx *vc, u8 status) { - struct virtio_scsi_cmd_resp __user *resp; struct virtio_scsi_cmd_resp rsp; + struct iov_iter iov_iter; int ret;
memset(&rsp, 0, sizeof(rsp)); rsp.status = status; - resp = vq->iov[out].iov_base; - ret = __copy_to_user(resp, &rsp, sizeof(rsp)); - if (!ret) - vhost_add_used_and_signal(&vs->dev, vq, head, 0); + + iov_iter_init(&iov_iter, ITER_DEST, &vq->iov[vc->out], vc->in, + sizeof(rsp)); + + ret = copy_to_iter(&rsp, sizeof(rsp), &iov_iter); + + if (likely(ret == sizeof(rsp))) + vhost_add_used_and_signal(&vs->dev, vq, vc->head, 0); else pr_err("Faulted on virtio_scsi_cmd_resp\n"); } @@ -1302,7 +1306,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq) else if (ret == -EIO) vhost_scsi_send_bad_target(vs, vq, &vc, TYPE_IO_CMD); else if (ret == -ENOMEM) - vhost_scsi_send_status(vs, vq, vc.head, vc.out, + vhost_scsi_send_status(vs, vq, &vc, SAM_STAT_TASK_SET_FULL); } while (likely(!vhost_exceeds_weight(vq, ++c, 0))); out:
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin bsdhenrymartin@gmail.com
[ Upstream commit 91037037ee3d611ce17f39d75f79c7de394b122a ]
Add NULL check for mlx5_get_flow_namespace() returns in mlx5_create_inner_ttc_table() and mlx5_create_ttc_table() to prevent NULL pointer dereference.
Fixes: 137f3d50ad2a ("net/mlx5: Support matching on l4_type for ttc_table") Signed-off-by: Henry Martin bsdhenrymartin@gmail.com Reviewed-by: Mark Bloch mbloch@nvidia.com Reviewed-by: Michal Swiatkowski michal.swiatkowski@linux.intel.com Link: https://patch.msgid.link/20250418023814.71789-2-bsdhenrymartin@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c index 9f13cea164465..510879e1ba30e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c @@ -636,6 +636,11 @@ struct mlx5_ttc_table *mlx5_create_inner_ttc_table(struct mlx5_core_dev *dev, }
ns = mlx5_get_flow_namespace(dev, params->ns_type); + if (!ns) { + kvfree(ttc); + return ERR_PTR(-EOPNOTSUPP); + } + groups = use_l4_type ? &inner_ttc_groups[TTC_GROUPS_USE_L4_TYPE] : &inner_ttc_groups[TTC_GROUPS_DEFAULT];
@@ -709,6 +714,11 @@ struct mlx5_ttc_table *mlx5_create_ttc_table(struct mlx5_core_dev *dev, }
ns = mlx5_get_flow_namespace(dev, params->ns_type); + if (!ns) { + kvfree(ttc); + return ERR_PTR(-EOPNOTSUPP); + } + groups = use_l4_type ? &ttc_groups[TTC_GROUPS_USE_L4_TYPE] : &ttc_groups[TTC_GROUPS_DEFAULT];
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin bsdhenrymartin@gmail.com
[ Upstream commit fa8fd315127ca48c65e7e6692a84ffcf3d07168e ]
Relocate the memory allocation for ttc table after the switch statement that validates params->ns_type in both mlx5_create_inner_ttc_table() and mlx5_create_ttc_table(). This ensures memory is only allocated after confirming valid input, eliminating potential memory leaks when invalid ns_type cases occur.
Fixes: 137f3d50ad2a ("net/mlx5: Support matching on l4_type for ttc_table") Signed-off-by: Henry Martin bsdhenrymartin@gmail.com Reviewed-by: Michal Swiatkowski michal.swiatkowski@linux.intel.com Reviewed-by: Mark Bloch mbloch@nvidia.com Link: https://patch.msgid.link/20250418023814.71789-3-bsdhenrymartin@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- .../net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c index 510879e1ba30e..43b2216bc0a22 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/fs_ttc.c @@ -618,10 +618,6 @@ struct mlx5_ttc_table *mlx5_create_inner_ttc_table(struct mlx5_core_dev *dev, bool use_l4_type; int err;
- ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL); - if (!ttc) - return ERR_PTR(-ENOMEM); - switch (params->ns_type) { case MLX5_FLOW_NAMESPACE_PORT_SEL: use_l4_type = MLX5_CAP_GEN_2(dev, pcc_ifa2) && @@ -635,6 +631,10 @@ struct mlx5_ttc_table *mlx5_create_inner_ttc_table(struct mlx5_core_dev *dev, return ERR_PTR(-EINVAL); }
+ ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL); + if (!ttc) + return ERR_PTR(-ENOMEM); + ns = mlx5_get_flow_namespace(dev, params->ns_type); if (!ns) { kvfree(ttc); @@ -696,10 +696,6 @@ struct mlx5_ttc_table *mlx5_create_ttc_table(struct mlx5_core_dev *dev, bool use_l4_type; int err;
- ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL); - if (!ttc) - return ERR_PTR(-ENOMEM); - switch (params->ns_type) { case MLX5_FLOW_NAMESPACE_PORT_SEL: use_l4_type = MLX5_CAP_GEN_2(dev, pcc_ifa2) && @@ -713,6 +709,10 @@ struct mlx5_ttc_table *mlx5_create_ttc_table(struct mlx5_core_dev *dev, return ERR_PTR(-EINVAL); }
+ ttc = kvzalloc(sizeof(*ttc), GFP_KERNEL); + if (!ttc) + return ERR_PTR(-ENOMEM); + ns = mlx5_get_flow_namespace(dev, params->ns_type); if (!ns) { kvfree(ttc);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anastasia Kovaleva a.kovaleva@yadro.com
[ Upstream commit 54bebe46871d4e56e05fcf55c1a37e7efa24e0a8 ]
Commands that have not been completed with scsi_done() do not clear the SCMD_INITIALIZED flag and therefore will not be properly reinitialized. Thus, the next time the scsi_cmnd structure is used, the command may fail in scsi_cmd_runtime_exceeded() due to the old jiffies_at_alloc value:
kernel: sd 16:0:1:84: [sdts] tag#405 timing out command, waited 720s kernel: sd 16:0:1:84: [sdts] tag#405 FAILED Result: hostbyte=DID_OK driverbyte=DRIVER_OK cmd_age=66636s
Clear flags for commands that have not been completed by SCSI.
Fixes: 4abafdc4360d ("block: remove the initialize_rq_fn blk_mq_ops method") Signed-off-by: Anastasia Kovaleva a.kovaleva@yadro.com Link: https://lore.kernel.org/r/20250324084933.15932-2-a.kovaleva@yadro.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/scsi_lib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index f1cfe0bb89b20..7a31dae9aa82d 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1253,8 +1253,12 @@ EXPORT_SYMBOL_GPL(scsi_alloc_request); */ static void scsi_cleanup_rq(struct request *rq) { + struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(rq); + + cmd->flags = 0; + if (rq->rq_flags & RQF_DONTPREP) { - scsi_mq_uninit_cmd(blk_mq_rq_to_pdu(rq)); + scsi_mq_uninit_cmd(cmd); rq->rq_flags &= ~RQF_DONTPREP; } }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang chenyuan0y@gmail.com
[ Upstream commit 08a966a917fe3d92150fa3cc15793ad5e57051eb ]
Add a NULL check for the returned hwq pointer by ufshcd_mcq_req_to_hwq().
This is similar to the fix in commit 74736103fb41 ("scsi: ufs: core: Fix ufshcd_abort_one racing issue").
Signed-off-by: Chenyuan Yang chenyuan0y@gmail.com Link: https://lore.kernel.org/r/20250412195909.315418-1-chenyuan0y@gmail.com Fixes: ab248643d3d6 ("scsi: ufs: core: Add error handling for MCQ mode") Reviewed-by: Peter Wang peter.wang@mediatek.com 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 | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 464f13da259aa..128e35a848b7b 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5658,6 +5658,8 @@ static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba, continue;
hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(cmd)); + if (!hwq) + continue;
if (force_compl) { ufshcd_mcq_compl_all_cqes_lock(hba, hwq);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 2768b2e2f7d25ae8984ebdcde8ec1014b6fdcd89 ]
At the time when bpf_xdp_adjust_tail() gained support for non-linear buffers, ENETC was already generating this kind of geometry on RX, due to its use of 2K half page buffers. Frames larger than 1472 bytes (without FCS) are stored as multi-buffer, presenting a need for multi buffer support to work properly even in standard MTU circumstances.
Allow bpf_xdp_frags_increase_tail() to know the allocation size of paged data, so it can safely permit growing the tailroom of the buffer from XDP programs.
Fixes: bf25146a5595 ("bpf: add frags support to the bpf_xdp_adjust_tail() API") Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Wei Fang wei.fang@nxp.com Link: https://patch.msgid.link/20250417120005.3288549-2-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 2106861463e40..9b333254c73ec 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -3362,7 +3362,8 @@ static int enetc_int_vector_init(struct enetc_ndev_priv *priv, int i, bdr->buffer_offset = ENETC_RXB_PAD; priv->rx_ring[i] = bdr;
- err = xdp_rxq_info_reg(&bdr->xdp.rxq, priv->ndev, i, 0); + err = __xdp_rxq_info_reg(&bdr->xdp.rxq, priv->ndev, i, 0, + ENETC_RXB_DMA_SIZE_XDP); if (err) goto free_vector;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 1d587faa5be7e9785b682cc5f58ba8f4100c13ea ]
This small snippet of code ensures that we do something with the array of RX software buffer descriptor elements after passing the skb to the stack. In this case, we see if the other half of the page is reusable, and if so, we "turn around" the buffers, making them directly usable by enetc_refill_rx_ring() without going to enetc_new_page().
We will need to perform this kind of buffer flipping from a new code path, i.e. from XDP_PASS. Currently, enetc_build_skb() does it there buffer by buffer, but in a subsequent change we will stop using enetc_build_skb() for XDP_PASS.
Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Wei Fang wei.fang@nxp.com Link: https://patch.msgid.link/20250417120005.3288549-3-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 020f0c8b3d39 ("net: enetc: fix frame corruption on bpf_xdp_adjust_head/tail() and XDP_PASS") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 9b333254c73ec..74721995cb1f9 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1850,6 +1850,16 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first, } }
+static void enetc_bulk_flip_buff(struct enetc_bdr *rx_ring, int rx_ring_first, + int rx_ring_last) +{ + while (rx_ring_first != rx_ring_last) { + enetc_flip_rx_buff(rx_ring, + &rx_ring->rx_swbd[rx_ring_first]); + enetc_bdr_idx_inc(rx_ring, &rx_ring_first); + } +} + static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, struct napi_struct *napi, int work_limit, struct bpf_prog *prog) @@ -1965,11 +1975,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, enetc_xdp_drop(rx_ring, orig_i, i); rx_ring->stats.xdp_redirect_failures++; } else { - while (orig_i != i) { - enetc_flip_rx_buff(rx_ring, - &rx_ring->rx_swbd[orig_i]); - enetc_bdr_idx_inc(rx_ring, &orig_i); - } + enetc_bulk_flip_buff(rx_ring, orig_i, i); xdp_redirect_frm_cnt++; rx_ring->stats.xdp_redirect++; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean vladimir.oltean@nxp.com
[ Upstream commit 020f0c8b3d396ec8190948f86063e1c45133f839 ]
Vlatko Markovikj reported that XDP programs attached to ENETC do not work well if they use bpf_xdp_adjust_head() or bpf_xdp_adjust_tail(), combined with the XDP_PASS verdict. A typical use case is to add or remove a VLAN tag.
The resulting sk_buff passed to the stack is corrupted, because the algorithm used by the driver for XDP_PASS is to unwind the current buffer pointer in the RX ring and to re-process the current frame with enetc_build_skb() as if XDP hadn't run. That is incorrect because XDP may have modified the geometry of the buffer, which we then are completely unaware of. We are looking at a modified buffer with the original geometry.
The initial reaction, both from me and from Vlatko, was to shop around the kernel for code to steal that would calculate a delta between the old and the new XDP buffer geometry, and apply that to the sk_buff too. We noticed that veth and generic xdp have such code.
The headroom adjustment is pretty uncontroversial, but what turned out severely problematic is the tailroom.
veth has this snippet:
__skb_put(skb, off); /* positive on grow, negative on shrink */
which on first sight looks decent enough, except __skb_put() takes an "unsigned int" for the second argument, and the arithmetic seems to only work correctly by coincidence. Second issue, __skb_put() contains a SKB_LINEAR_ASSERT(). It's not a great pattern to make more widespread. The skb may still be nonlinear at that point - it only becomes linear later when resetting skb->data_len to zero.
To avoid the above, bpf_prog_run_generic_xdp() does this instead:
skb_set_tail_pointer(skb, xdp->data_end - xdp->data); skb->len += off; /* positive on grow, negative on shrink */
which is more open-coded, uses lower-level functions and is in general a bit too much to spread around in driver code.
Then there is the snippet:
if (xdp_buff_has_frags(xdp)) skb->data_len = skb_shinfo(skb)->xdp_frags_size; else skb->data_len = 0;
One would have expected __pskb_trim() to be the function of choice for this task. But it's not used in veth/xdpgeneric because the extraneous fragments were _already_ freed by bpf_xdp_adjust_tail() -> bpf_xdp_frags_shrink_tail() -> ... -> __xdp_return() - the backing memory for the skb frags and the xdp frags is the same, but they don't keep individual references.
In fact, that is the biggest reason why this snippet cannot be reused as-is, because ENETC temporarily constructs an skb with the original len and the original number of frags. Because the extraneous frags are already freed by bpf_xdp_adjust_tail() and returned to the page allocator, it means the entire approach of using enetc_build_skb() is questionable for XDP_PASS. To avoid that, one would need to elevate the page refcount of all frags before calling bpf_prog_run_xdp() and drop it after XDP_PASS.
There are other things that are missing in ENETC's handling of XDP_PASS, like for example updating skb_shinfo(skb)->meta_len.
These are all handled correctly and cleanly in commit 539c1fba1ac7 ("xdp: add generic xdp_build_skb_from_buff()"), added to net-next in Dec 2024, and in addition might even be quicker that way. I have a very strong preference towards backporting that commit for "stable", and that is what is used to fix the handling bugs. It is way too messy to go this deep into the guts of an sk_buff from the code of a device driver.
Fixes: d1b15102dd16 ("net: enetc: add support for XDP_DROP and XDP_PASS") Reported-by: Vlatko Markovikj vlatko.markovikj@etas.com Signed-off-by: Vladimir Oltean vladimir.oltean@nxp.com Reviewed-by: Wei Fang wei.fang@nxp.com Link: https://patch.msgid.link/20250417120005.3288549-4-vladimir.oltean@nxp.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/freescale/enetc/enetc.c | 26 +++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/freescale/enetc/enetc.c b/drivers/net/ethernet/freescale/enetc/enetc.c index 74721995cb1f9..3ee52f4b11660 100644 --- a/drivers/net/ethernet/freescale/enetc/enetc.c +++ b/drivers/net/ethernet/freescale/enetc/enetc.c @@ -1878,11 +1878,10 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring,
while (likely(rx_frm_cnt < work_limit)) { union enetc_rx_bd *rxbd, *orig_rxbd; - int orig_i, orig_cleaned_cnt; struct xdp_buff xdp_buff; struct sk_buff *skb; + int orig_i, err; u32 bd_status; - int err;
rxbd = enetc_rxbd(rx_ring, i); bd_status = le32_to_cpu(rxbd->r.lstatus); @@ -1897,7 +1896,6 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, break;
orig_rxbd = rxbd; - orig_cleaned_cnt = cleaned_cnt; orig_i = i;
enetc_build_xdp_buff(rx_ring, bd_status, &rxbd, &i, @@ -1925,15 +1923,21 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, rx_ring->stats.xdp_drops++; break; case XDP_PASS: - rxbd = orig_rxbd; - cleaned_cnt = orig_cleaned_cnt; - i = orig_i; - - skb = enetc_build_skb(rx_ring, bd_status, &rxbd, - &i, &cleaned_cnt, - ENETC_RXB_DMA_SIZE_XDP); - if (unlikely(!skb)) + skb = xdp_build_skb_from_buff(&xdp_buff); + /* Probably under memory pressure, stop NAPI */ + if (unlikely(!skb)) { + enetc_xdp_drop(rx_ring, orig_i, i); + rx_ring->stats.xdp_drops++; goto out; + } + + enetc_get_offloads(rx_ring, orig_rxbd, skb); + + /* These buffers are about to be owned by the stack. + * Update our buffer cache (the rx_swbd array elements) + * with their other page halves. + */ + enetc_bulk_flip_buff(rx_ring, orig_i, i);
napi_gro_receive(napi, skb); break;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Weinberger richard@nod.at
[ Upstream commit 3d7aa0c7b4e96cd460826d932e44710cdeb3378b ]
When trying to enable a port that has no transport configured yet, nvmet_enable_port() uses NVMF_TRTYPE_MAX (255) to query the transports array, causing an out-of-bounds access:
[ 106.058694] BUG: KASAN: global-out-of-bounds in nvmet_enable_port+0x42/0x1da [ 106.058719] Read of size 8 at addr ffffffff89dafa58 by task ln/632 [...] [ 106.076026] nvmet: transport type 255 not supported
Since commit 200adac75888, NVMF_TRTYPE_MAX is the default state as configured by nvmet_ports_make(). Avoid this by checking for NVMF_TRTYPE_MAX before proceeding.
Fixes: 200adac75888 ("nvme: Add PCI transport type") Signed-off-by: Richard Weinberger richard@nod.at Reviewed-by: Sagi Grimberg sagi@grimberg.me Reviewed-by: Chaitanya Kulkarni kch@nvidia.com Reviewed-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/core.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c index 2e741696f3712..6ccce0ee51573 100644 --- a/drivers/nvme/target/core.c +++ b/drivers/nvme/target/core.c @@ -324,6 +324,9 @@ int nvmet_enable_port(struct nvmet_port *port)
lockdep_assert_held(&nvmet_config_sem);
+ if (port->disc_addr.trtype == NVMF_TRTYPE_MAX) + return -EINVAL; + ops = nvmet_transports[port->disc_addr.trtype]; if (!ops) { up_write(&nvmet_config_sem);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Iurman justin.iurman@uliege.be
[ Upstream commit c03a49f3093a4903c8a93c8b5c9a297b5343b169 ]
In lwtunnel_{output|xmit}(), dev_xmit_recursion() may be called in preemptible scope for PREEMPT kernels. This patch disables BHs before calling dev_xmit_recursion(). BHs are re-enabled only at the end, since we must ensure the same CPU is used for both dev_xmit_recursion_inc() and dev_xmit_recursion_dec() (and any other recursion levels in some cases) in order to maintain valid per-cpu counters.
Reported-by: Alexei Starovoitov alexei.starovoitov@gmail.com Closes: https://lore.kernel.org/netdev/CAADnVQJFWn3dBFJtY+ci6oN1pDFL=TzCmNbRgey7MdYx... Reported-by: Eduard Zingerman eddyz87@gmail.com Closes: https://lore.kernel.org/netdev/m2h62qwf34.fsf@gmail.com/ Fixes: 986ffb3a57c5 ("net: lwtunnel: fix recursion loops") Signed-off-by: Justin Iurman justin.iurman@uliege.be Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/20250416160716.8823-1-justin.iurman@uliege.be Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- net/core/lwtunnel.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c index 4417a18b3e951..f63586c9ce021 100644 --- a/net/core/lwtunnel.c +++ b/net/core/lwtunnel.c @@ -332,6 +332,8 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) struct dst_entry *dst; int ret;
+ local_bh_disable(); + if (dev_xmit_recursion()) { net_crit_ratelimited("%s(): recursion limit reached on datapath\n", __func__); @@ -347,8 +349,10 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) lwtstate = dst->lwtstate;
if (lwtstate->type == LWTUNNEL_ENCAP_NONE || - lwtstate->type > LWTUNNEL_ENCAP_MAX) - return 0; + lwtstate->type > LWTUNNEL_ENCAP_MAX) { + ret = 0; + goto out; + }
ret = -EOPNOTSUPP; rcu_read_lock(); @@ -363,11 +367,13 @@ int lwtunnel_output(struct net *net, struct sock *sk, struct sk_buff *skb) if (ret == -EOPNOTSUPP) goto drop;
- return ret; + goto out;
drop: kfree_skb(skb);
+out: + local_bh_enable(); return ret; } EXPORT_SYMBOL_GPL(lwtunnel_output); @@ -379,6 +385,8 @@ int lwtunnel_xmit(struct sk_buff *skb) struct dst_entry *dst; int ret;
+ local_bh_disable(); + if (dev_xmit_recursion()) { net_crit_ratelimited("%s(): recursion limit reached on datapath\n", __func__); @@ -395,8 +403,10 @@ int lwtunnel_xmit(struct sk_buff *skb) lwtstate = dst->lwtstate;
if (lwtstate->type == LWTUNNEL_ENCAP_NONE || - lwtstate->type > LWTUNNEL_ENCAP_MAX) - return 0; + lwtstate->type > LWTUNNEL_ENCAP_MAX) { + ret = 0; + goto out; + }
ret = -EOPNOTSUPP; rcu_read_lock(); @@ -411,11 +421,13 @@ int lwtunnel_xmit(struct sk_buff *skb) if (ret == -EOPNOTSUPP) goto drop;
- return ret; + goto out;
drop: kfree_skb(skb);
+out: + local_bh_enable(); return ret; } EXPORT_SYMBOL_GPL(lwtunnel_xmit); @@ -427,6 +439,8 @@ int lwtunnel_input(struct sk_buff *skb) struct dst_entry *dst; int ret;
+ DEBUG_NET_WARN_ON_ONCE(!in_softirq()); + if (dev_xmit_recursion()) { net_crit_ratelimited("%s(): recursion limit reached on datapath\n", __func__);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
[ Upstream commit f1ae32a709e0b525d7963207eb3a4747626f4818 ]
If we fail to configure the MAC or PCS according to the desired mode, do not allow the network link to come up until we have successfully configured the MAC and PCS. This improves phylink's behaviour when an error occurs.
Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://patch.msgid.link/E1twkqO-0006FI-Gm@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 4c8925cb9db1 ("net: phylink: fix suspend/resume with WoL enabled and link down") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phylink.c | 42 +++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index b00a315de0601..b74b1c3365000 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -82,6 +82,7 @@ struct phylink { unsigned int pcs_state;
bool link_failed; + bool major_config_failed; bool mac_supports_eee_ops; bool mac_supports_eee; bool phy_enable_tx_lpi; @@ -1360,12 +1361,16 @@ static void phylink_major_config(struct phylink *pl, bool restart, phylink_an_mode_str(pl->req_link_an_mode), phy_modes(state->interface));
+ pl->major_config_failed = false; + if (pl->mac_ops->mac_select_pcs) { pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface); if (IS_ERR(pcs)) { phylink_err(pl, "mac_select_pcs unexpectedly failed: %pe\n", pcs); + + pl->major_config_failed = true; return; }
@@ -1387,6 +1392,7 @@ static void phylink_major_config(struct phylink *pl, bool restart, if (err < 0) { phylink_err(pl, "mac_prepare failed: %pe\n", ERR_PTR(err)); + pl->major_config_failed = true; return; } } @@ -1410,8 +1416,15 @@ static void phylink_major_config(struct phylink *pl, bool restart,
phylink_mac_config(pl, state);
- if (pl->pcs) - phylink_pcs_post_config(pl->pcs, state->interface); + if (pl->pcs) { + err = phylink_pcs_post_config(pl->pcs, state->interface); + if (err < 0) { + phylink_err(pl, "pcs_post_config failed: %pe\n", + ERR_PTR(err)); + + pl->major_config_failed = true; + } + }
if (pl->pcs_state == PCS_STATE_STARTING || pcs_changed) phylink_pcs_enable(pl->pcs); @@ -1422,11 +1435,12 @@ static void phylink_major_config(struct phylink *pl, bool restart,
err = phylink_pcs_config(pl->pcs, neg_mode, state, !!(pl->link_config.pause & MLO_PAUSE_AN)); - if (err < 0) - phylink_err(pl, "pcs_config failed: %pe\n", - ERR_PTR(err)); - else if (err > 0) + if (err < 0) { + phylink_err(pl, "pcs_config failed: %pe\n", ERR_PTR(err)); + pl->major_config_failed = true; + } else if (err > 0) { restart = true; + }
if (restart) phylink_pcs_an_restart(pl); @@ -1434,16 +1448,22 @@ static void phylink_major_config(struct phylink *pl, bool restart, if (pl->mac_ops->mac_finish) { err = pl->mac_ops->mac_finish(pl->config, pl->act_link_an_mode, state->interface); - if (err < 0) + if (err < 0) { phylink_err(pl, "mac_finish failed: %pe\n", ERR_PTR(err)); + + pl->major_config_failed = true; + } }
if (pl->phydev && pl->phy_ib_mode) { err = phy_config_inband(pl->phydev, pl->phy_ib_mode); - if (err < 0) + if (err < 0) { phylink_err(pl, "phy_config_inband: %pe\n", ERR_PTR(err)); + + pl->major_config_failed = true; + } }
if (pl->sfp_bus) { @@ -1795,6 +1815,12 @@ static void phylink_resolve(struct work_struct *w) } }
+ /* If configuration of the interface failed, force the link down + * until we get a successful configuration. + */ + if (pl->major_config_failed) + link_state.link = false; + if (link_state.link != cur_link_state) { pl->old_link_state = link_state.link; if (!link_state.link)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
[ Upstream commit 4c8925cb9db158c812e1e11f3e74b945df7c9801 ]
When WoL is enabled, we update the software state in phylink to indicate that the link is down, and disable the resolver from bringing the link back up.
On resume, we attempt to bring the overall state into consistency by calling the .mac_link_down() method, but this is wrong if the link was already down, as phylink strictly orders the .mac_link_up() and .mac_link_down() methods - and this would break that ordering.
Fixes: f97493657c63 ("net: phylink: add suspend/resume support") Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Tested-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://patch.msgid.link/E1u55Qf-0016RN-PA@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phylink.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index b74b1c3365000..306275fbe4c98 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -82,6 +82,7 @@ struct phylink { unsigned int pcs_state;
bool link_failed; + bool suspend_link_up; bool major_config_failed; bool mac_supports_eee_ops; bool mac_supports_eee; @@ -2645,14 +2646,16 @@ void phylink_suspend(struct phylink *pl, bool mac_wol) /* Stop the resolver bringing the link up */ __set_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state);
- /* Disable the carrier, to prevent transmit timeouts, - * but one would hope all packets have been sent. This - * also means phylink_resolve() will do nothing. - */ - if (pl->netdev) - netif_carrier_off(pl->netdev); - else + pl->suspend_link_up = phylink_link_is_up(pl); + if (pl->suspend_link_up) { + /* Disable the carrier, to prevent transmit timeouts, + * but one would hope all packets have been sent. This + * also means phylink_resolve() will do nothing. + */ + if (pl->netdev) + netif_carrier_off(pl->netdev); pl->old_link_state = false; + }
/* We do not call mac_link_down() here as we want the * link to remain up to receive the WoL packets. @@ -2678,15 +2681,18 @@ void phylink_resume(struct phylink *pl) if (test_bit(PHYLINK_DISABLE_MAC_WOL, &pl->phylink_disable_state)) { /* Wake-on-Lan enabled, MAC handling */
- /* Call mac_link_down() so we keep the overall state balanced. - * Do this under the state_mutex lock for consistency. This - * will cause a "Link Down" message to be printed during - * resume, which is harmless - the true link state will be - * printed when we run a resolve. - */ - mutex_lock(&pl->state_mutex); - phylink_link_down(pl); - mutex_unlock(&pl->state_mutex); + if (pl->suspend_link_up) { + /* Call mac_link_down() so we keep the overall state + * balanced. Do this under the state_mutex lock for + * consistency. This will cause a "Link Down" message + * to be printed during resume, which is harmless - + * the true link state will be printed when we run a + * resolve. + */ + mutex_lock(&pl->state_mutex); + phylink_link_down(pl); + mutex_unlock(&pl->state_mutex); + }
/* Re-apply the link parameters so that all the settings get * restored to the MAC.
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng qingfang.deng@siflower.com.cn
[ Upstream commit b7f0ee992adf601aa00c252418266177eb7ac2bc ]
A network restart test on a router led to an out-of-memory condition, which was traced to a memory leak in the PHY LED trigger code.
The root cause is misuse of the devm API. The registration function (phy_led_triggers_register) is called from phy_attach_direct, not phy_probe, and the unregister function (phy_led_triggers_unregister) is called from phy_detach, not phy_remove. This means the register and unregister functions can be called multiple times for the same PHY device, but devm-allocated memory is not freed until the driver is unbound.
This also prevents kmemleak from detecting the leak, as the devm API internally stores the allocated pointer.
Fix this by replacing devm_kzalloc/devm_kcalloc with standard kzalloc/kcalloc, and add the corresponding kfree calls in the unregister path.
Fixes: 3928ee6485a3 ("net: phy: leds: Add support for "link" trigger") Fixes: 2e0bc452f472 ("net: phy: leds: add support for led triggers on phy link state change") Signed-off-by: Hao Guan hao.guan@siflower.com.cn Signed-off-by: Qingfang Deng qingfang.deng@siflower.com.cn Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://patch.msgid.link/20250417032557.2929427-1-dqfext@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phy_led_triggers.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/drivers/net/phy/phy_led_triggers.c b/drivers/net/phy/phy_led_triggers.c index f550576eb9dae..6f9d8da76c4df 100644 --- a/drivers/net/phy/phy_led_triggers.c +++ b/drivers/net/phy/phy_led_triggers.c @@ -91,9 +91,8 @@ int phy_led_triggers_register(struct phy_device *phy) if (!phy->phy_num_led_triggers) return 0;
- phy->led_link_trigger = devm_kzalloc(&phy->mdio.dev, - sizeof(*phy->led_link_trigger), - GFP_KERNEL); + phy->led_link_trigger = kzalloc(sizeof(*phy->led_link_trigger), + GFP_KERNEL); if (!phy->led_link_trigger) { err = -ENOMEM; goto out_clear; @@ -103,10 +102,9 @@ int phy_led_triggers_register(struct phy_device *phy) if (err) goto out_free_link;
- phy->phy_led_triggers = devm_kcalloc(&phy->mdio.dev, - phy->phy_num_led_triggers, - sizeof(struct phy_led_trigger), - GFP_KERNEL); + phy->phy_led_triggers = kcalloc(phy->phy_num_led_triggers, + sizeof(struct phy_led_trigger), + GFP_KERNEL); if (!phy->phy_led_triggers) { err = -ENOMEM; goto out_unreg_link; @@ -127,11 +125,11 @@ int phy_led_triggers_register(struct phy_device *phy) out_unreg: while (i--) phy_led_trigger_unregister(&phy->phy_led_triggers[i]); - devm_kfree(&phy->mdio.dev, phy->phy_led_triggers); + kfree(phy->phy_led_triggers); out_unreg_link: phy_led_trigger_unregister(phy->led_link_trigger); out_free_link: - devm_kfree(&phy->mdio.dev, phy->led_link_trigger); + kfree(phy->led_link_trigger); phy->led_link_trigger = NULL; out_clear: phy->phy_num_led_triggers = 0; @@ -145,8 +143,13 @@ void phy_led_triggers_unregister(struct phy_device *phy)
for (i = 0; i < phy->phy_num_led_triggers; i++) phy_led_trigger_unregister(&phy->phy_led_triggers[i]); + kfree(phy->phy_led_triggers); + phy->phy_led_triggers = NULL;
- if (phy->led_link_trigger) + if (phy->led_link_trigger) { phy_led_trigger_unregister(phy->led_link_trigger); + kfree(phy->led_link_trigger); + phy->led_link_trigger = NULL; + } } EXPORT_SYMBOL_GPL(phy_led_triggers_unregister);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato jdamato@fastly.com
[ Upstream commit 2af5adf962d4611a576061501faa8fb39590407e ]
Refactor virtnet_napi_enable and virtnet_napi_tx_enable to take a struct receive_queue. Create a helper, virtnet_napi_do_enable, which contains the logic to enable a NAPI.
Signed-off-by: Joe Damato jdamato@fastly.com Acked-by: Michael S. Tsirkin mst@redhat.com Acked-by: Jason Wang jasowang@redhat.com Tested-by: Lei Yang leiyang@redhat.com Reviewed-by: Xuan Zhuo xuanzhuo@linux.alibaba.com Link: https://patch.msgid.link/20250307011215.266806-2-jdamato@fastly.com Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 4bc12818b363 ("virtio-net: disable delayed refill when pausing rx") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/virtio_net.c | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d1ed544ba03ac..d25f68004f97e 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2789,7 +2789,8 @@ static void skb_recv_done(struct virtqueue *rvq) virtqueue_napi_schedule(&rq->napi, rvq); }
-static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi) +static void virtnet_napi_do_enable(struct virtqueue *vq, + struct napi_struct *napi) { napi_enable(napi);
@@ -2802,10 +2803,16 @@ static void virtnet_napi_enable(struct virtqueue *vq, struct napi_struct *napi) local_bh_enable(); }
-static void virtnet_napi_tx_enable(struct virtnet_info *vi, - struct virtqueue *vq, - struct napi_struct *napi) +static void virtnet_napi_enable(struct receive_queue *rq) { + virtnet_napi_do_enable(rq->vq, &rq->napi); +} + +static void virtnet_napi_tx_enable(struct send_queue *sq) +{ + struct virtnet_info *vi = sq->vq->vdev->priv; + struct napi_struct *napi = &sq->napi; + if (!napi->weight) return;
@@ -2817,7 +2824,7 @@ static void virtnet_napi_tx_enable(struct virtnet_info *vi, return; }
- return virtnet_napi_enable(vq, napi); + virtnet_napi_do_enable(sq->vq, napi); }
static void virtnet_napi_tx_disable(struct napi_struct *napi) @@ -2838,7 +2845,7 @@ static void refill_work(struct work_struct *work)
napi_disable(&rq->napi); still_empty = !try_fill_recv(vi, rq, GFP_KERNEL); - virtnet_napi_enable(rq->vq, &rq->napi); + virtnet_napi_enable(rq);
/* In theory, this can happen: if we don't get any buffers in * we will *never* try to fill again. @@ -3055,8 +3062,8 @@ static int virtnet_enable_queue_pair(struct virtnet_info *vi, int qp_index) if (err < 0) goto err_xdp_reg_mem_model;
- virtnet_napi_enable(vi->rq[qp_index].vq, &vi->rq[qp_index].napi); - virtnet_napi_tx_enable(vi, vi->sq[qp_index].vq, &vi->sq[qp_index].napi); + virtnet_napi_enable(&vi->rq[qp_index]); + virtnet_napi_tx_enable(&vi->sq[qp_index]);
return 0;
@@ -3320,7 +3327,7 @@ static void virtnet_rx_resume(struct virtnet_info *vi, struct receive_queue *rq) schedule_delayed_work(&vi->refill, 0);
if (running) - virtnet_napi_enable(rq->vq, &rq->napi); + virtnet_napi_enable(rq); }
static int virtnet_rx_resize(struct virtnet_info *vi, @@ -3383,7 +3390,7 @@ static void virtnet_tx_resume(struct virtnet_info *vi, struct send_queue *sq) __netif_tx_unlock_bh(txq);
if (running) - virtnet_napi_tx_enable(vi, sq->vq, &sq->napi); + virtnet_napi_tx_enable(sq); }
static int virtnet_tx_resize(struct virtnet_info *vi, struct send_queue *sq, @@ -5964,9 +5971,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, if (old_prog) bpf_prog_put(old_prog); if (netif_running(dev)) { - virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); - virtnet_napi_tx_enable(vi, vi->sq[i].vq, - &vi->sq[i].napi); + virtnet_napi_enable(&vi->rq[i]); + virtnet_napi_tx_enable(&vi->sq[i]); } }
@@ -5981,9 +5987,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog,
if (netif_running(dev)) { for (i = 0; i < vi->max_queue_pairs; i++) { - virtnet_napi_enable(vi->rq[i].vq, &vi->rq[i].napi); - virtnet_napi_tx_enable(vi, vi->sq[i].vq, - &vi->sq[i].napi); + virtnet_napi_enable(&vi->rq[i]); + virtnet_napi_tx_enable(&vi->sq[i]); } } if (prog)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato jdamato@fastly.com
[ Upstream commit 986a93045183ae2f13e6d99d990ae8be36f6d6b0 ]
Create virtnet_napi_disable helper and refactor virtnet_napi_tx_disable to take a struct send_queue.
Signed-off-by: Joe Damato jdamato@fastly.com Acked-by: Michael S. Tsirkin mst@redhat.com Acked-by: Jason Wang jasowang@redhat.com Tested-by: Lei Yang leiyang@redhat.com Reviewed-by: Xuan Zhuo xuanzhuo@linux.alibaba.com Link: https://patch.msgid.link/20250307011215.266806-3-jdamato@fastly.com Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 4bc12818b363 ("virtio-net: disable delayed refill when pausing rx") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/virtio_net.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index d25f68004f97e..44dbb991787ed 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -2827,12 +2827,21 @@ static void virtnet_napi_tx_enable(struct send_queue *sq) virtnet_napi_do_enable(sq->vq, napi); }
-static void virtnet_napi_tx_disable(struct napi_struct *napi) +static void virtnet_napi_tx_disable(struct send_queue *sq) { + struct napi_struct *napi = &sq->napi; + if (napi->weight) napi_disable(napi); }
+static void virtnet_napi_disable(struct receive_queue *rq) +{ + struct napi_struct *napi = &rq->napi; + + napi_disable(napi); +} + static void refill_work(struct work_struct *work) { struct virtnet_info *vi = @@ -2843,7 +2852,7 @@ static void refill_work(struct work_struct *work) for (i = 0; i < vi->curr_queue_pairs; i++) { struct receive_queue *rq = &vi->rq[i];
- napi_disable(&rq->napi); + virtnet_napi_disable(rq); still_empty = !try_fill_recv(vi, rq, GFP_KERNEL); virtnet_napi_enable(rq);
@@ -3042,8 +3051,8 @@ static int virtnet_poll(struct napi_struct *napi, int budget)
static void virtnet_disable_queue_pair(struct virtnet_info *vi, int qp_index) { - virtnet_napi_tx_disable(&vi->sq[qp_index].napi); - napi_disable(&vi->rq[qp_index].napi); + virtnet_napi_tx_disable(&vi->sq[qp_index]); + virtnet_napi_disable(&vi->rq[qp_index]); xdp_rxq_info_unreg(&vi->rq[qp_index].xdp_rxq); }
@@ -3314,7 +3323,7 @@ static void virtnet_rx_pause(struct virtnet_info *vi, struct receive_queue *rq) bool running = netif_running(vi->dev);
if (running) { - napi_disable(&rq->napi); + virtnet_napi_disable(rq); virtnet_cancel_dim(vi, &rq->dim); } } @@ -3356,7 +3365,7 @@ static void virtnet_tx_pause(struct virtnet_info *vi, struct send_queue *sq) qindex = sq - vi->sq;
if (running) - virtnet_napi_tx_disable(&sq->napi); + virtnet_napi_tx_disable(sq);
txq = netdev_get_tx_queue(vi->dev, qindex);
@@ -5933,8 +5942,8 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, /* Make sure NAPI is not using any XDP TX queues for RX. */ if (netif_running(dev)) { for (i = 0; i < vi->max_queue_pairs; i++) { - napi_disable(&vi->rq[i].napi); - virtnet_napi_tx_disable(&vi->sq[i].napi); + virtnet_napi_disable(&vi->rq[i]); + virtnet_napi_tx_disable(&vi->sq[i]); } }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bui Quang Minh minhquangbui99@gmail.com
[ Upstream commit 4bc12818b363bd30f0f7348dd9ab077290a637ae ]
When pausing rx (e.g. set up xdp, xsk pool, rx resize), we call napi_disable() on the receive queue's napi. In delayed refill_work, it also calls napi_disable() on the receive queue's napi. When napi_disable() is called on an already disabled napi, it will sleep in napi_disable_locked while still holding the netdev_lock. As a result, later napi_enable gets stuck too as it cannot acquire the netdev_lock. This leads to refill_work and the pause-then-resume tx are stuck altogether.
This scenario can be reproducible by binding a XDP socket to virtio-net interface without setting up the fill ring. As a result, try_fill_recv will fail until the fill ring is set up and refill_work is scheduled.
This commit adds virtnet_rx_(pause/resume)_all helpers and fixes up the virtnet_rx_resume to disable future and cancel all inflights delayed refill_work before calling napi_disable() to pause the rx.
Fixes: 413f0271f396 ("net: protect NAPI enablement with netdev_lock()") Acked-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Bui Quang Minh minhquangbui99@gmail.com Acked-by: Jason Wang jasowang@redhat.com Link: https://patch.msgid.link/20250417072806.18660-2-minhquangbui99@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/virtio_net.c | 69 +++++++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 12 deletions(-)
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 44dbb991787ed..3e4896d9537ee 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -3318,7 +3318,8 @@ static netdev_tx_t start_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; }
-static void virtnet_rx_pause(struct virtnet_info *vi, struct receive_queue *rq) +static void __virtnet_rx_pause(struct virtnet_info *vi, + struct receive_queue *rq) { bool running = netif_running(vi->dev);
@@ -3328,17 +3329,63 @@ static void virtnet_rx_pause(struct virtnet_info *vi, struct receive_queue *rq) } }
-static void virtnet_rx_resume(struct virtnet_info *vi, struct receive_queue *rq) +static void virtnet_rx_pause_all(struct virtnet_info *vi) +{ + int i; + + /* + * Make sure refill_work does not run concurrently to + * avoid napi_disable race which leads to deadlock. + */ + disable_delayed_refill(vi); + cancel_delayed_work_sync(&vi->refill); + for (i = 0; i < vi->max_queue_pairs; i++) + __virtnet_rx_pause(vi, &vi->rq[i]); +} + +static void virtnet_rx_pause(struct virtnet_info *vi, struct receive_queue *rq) +{ + /* + * Make sure refill_work does not run concurrently to + * avoid napi_disable race which leads to deadlock. + */ + disable_delayed_refill(vi); + cancel_delayed_work_sync(&vi->refill); + __virtnet_rx_pause(vi, rq); +} + +static void __virtnet_rx_resume(struct virtnet_info *vi, + struct receive_queue *rq, + bool refill) { bool running = netif_running(vi->dev);
- if (!try_fill_recv(vi, rq, GFP_KERNEL)) + if (refill && !try_fill_recv(vi, rq, GFP_KERNEL)) schedule_delayed_work(&vi->refill, 0);
if (running) virtnet_napi_enable(rq); }
+static void virtnet_rx_resume_all(struct virtnet_info *vi) +{ + int i; + + enable_delayed_refill(vi); + for (i = 0; i < vi->max_queue_pairs; i++) { + if (i < vi->curr_queue_pairs) + __virtnet_rx_resume(vi, &vi->rq[i], true); + else + __virtnet_rx_resume(vi, &vi->rq[i], false); + } +} + +static void virtnet_rx_resume(struct virtnet_info *vi, struct receive_queue *rq) +{ + enable_delayed_refill(vi); + __virtnet_rx_resume(vi, rq, true); +} + static int virtnet_rx_resize(struct virtnet_info *vi, struct receive_queue *rq, u32 ring_num) { @@ -5939,12 +5986,12 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, if (prog) bpf_prog_add(prog, vi->max_queue_pairs - 1);
+ virtnet_rx_pause_all(vi); + /* Make sure NAPI is not using any XDP TX queues for RX. */ if (netif_running(dev)) { - for (i = 0; i < vi->max_queue_pairs; i++) { - virtnet_napi_disable(&vi->rq[i]); + for (i = 0; i < vi->max_queue_pairs; i++) virtnet_napi_tx_disable(&vi->sq[i]); - } }
if (!prog) { @@ -5976,13 +6023,12 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, vi->xdp_enabled = false; }
+ virtnet_rx_resume_all(vi); for (i = 0; i < vi->max_queue_pairs; i++) { if (old_prog) bpf_prog_put(old_prog); - if (netif_running(dev)) { - virtnet_napi_enable(&vi->rq[i]); + if (netif_running(dev)) virtnet_napi_tx_enable(&vi->sq[i]); - } }
return 0; @@ -5994,11 +6040,10 @@ static int virtnet_xdp_set(struct net_device *dev, struct bpf_prog *prog, rcu_assign_pointer(vi->rq[i].xdp_prog, old_prog); }
+ virtnet_rx_resume_all(vi); if (netif_running(dev)) { - for (i = 0; i < vi->max_queue_pairs; i++) { - virtnet_napi_enable(&vi->rq[i]); + for (i = 0; i < vi->max_queue_pairs; i++) virtnet_napi_tx_enable(&vi->sq[i]); - } } if (prog) bpf_prog_sub(prog, vi->max_queue_pairs - 1);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tung Nguyen tung.quang.nguyen@est.tech
[ Upstream commit d63527e109e811ef11abb1c2985048fdb528b4cb ]
syzbot reported:
tipc: Node number set to 1055423674 Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] CPU: 3 UID: 0 PID: 6017 Comm: kworker/3:5 Not tainted 6.15.0-rc1-syzkaller-00246-g900241a5cc15 #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2~bpo12+1 04/01/2014 Workqueue: events tipc_net_finalize_work RIP: 0010:tipc_mon_reinit_self+0x11c/0x210 net/tipc/monitor.c:719 ... RSP: 0018:ffffc9000356fb68 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000003ee87cba RDX: 0000000000000000 RSI: ffffffff8dbc56a7 RDI: ffff88804c2cc010 RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000007 R13: fffffbfff2111097 R14: ffff88804ead8000 R15: ffff88804ead9010 FS: 0000000000000000(0000) GS:ffff888097ab9000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000f720eb00 CR3: 000000000e182000 CR4: 0000000000352ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Call Trace: <TASK> tipc_net_finalize+0x10b/0x180 net/tipc/net.c:140 process_one_work+0x9cc/0x1b70 kernel/workqueue.c:3238 process_scheduled_works kernel/workqueue.c:3319 [inline] worker_thread+0x6c8/0xf10 kernel/workqueue.c:3400 kthread+0x3c2/0x780 kernel/kthread.c:464 ret_from_fork+0x45/0x80 arch/x86/kernel/process.c:153 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK> ... RIP: 0010:tipc_mon_reinit_self+0x11c/0x210 net/tipc/monitor.c:719 ... RSP: 0018:ffffc9000356fb68 EFLAGS: 00010246 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 000000003ee87cba RDX: 0000000000000000 RSI: ffffffff8dbc56a7 RDI: ffff88804c2cc010 RBP: dffffc0000000000 R08: 0000000000000001 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000007 R13: fffffbfff2111097 R14: ffff88804ead8000 R15: ffff88804ead9010 FS: 0000000000000000(0000) GS:ffff888097ab9000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000f720eb00 CR3: 000000000e182000 CR4: 0000000000352ef0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
There is a racing condition between workqueue created when enabling bearer and another thread created when disabling bearer right after that as follow:
enabling_bearer | disabling_bearer --------------- | ---------------- tipc_disc_timeout() | { | bearer_disable() ... | { schedule_work(&tn->work); | tipc_mon_delete() ... | { } | ... | write_lock_bh(&mon->lock); | mon->self = NULL; | write_unlock_bh(&mon->lock); | ... | } tipc_net_finalize_work() | } { | ... | tipc_net_finalize() | { | ... | tipc_mon_reinit_self() | { | ... | write_lock_bh(&mon->lock); | mon->self->addr = tipc_own_addr(net); | write_unlock_bh(&mon->lock); | ... | } | ... | } | ... | } |
'mon->self' is set to NULL in disabling_bearer thread and dereferenced later in enabling_bearer thread.
This commit fixes this issue by validating 'mon->self' before assigning node address to it.
Reported-by: syzbot+ed60da8d686dc709164c@syzkaller.appspotmail.com Fixes: 46cb01eeeb86 ("tipc: update mon's self addr when node addr generated") Signed-off-by: Tung Nguyen tung.quang.nguyen@est.tech Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/20250417074826.578115-1-tung.quang.nguyen@est.tech Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/tipc/monitor.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index e2f19627e43d5..b45c5b91bc7af 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c @@ -716,7 +716,8 @@ void tipc_mon_reinit_self(struct net *net) if (!mon) continue; write_lock_bh(&mon->lock); - mon->self->addr = tipc_own_addr(net); + if (mon->self) + mon->self->addr = tipc_own_addr(net); write_unlock_bh(&mon->lock); } }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bo-Cun Chen bc-bocun.chen@mediatek.com
[ Upstream commit 491ef1117c56476f199b481f8c68820fe4c3a7c2 ]
Change hardware configuration for the NETSYSv3. - Enable PSE dummy page mechanism for the GDM1/2/3 - Enable PSE drop mechanism when the WDMA Rx ring full - Enable PSE no-drop mechanism for packets from the WDMA Tx - Correct PSE free drop threshold - Correct PSE CDMA high threshold
Fixes: 1953f134a1a8b ("net: ethernet: mtk_eth_soc: add NETSYS_V3 version support") Signed-off-by: Bo-Cun Chen bc-bocun.chen@mediatek.com Signed-off-by: Daniel Golle daniel@makrotopia.org Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/b71f8fd9d4bb69c646c4d558f9331dd965068606.1744907886... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/mediatek/mtk_eth_soc.c | 24 +++++++++++++++++---- drivers/net/ethernet/mediatek/mtk_eth_soc.h | 10 ++++++++- 2 files changed, 29 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c index 0cd1ecacfd29f..477b8732b8609 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c @@ -3997,11 +3997,27 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset) mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
if (mtk_is_netsys_v3_or_greater(eth)) { - /* PSE should not drop port1, port8 and port9 packets */ - mtk_w32(eth, 0x00000302, PSE_DROP_CFG); + /* PSE dummy page mechanism */ + mtk_w32(eth, PSE_DUMMY_WORK_GDM(1) | PSE_DUMMY_WORK_GDM(2) | + PSE_DUMMY_WORK_GDM(3) | DUMMY_PAGE_THR, PSE_DUMY_REQ); + + /* PSE free buffer drop threshold */ + mtk_w32(eth, 0x00600009, PSE_IQ_REV(8)); + + /* PSE should not drop port8, port9 and port13 packets from + * WDMA Tx + */ + mtk_w32(eth, 0x00002300, PSE_DROP_CFG); + + /* PSE should drop packets to port8, port9 and port13 on WDMA Rx + * ring full + */ + mtk_w32(eth, 0x00002300, PSE_PPE_DROP(0)); + mtk_w32(eth, 0x00002300, PSE_PPE_DROP(1)); + mtk_w32(eth, 0x00002300, PSE_PPE_DROP(2));
/* GDM and CDM Threshold */ - mtk_w32(eth, 0x00000707, MTK_CDMW0_THRES); + mtk_w32(eth, 0x08000707, MTK_CDMW0_THRES); mtk_w32(eth, 0x00000077, MTK_CDMW1_THRES);
/* Disable GDM1 RX CRC stripping */ @@ -4018,7 +4034,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset) mtk_w32(eth, 0x00000300, PSE_DROP_CFG);
/* PSE should drop packets to port 8/9 on WDMA Rx ring full */ - mtk_w32(eth, 0x00000300, PSE_PPE0_DROP); + mtk_w32(eth, 0x00000300, PSE_PPE_DROP(0));
/* PSE Free Queue Flow Control */ mtk_w32(eth, 0x01fa01f4, PSE_FQFC_CFG2); diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h index 8d7b6818d8601..0570623e569d5 100644 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h @@ -151,7 +151,15 @@ #define PSE_FQFC_CFG1 0x100 #define PSE_FQFC_CFG2 0x104 #define PSE_DROP_CFG 0x108 -#define PSE_PPE0_DROP 0x110 +#define PSE_PPE_DROP(x) (0x110 + ((x) * 0x4)) + +/* PSE Last FreeQ Page Request Control */ +#define PSE_DUMY_REQ 0x10C +/* PSE_DUMY_REQ is not a typo but actually called like that also in + * MediaTek's datasheet + */ +#define PSE_DUMMY_WORK_GDM(x) BIT(16 + (x)) +#define DUMMY_PAGE_THR 0x1
/* PSE Input Queue Reservation Register*/ #define PSE_IQ_REV(x) (0x140 + (((x) - 1) << 2))
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit 0d039eac6e5950f9d1ecc9e410c2fd1feaeab3b6 ]
Normally do_lock_mount(path, _) is locking a mountpoint pinned by *path and at the time when matching unlock_mount() unlocks that location it is still pinned by the same thing.
Unfortunately, for 'beneath' case it's no longer that simple - the object being locked is not the one *path points to. It's the mountpoint of path->mnt. The thing is, without sufficient locking ->mnt_parent may change under us and none of the locks are held at that point. The rules are * mount_lock stabilizes m->mnt_parent for any mount m. * namespace_sem stabilizes m->mnt_parent, provided that m is mounted. * if either of the above holds and refcount of m is positive, we are guaranteed the same for refcount of m->mnt_parent.
namespace_sem nests inside inode_lock(), so do_lock_mount() has to take inode_lock() before grabbing namespace_sem. It does recheck that path->mnt is still mounted in the same place after getting namespace_sem, and it does take care to pin the dentry. It is needed, since otherwise we might end up with racing mount --move (or umount) happening while we were getting locks; in that case dentry would no longer be a mountpoint and could've been evicted on memory pressure along with its inode - not something you want when grabbing lock on that inode.
However, pinning a dentry is not enough - the matching mount is also pinned only by the fact that path->mnt is mounted on top it and at that point we are not holding any locks whatsoever, so the same kind of races could end up with all references to that mount gone just as we are about to enter inode_lock(). If that happens, we are left with filesystem being shut down while we are holding a dentry reference on it; results are not pretty.
What we need to do is grab both dentry and mount at the same time; that makes inode_lock() safe *and* avoids the problem with fs getting shut down under us. After taking namespace_sem we verify that path->mnt is still mounted (which stabilizes its ->mnt_parent) and check that it's still mounted at the same place. From that point on to the matching namespace_unlock() we are guaranteed that mount/dentry pair we'd grabbed are also pinned by being the mountpoint of path->mnt, so we can quietly drop both the dentry reference (as the current code does) and mnt one - it's OK to do under namespace_sem, since we are not dropping the final refs.
That solves the problem on do_lock_mount() side; unlock_mount() also has one, since dentry is guaranteed to stay pinned only until the namespace_unlock(). That's easy to fix - just have inode_unlock() done earlier, while it's still pinned by mp->m_dentry.
Fixes: 6ac392815628 "fs: allow to mount beneath top mount" # v6.5+ Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/namespace.c | 69 ++++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 33 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c index d401486fe95d1..280a6ebc46d93 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2640,56 +2640,62 @@ static struct mountpoint *do_lock_mount(struct path *path, bool beneath) struct vfsmount *mnt = path->mnt; struct dentry *dentry; struct mountpoint *mp = ERR_PTR(-ENOENT); + struct path under = {};
for (;;) { - struct mount *m; + struct mount *m = real_mount(mnt);
if (beneath) { - m = real_mount(mnt); + path_put(&under); read_seqlock_excl(&mount_lock); - dentry = dget(m->mnt_mountpoint); + under.mnt = mntget(&m->mnt_parent->mnt); + under.dentry = dget(m->mnt_mountpoint); read_sequnlock_excl(&mount_lock); + dentry = under.dentry; } else { dentry = path->dentry; }
inode_lock(dentry->d_inode); - if (unlikely(cant_mount(dentry))) { - inode_unlock(dentry->d_inode); - goto out; - } - namespace_lock();
- if (beneath && (!is_mounted(mnt) || m->mnt_mountpoint != dentry)) { + if (unlikely(cant_mount(dentry) || !is_mounted(mnt))) + break; // not to be mounted on + + if (beneath && unlikely(m->mnt_mountpoint != dentry || + &m->mnt_parent->mnt != under.mnt)) { namespace_unlock(); inode_unlock(dentry->d_inode); - goto out; + continue; // got moved }
mnt = lookup_mnt(path); - if (likely(!mnt)) + if (unlikely(mnt)) { + namespace_unlock(); + inode_unlock(dentry->d_inode); + path_put(path); + path->mnt = mnt; + path->dentry = dget(mnt->mnt_root); + continue; // got overmounted + } + mp = get_mountpoint(dentry); + if (IS_ERR(mp)) break; - - namespace_unlock(); - inode_unlock(dentry->d_inode); - if (beneath) - dput(dentry); - path_put(path); - path->mnt = mnt; - path->dentry = dget(mnt->mnt_root); - } - - mp = get_mountpoint(dentry); - if (IS_ERR(mp)) { - namespace_unlock(); - inode_unlock(dentry->d_inode); + if (beneath) { + /* + * @under duplicates the references that will stay + * at least until namespace_unlock(), so the path_put() + * below is safe (and OK to do under namespace_lock - + * we are not dropping the final references here). + */ + path_put(&under); + } + return mp; } - -out: + namespace_unlock(); + inode_unlock(dentry->d_inode); if (beneath) - dput(dentry); - + path_put(&under); return mp; }
@@ -2700,14 +2706,11 @@ static inline struct mountpoint *lock_mount(struct path *path)
static void unlock_mount(struct mountpoint *where) { - struct dentry *dentry = where->m_dentry; - + inode_unlock(where->m_dentry->d_inode); read_seqlock_excl(&mount_lock); put_mountpoint(where); read_sequnlock_excl(&mount_lock); - namespace_unlock(); - inode_unlock(dentry->d_inode); }
static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang xiyou.wangcong@gmail.com
[ Upstream commit 3df275ef0a6ae181e8428a6589ef5d5231e58b5c ]
This patch fixes a Use-After-Free vulnerability in the HFSC qdisc class handling. The issue occurs due to a time-of-check/time-of-use condition in hfsc_change_class() when working with certain child qdiscs like netem or codel.
The vulnerability works as follows: 1. hfsc_change_class() checks if a class has packets (q.qlen != 0) 2. It then calls qdisc_peek_len(), which for certain qdiscs (e.g., codel, netem) might drop packets and empty the queue 3. The code continues assuming the queue is still non-empty, adding the class to vttree 4. This breaks HFSC scheduler assumptions that only non-empty classes are in vttree 5. Later, when the class is destroyed, this can lead to a Use-After-Free
The fix adds a second queue length check after qdisc_peek_len() to verify the queue wasn't emptied.
Fixes: 21f4d5cc25ec ("net_sched/hfsc: fix curve activation in hfsc_change_class()") Reported-by: Gerrard Tai gerrard.tai@starlabs.sg Reviewed-by: Konstantin Khlebnikov koct9i@gmail.com Signed-off-by: Cong Wang xiyou.wangcong@gmail.com Reviewed-by: Jamal Hadi Salim jhs@mojatatu.com Link: https://patch.msgid.link/20250417184732.943057-2-xiyou.wangcong@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_hfsc.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index c287bf8423b47..e730d3f791c24 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -958,6 +958,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
if (cl != NULL) { int old_flags; + int len = 0;
if (parentid) { if (cl->cl_parent && @@ -988,9 +989,13 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid, if (usc != NULL) hfsc_change_usc(cl, usc, cur_time);
+ if (cl->qdisc->q.qlen != 0) + len = qdisc_peek_len(cl->qdisc); + /* Check queue length again since some qdisc implementations + * (e.g., netem/codel) might empty the queue during the peek + * operation. + */ if (cl->qdisc->q.qlen != 0) { - int len = qdisc_peek_len(cl->qdisc); - if (cl->cl_flags & HFSC_RSC) { if (old_flags & HFSC_RSC) update_ed(cl, len);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang xiyou.wangcong@gmail.com
[ Upstream commit 6ccbda44e2cc3d26fd22af54c650d6d5d801addf ]
Similarly to the previous patch, we need to safe guard hfsc_dequeue() too. But for this one, we don't have a reliable reproducer.
Fixes: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ("Linux-2.6.12-rc2") Reported-by: Gerrard Tai gerrard.tai@starlabs.sg Signed-off-by: Cong Wang xiyou.wangcong@gmail.com Reviewed-by: Jamal Hadi Salim jhs@mojatatu.com Link: https://patch.msgid.link/20250417184732.943057-3-xiyou.wangcong@gmail.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/sched/sch_hfsc.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c index e730d3f791c24..5bb4ab9941d6e 100644 --- a/net/sched/sch_hfsc.c +++ b/net/sched/sch_hfsc.c @@ -1637,10 +1637,16 @@ hfsc_dequeue(struct Qdisc *sch) if (cl->qdisc->q.qlen != 0) { /* update ed */ next_len = qdisc_peek_len(cl->qdisc); - if (realtime) - update_ed(cl, next_len); - else - update_d(cl, next_len); + /* Check queue length again since some qdisc implementations + * (e.g., netem/codel) might empty the queue during the peek + * operation. + */ + if (cl->qdisc->q.qlen != 0) { + if (realtime) + update_ed(cl, next_len); + else + update_d(cl, next_len); + } } else { /* the class becomes passive */ eltree_remove(cl);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Golle daniel@makrotopia.org
[ Upstream commit 497041d763016c2e8314d2f6a329a9b77c3797ca ]
MT7531 standalone and MMIO variants found in MT7988 and EN7581 share most basic properties. Despite that, assisted_learning_on_cpu_port and mtu_enforcement_ingress were only applied for MT7531 but not for MT7988 or EN7581, causing the expected issues on MMIO devices.
Apply both settings equally also for MT7988 and EN7581 by moving both assignments form mt7531_setup() to mt7531_setup_common().
This fixes unwanted flooding of packets due to unknown unicast during DA lookup, as well as issues with heterogenous MTU settings.
Fixes: 7f54cc9772ce ("net: dsa: mt7530: split-off common parts from mt7531_setup") Signed-off-by: Daniel Golle daniel@makrotopia.org Reviewed-by: Chester A. Unal chester.a.unal@arinc9.com Link: https://patch.msgid.link/89ed7ec6d4fa0395ac53ad2809742bb1ce61ed12.1745290867... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/dsa/mt7530.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c index 5883eb93efb11..22513f3d56db1 100644 --- a/drivers/net/dsa/mt7530.c +++ b/drivers/net/dsa/mt7530.c @@ -2541,6 +2541,9 @@ mt7531_setup_common(struct dsa_switch *ds) struct mt7530_priv *priv = ds->priv; int ret, i;
+ ds->assisted_learning_on_cpu_port = true; + ds->mtu_enforcement_ingress = true; + mt753x_trap_frames(priv);
/* Enable and reset MIB counters */ @@ -2688,9 +2691,6 @@ mt7531_setup(struct dsa_switch *ds) if (ret) return ret;
- ds->assisted_learning_on_cpu_port = true; - ds->mtu_enforcement_ingress = true; - return 0; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brett Creeley brett.creeley@amd.com
[ Upstream commit d9e2f070d8af60f2c8c02b2ddf0a9e90b4e9220c ]
The pds_core's adminq is protected by the adminq_lock, which prevents more than 1 command to be posted onto it at any one time. This makes it so the client drivers cannot simultaneously post adminq commands. However, the completions happen in a different context, which means multiple adminq commands can be posted sequentially and all waiting on completion.
On the FW side, the backing adminq request queue is only 16 entries long and the retry mechanism and/or overflow/stuck prevention is lacking. This can cause the adminq to get stuck, so commands are no longer processed and completions are no longer sent by the FW.
As an initial fix, prevent more than 16 outstanding adminq commands so there's no way to cause the adminq from getting stuck. This works because the backing adminq request queue will never have more than 16 pending adminq commands, so it will never overflow. This is done by reducing the adminq depth to 16.
Fixes: 45d76f492938 ("pds_core: set up device and adminq") Reviewed-by: Michal Swiatkowski michal.swiatkowski@linux.intel.com Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: Brett Creeley brett.creeley@amd.com Signed-off-by: Shannon Nelson shannon.nelson@amd.com Reviewed-by: Jacob Keller jacob.e.keller@intel.com Link: https://patch.msgid.link/20250421174606.3892-2-shannon.nelson@amd.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amd/pds_core/core.c | 5 +---- drivers/net/ethernet/amd/pds_core/core.h | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/amd/pds_core/core.c b/drivers/net/ethernet/amd/pds_core/core.c index 536635e577279..4830292d5f879 100644 --- a/drivers/net/ethernet/amd/pds_core/core.c +++ b/drivers/net/ethernet/amd/pds_core/core.c @@ -325,10 +325,7 @@ static int pdsc_core_init(struct pdsc *pdsc) size_t sz; int err;
- /* Scale the descriptor ring length based on number of CPUs and VFs */ - numdescs = max_t(int, PDSC_ADMINQ_MIN_LENGTH, num_online_cpus()); - numdescs += 2 * pci_sriov_get_totalvfs(pdsc->pdev); - numdescs = roundup_pow_of_two(numdescs); + numdescs = PDSC_ADMINQ_MAX_LENGTH; err = pdsc_qcq_alloc(pdsc, PDS_CORE_QTYPE_ADMINQ, 0, "adminq", PDS_CORE_QCQ_F_CORE | PDS_CORE_QCQ_F_INTR, numdescs, diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h index 14522d6d5f86b..543097983bf60 100644 --- a/drivers/net/ethernet/amd/pds_core/core.h +++ b/drivers/net/ethernet/amd/pds_core/core.h @@ -16,7 +16,7 @@
#define PDSC_WATCHDOG_SECS 5 #define PDSC_QUEUE_NAME_MAX_SZ 16 -#define PDSC_ADMINQ_MIN_LENGTH 16 /* must be a power of two */ +#define PDSC_ADMINQ_MAX_LENGTH 16 /* must be a power of two */ #define PDSC_NOTIFYQ_LENGTH 64 /* must be a power of two */ #define PDSC_TEARDOWN_RECOVERY false #define PDSC_TEARDOWN_REMOVING true
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brett Creeley brett.creeley@amd.com
[ Upstream commit 2567daad69cd1107fc0ec29b1615f110d7cf7385 ]
If the FW doesn't support the PDS_CORE_CMD_FW_CONTROL command the driver might at the least print garbage and at the worst crash when the user runs the "devlink dev info" devlink command.
This happens because the stack variable fw_list is not 0 initialized which results in fw_list.num_fw_slots being a garbage value from the stack. Then the driver tries to access fw_list.fw_names[i] with i >= ARRAY_SIZE and runs off the end of the array.
Fix this by initializing the fw_list and by not failing completely if the devcmd fails because other useful information is printed via devlink dev info even if the devcmd fails.
Fixes: 45d76f492938 ("pds_core: set up device and adminq") Signed-off-by: Brett Creeley brett.creeley@amd.com Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: Shannon Nelson shannon.nelson@amd.com Reviewed-by: Jacob Keller jacob.e.keller@intel.com Link: https://patch.msgid.link/20250421174606.3892-3-shannon.nelson@amd.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amd/pds_core/devlink.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/amd/pds_core/devlink.c b/drivers/net/ethernet/amd/pds_core/devlink.c index 44971e71991ff..ca23cde385e67 100644 --- a/drivers/net/ethernet/amd/pds_core/devlink.c +++ b/drivers/net/ethernet/amd/pds_core/devlink.c @@ -102,7 +102,7 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, .fw_control.opcode = PDS_CORE_CMD_FW_CONTROL, .fw_control.oper = PDS_CORE_FW_GET_LIST, }; - struct pds_core_fw_list_info fw_list; + struct pds_core_fw_list_info fw_list = {}; struct pdsc *pdsc = devlink_priv(dl); union pds_core_dev_comp comp; char buf[32]; @@ -115,8 +115,6 @@ int pdsc_dl_info_get(struct devlink *dl, struct devlink_info_req *req, if (!err) memcpy_fromio(&fw_list, pdsc->cmd_regs->data, sizeof(fw_list)); mutex_unlock(&pdsc->devcmd_lock); - if (err && err != -EIO) - return err;
listlen = min(fw_list.num_fw_slots, ARRAY_SIZE(fw_list.fw_names)); for (i = 0; i < listlen; i++) {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brett Creeley brett.creeley@amd.com
[ Upstream commit f9559d818205a4a0b9cd87181ef46e101ea11157 ]
When the pds_core driver was first created there were some race conditions around using the adminq, especially for client drivers. To reduce the possibility of a race condition there's a check against pf->state in pds_client_adminq_cmd(). This is problematic for a couple of reasons:
1. The PDSC_S_INITING_DRIVER bit is set during probe, but not cleared until after everything in probe is complete, which includes creating the auxiliary devices. For pds_fwctl this means it can't make any adminq commands until after pds_core's probe is complete even though the adminq is fully up by the time pds_fwctl's auxiliary device is created.
2. The race conditions around using the adminq have been fixed and this path is already protected against client drivers calling pds_client_adminq_cmd() if the adminq isn't ready, i.e. see pdsc_adminq_post() -> pdsc_adminq_inc_if_up().
Fix this by removing the pf->state check in pds_client_adminq_cmd() because invalid accesses to pds_core's adminq is already handled by pdsc_adminq_post()->pdsc_adminq_inc_if_up().
Fixes: 10659034c622 ("pds_core: add the aux client API") Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: Brett Creeley brett.creeley@amd.com Signed-off-by: Shannon Nelson shannon.nelson@amd.com Reviewed-by: Jacob Keller jacob.e.keller@intel.com Link: https://patch.msgid.link/20250421174606.3892-4-shannon.nelson@amd.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amd/pds_core/auxbus.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/drivers/net/ethernet/amd/pds_core/auxbus.c b/drivers/net/ethernet/amd/pds_core/auxbus.c index 2babea1109917..b76a9b7e0aed6 100644 --- a/drivers/net/ethernet/amd/pds_core/auxbus.c +++ b/drivers/net/ethernet/amd/pds_core/auxbus.c @@ -107,9 +107,6 @@ int pds_client_adminq_cmd(struct pds_auxiliary_dev *padev, dev_dbg(pf->dev, "%s: %s opcode %d\n", __func__, dev_name(&padev->aux_dev.dev), req->opcode);
- if (pf->state) - return -ENXIO; - /* Wrap the client's request */ cmd.client_request.opcode = PDS_AQ_CMD_CLIENT_CMD; cmd.client_request.client_id = cpu_to_le16(padev->client_id);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shannon Nelson shannon.nelson@amd.com
[ Upstream commit 3f77c3dfffc7063428b100c4945ca2a7a8680380 ]
Make the wait_context a full part of the q_info struct rather than a stack variable that goes away after pdsc_adminq_post() is done so that the context is still available after the wait loop has given up.
There was a case where a slow development firmware caused the adminq request to time out, but then later the FW finally finished the request and sent the interrupt. The handler tried to complete_all() the completion context that had been created on the stack in pdsc_adminq_post() but no longer existed. This caused bad pointer usage, kernel crashes, and much wailing and gnashing of teeth.
Fixes: 01ba61b55b20 ("pds_core: Add adminq processing and commands") Reviewed-by: Simon Horman horms@kernel.org Signed-off-by: Shannon Nelson shannon.nelson@amd.com Reviewed-by: Jacob Keller jacob.e.keller@intel.com Link: https://patch.msgid.link/20250421174606.3892-5-shannon.nelson@amd.com Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/amd/pds_core/adminq.c | 36 +++++++++------------- drivers/net/ethernet/amd/pds_core/core.c | 4 ++- drivers/net/ethernet/amd/pds_core/core.h | 2 +- 3 files changed, 18 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/amd/pds_core/adminq.c b/drivers/net/ethernet/amd/pds_core/adminq.c index c83a0a80d5334..506f682d15c10 100644 --- a/drivers/net/ethernet/amd/pds_core/adminq.c +++ b/drivers/net/ethernet/amd/pds_core/adminq.c @@ -5,11 +5,6 @@
#include "core.h"
-struct pdsc_wait_context { - struct pdsc_qcq *qcq; - struct completion wait_completion; -}; - static int pdsc_process_notifyq(struct pdsc_qcq *qcq) { union pds_core_notifyq_comp *comp; @@ -109,10 +104,10 @@ void pdsc_process_adminq(struct pdsc_qcq *qcq) q_info = &q->info[q->tail_idx]; q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
- /* Copy out the completion data */ - memcpy(q_info->dest, comp, sizeof(*comp)); - - complete_all(&q_info->wc->wait_completion); + if (!completion_done(&q_info->completion)) { + memcpy(q_info->dest, comp, sizeof(*comp)); + complete(&q_info->completion); + }
if (cq->tail_idx == cq->num_descs - 1) cq->done_color = !cq->done_color; @@ -162,8 +157,7 @@ irqreturn_t pdsc_adminq_isr(int irq, void *data) static int __pdsc_adminq_post(struct pdsc *pdsc, struct pdsc_qcq *qcq, union pds_core_adminq_cmd *cmd, - union pds_core_adminq_comp *comp, - struct pdsc_wait_context *wc) + union pds_core_adminq_comp *comp) { struct pdsc_queue *q = &qcq->q; struct pdsc_q_info *q_info; @@ -205,9 +199,9 @@ static int __pdsc_adminq_post(struct pdsc *pdsc, /* Post the request */ index = q->head_idx; q_info = &q->info[index]; - q_info->wc = wc; q_info->dest = comp; memcpy(q_info->desc, cmd, sizeof(*cmd)); + reinit_completion(&q_info->completion);
dev_dbg(pdsc->dev, "head_idx %d tail_idx %d\n", q->head_idx, q->tail_idx); @@ -231,16 +225,13 @@ int pdsc_adminq_post(struct pdsc *pdsc, union pds_core_adminq_comp *comp, bool fast_poll) { - struct pdsc_wait_context wc = { - .wait_completion = - COMPLETION_INITIALIZER_ONSTACK(wc.wait_completion), - }; unsigned long poll_interval = 1; unsigned long poll_jiffies; unsigned long time_limit; unsigned long time_start; unsigned long time_done; unsigned long remaining; + struct completion *wc; int err = 0; int index;
@@ -250,20 +241,19 @@ int pdsc_adminq_post(struct pdsc *pdsc, return -ENXIO; }
- wc.qcq = &pdsc->adminqcq; - index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp, &wc); + index = __pdsc_adminq_post(pdsc, &pdsc->adminqcq, cmd, comp); if (index < 0) { err = index; goto err_out; }
+ wc = &pdsc->adminqcq.q.info[index].completion; time_start = jiffies; time_limit = time_start + HZ * pdsc->devcmd_timeout; do { /* Timeslice the actual wait to catch IO errors etc early */ poll_jiffies = msecs_to_jiffies(poll_interval); - remaining = wait_for_completion_timeout(&wc.wait_completion, - poll_jiffies); + remaining = wait_for_completion_timeout(wc, poll_jiffies); if (remaining) break;
@@ -292,9 +282,11 @@ int pdsc_adminq_post(struct pdsc *pdsc, dev_dbg(pdsc->dev, "%s: elapsed %d msecs\n", __func__, jiffies_to_msecs(time_done - time_start));
- /* Check the results */ - if (time_after_eq(time_done, time_limit)) + /* Check the results and clear an un-completed timeout */ + if (time_after_eq(time_done, time_limit) && !completion_done(wc)) { err = -ETIMEDOUT; + complete(wc); + }
dev_dbg(pdsc->dev, "read admin queue completion idx %d:\n", index); dynamic_hex_dump("comp ", DUMP_PREFIX_OFFSET, 16, 1, diff --git a/drivers/net/ethernet/amd/pds_core/core.c b/drivers/net/ethernet/amd/pds_core/core.c index 4830292d5f879..3c60d4cf9d0e1 100644 --- a/drivers/net/ethernet/amd/pds_core/core.c +++ b/drivers/net/ethernet/amd/pds_core/core.c @@ -167,8 +167,10 @@ static void pdsc_q_map(struct pdsc_queue *q, void *base, dma_addr_t base_pa) q->base = base; q->base_pa = base_pa;
- for (i = 0, cur = q->info; i < q->num_descs; i++, cur++) + for (i = 0, cur = q->info; i < q->num_descs; i++, cur++) { cur->desc = base + (i * q->desc_size); + init_completion(&cur->completion); + } }
static void pdsc_cq_map(struct pdsc_cq *cq, void *base, dma_addr_t base_pa) diff --git a/drivers/net/ethernet/amd/pds_core/core.h b/drivers/net/ethernet/amd/pds_core/core.h index 543097983bf60..ec637dc4327a5 100644 --- a/drivers/net/ethernet/amd/pds_core/core.h +++ b/drivers/net/ethernet/amd/pds_core/core.h @@ -96,7 +96,7 @@ struct pdsc_q_info { unsigned int bytes; unsigned int nbufs; struct pdsc_buf_info bufs[PDS_CORE_MAX_FRAGS]; - struct pdsc_wait_context *wc; + struct completion completion; void *dest; };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dimitri Fedrau dimitri.fedrau@liebherr.com
[ Upstream commit 961ee5aeea048aa292f28d61f3a96a48554e91af ]
Add helper which returns the tx amplitude gain defined in device tree. Modifying it can be necessary to compensate losses on the PCB and connector, so the voltages measured on the RJ45 pins are conforming.
Signed-off-by: Dimitri Fedrau dimitri.fedrau@liebherr.com Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://patch.msgid.link/20250214-dp83822-tx-swing-v5-2-02ca72620599@liebher... Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 607b310ada5e ("net: dp83822: Fix OF_MDIO config check") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/phy_device.c | 53 ++++++++++++++++++++++++------------ include/linux/phy.h | 4 +++ 2 files changed, 39 insertions(+), 18 deletions(-)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 92161af788afd..2a01887c5617e 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -3123,19 +3123,12 @@ void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause) EXPORT_SYMBOL(phy_get_pause);
#if IS_ENABLED(CONFIG_OF_MDIO) -static int phy_get_int_delay_property(struct device *dev, const char *name) +static int phy_get_u32_property(struct device *dev, const char *name, u32 *val) { - s32 int_delay; - int ret; - - ret = device_property_read_u32(dev, name, &int_delay); - if (ret) - return ret; - - return int_delay; + return device_property_read_u32(dev, name, val); } #else -static int phy_get_int_delay_property(struct device *dev, const char *name) +static int phy_get_u32_property(struct device *dev, const char *name, u32 *val) { return -EINVAL; } @@ -3160,12 +3153,12 @@ static int phy_get_int_delay_property(struct device *dev, const char *name) s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev, const int *delay_values, int size, bool is_rx) { - s32 delay; - int i; + int i, ret; + u32 delay;
if (is_rx) { - delay = phy_get_int_delay_property(dev, "rx-internal-delay-ps"); - if (delay < 0 && size == 0) { + ret = phy_get_u32_property(dev, "rx-internal-delay-ps", &delay); + if (ret < 0 && size == 0) { if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) return 1; @@ -3174,8 +3167,8 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev, }
} else { - delay = phy_get_int_delay_property(dev, "tx-internal-delay-ps"); - if (delay < 0 && size == 0) { + ret = phy_get_u32_property(dev, "tx-internal-delay-ps", &delay); + if (ret < 0 && size == 0) { if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID || phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) return 1; @@ -3184,8 +3177,8 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev, } }
- if (delay < 0) - return delay; + if (ret < 0) + return ret;
if (size == 0) return delay; @@ -3220,6 +3213,30 @@ s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev, } EXPORT_SYMBOL(phy_get_internal_delay);
+/** + * phy_get_tx_amplitude_gain - stores tx amplitude gain in @val + * @phydev: phy_device struct + * @dev: pointer to the devices device struct + * @linkmode: linkmode for which the tx amplitude gain should be retrieved + * @val: tx amplitude gain + * + * Returns: 0 on success, < 0 on failure + */ +int phy_get_tx_amplitude_gain(struct phy_device *phydev, struct device *dev, + enum ethtool_link_mode_bit_indices linkmode, + u32 *val) +{ + switch (linkmode) { + case ETHTOOL_LINK_MODE_100baseT_Full_BIT: + return phy_get_u32_property(dev, + "tx-amplitude-100base-tx-percent", + val); + default: + return -EINVAL; + } +} +EXPORT_SYMBOL_GPL(phy_get_tx_amplitude_gain); + static int phy_led_set_brightness(struct led_classdev *led_cdev, enum led_brightness value) { diff --git a/include/linux/phy.h b/include/linux/phy.h index 19f076a71f946..7c9da26145d30 100644 --- a/include/linux/phy.h +++ b/include/linux/phy.h @@ -2114,6 +2114,10 @@ void phy_get_pause(struct phy_device *phydev, bool *tx_pause, bool *rx_pause); s32 phy_get_internal_delay(struct phy_device *phydev, struct device *dev, const int *delay_values, int size, bool is_rx);
+int phy_get_tx_amplitude_gain(struct phy_device *phydev, struct device *dev, + enum ethtool_link_mode_bit_indices linkmode, + u32 *val); + void phy_resolve_pause(unsigned long *local_adv, unsigned long *partner_adv, bool *tx_pause, bool *rx_pause);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dimitri Fedrau dimitri.fedrau@liebherr.com
[ Upstream commit 4f3735e82d8a2e80ee39731832536b1e34697c71 ]
Add support for changing the transmit amplitude voltage in 100BASE-TX mode. Modifying it can be necessary to compensate losses on the PCB and connector, so the voltages measured on the RJ45 pins are conforming.
Signed-off-by: Dimitri Fedrau dimitri.fedrau@liebherr.com Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://patch.msgid.link/20250214-dp83822-tx-swing-v5-3-02ca72620599@liebher... Signed-off-by: Jakub Kicinski kuba@kernel.org Stable-dep-of: 607b310ada5e ("net: dp83822: Fix OF_MDIO config check") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/dp83822.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index 6599feca1967d..3662f3905d5ad 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -31,6 +31,7 @@ #define MII_DP83822_RCSR 0x17 #define MII_DP83822_RESET_CTRL 0x1f #define MII_DP83822_MLEDCR 0x25 +#define MII_DP83822_LDCTRL 0x403 #define MII_DP83822_LEDCFG1 0x460 #define MII_DP83822_IOCTRL1 0x462 #define MII_DP83822_IOCTRL2 0x463 @@ -123,6 +124,9 @@ #define DP83822_IOCTRL1_GPIO1_CTRL GENMASK(2, 0) #define DP83822_IOCTRL1_GPIO1_CTRL_LED_1 BIT(0)
+/* LDCTRL bits */ +#define DP83822_100BASE_TX_LINE_DRIVER_SWING GENMASK(7, 4) + /* IOCTRL2 bits */ #define DP83822_IOCTRL2_GPIO2_CLK_SRC GENMASK(6, 4) #define DP83822_IOCTRL2_GPIO2_CTRL GENMASK(2, 0) @@ -197,6 +201,7 @@ struct dp83822_private { bool set_gpio2_clk_out; u32 gpio2_clk_out; bool led_pin_enable[DP83822_MAX_LED_PINS]; + int tx_amplitude_100base_tx_index; };
static int dp83822_config_wol(struct phy_device *phydev, @@ -522,6 +527,12 @@ static int dp83822_config_init(struct phy_device *phydev) FIELD_PREP(DP83822_IOCTRL2_GPIO2_CLK_SRC, dp83822->gpio2_clk_out));
+ if (dp83822->tx_amplitude_100base_tx_index >= 0) + phy_modify_mmd(phydev, MDIO_MMD_VEND2, MII_DP83822_LDCTRL, + DP83822_100BASE_TX_LINE_DRIVER_SWING, + FIELD_PREP(DP83822_100BASE_TX_LINE_DRIVER_SWING, + dp83822->tx_amplitude_100base_tx_index)); + err = dp83822_config_init_leds(phydev); if (err) return err; @@ -720,6 +731,11 @@ static int dp83822_phy_reset(struct phy_device *phydev) }
#ifdef CONFIG_OF_MDIO +static const u32 tx_amplitude_100base_tx_gain[] = { + 80, 82, 83, 85, 87, 88, 90, 92, + 93, 95, 97, 98, 100, 102, 103, 105, +}; + static int dp83822_of_init_leds(struct phy_device *phydev) { struct device_node *node = phydev->mdio.dev.of_node; @@ -780,6 +796,8 @@ static int dp83822_of_init(struct phy_device *phydev) struct dp83822_private *dp83822 = phydev->priv; struct device *dev = &phydev->mdio.dev; const char *of_val; + int i, ret; + u32 val;
/* Signal detection for the PHY is only enabled if the FX_EN and the * SD_EN pins are strapped. Signal detection can only enabled if FX_EN @@ -815,6 +833,26 @@ static int dp83822_of_init(struct phy_device *phydev) dp83822->set_gpio2_clk_out = true; }
+ dp83822->tx_amplitude_100base_tx_index = -1; + ret = phy_get_tx_amplitude_gain(phydev, dev, + ETHTOOL_LINK_MODE_100baseT_Full_BIT, + &val); + if (!ret) { + for (i = 0; i < ARRAY_SIZE(tx_amplitude_100base_tx_gain); i++) { + if (tx_amplitude_100base_tx_gain[i] == val) { + dp83822->tx_amplitude_100base_tx_index = i; + break; + } + } + + if (dp83822->tx_amplitude_100base_tx_index < 0) { + phydev_err(phydev, + "Invalid value for tx-amplitude-100base-tx-percent property (%u)\n", + val); + return -EINVAL; + } + } + return dp83822_of_init_leds(phydev); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Schneider johannes.schneider@leica-geosystems.com
[ Upstream commit 607b310ada5ef4c738f9dffc758a62a9d309b084 ]
When CONFIG_OF_MDIO is set to be a module the code block is not compiled. Use the IS_ENABLED macro that checks for both built in as well as module.
Fixes: 5dc39fd5ef35 ("net: phy: DP83822: Add ability to advertise Fiber connection") Signed-off-by: Johannes Schneider johannes.schneider@leica-geosystems.com Reviewed-by: Maxime Chevallier maxime.chevallier@bootlin.com Link: https://patch.msgid.link/20250423044724.1284492-1-johannes.schneider@leica-g... Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/phy/dp83822.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/dp83822.c b/drivers/net/phy/dp83822.c index 3662f3905d5ad..89094aa6dbbdb 100644 --- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -730,7 +730,7 @@ static int dp83822_phy_reset(struct phy_device *phydev) return phydev->drv->config_init(phydev); }
-#ifdef CONFIG_OF_MDIO +#if IS_ENABLED(CONFIG_OF_MDIO) static const u32 tx_amplitude_100base_tx_gain[] = { 80, 82, 83, 85, 87, 88, 90, 92, 93, 95, 97, 98, 100, 102, 103, 105,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexis Lothore alexis.lothore@bootlin.com
[ Upstream commit 73fa4597bdc035437fbcd84d6be32bd39f1f2149 ]
When a PTP interrupt occurs, the driver accesses the wrong offset to learn about the number of available snapshots in the FIFO for dwmac1000: it should be accessing bits 29..25, while it is currently reading bits 19..16 (those are bits about the auxiliary triggers which have generated the timestamps). As a consequence, it does not compute correctly the number of available snapshots, and so possibly do not generate the corresponding clock events if the bogus value ends up being 0.
Fix clock events generation by reading the correct bits in the timestamp register for dwmac1000.
Fixes: 477c3e1f6363 ("net: stmmac: Introduce dwmac1000 timestamping operations") Signed-off-by: Alexis Lothoré alexis.lothore@bootlin.com Reviewed-by: Maxime Chevallier maxime.chevallier@bootlin.com Link: https://patch.msgid.link/20250423-stmmac_ts-v2-1-e2cf2bbd61b1@bootlin.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/dwmac1000.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h index 600fea8f712fd..2d5bf1de5d2e4 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h @@ -331,8 +331,8 @@ enum rtc_control {
/* PTP and timestamping registers */
-#define GMAC3_X_ATSNS GENMASK(19, 16) -#define GMAC3_X_ATSNS_SHIFT 16 +#define GMAC3_X_ATSNS GENMASK(29, 25) +#define GMAC3_X_ATSNS_SHIFT 25
#define GMAC_PTP_TCR_ATSFC BIT(24) #define GMAC_PTP_TCR_ATSEN0 BIT(25)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexis Lothoré alexis.lothore@bootlin.com
[ Upstream commit 7b7491372f8ec2d8c08da18e5d629e55f41dda89 ]
The current way of reading a timestamp snapshot in stmmac can lead to integer overflow, as the computation is done on 32 bits. The issue has been observed on a dwmac-socfpga platform returning chaotic timestamp values due to this overflow. The corresponding multiplication is done with a MUL instruction, which returns 32 bit values. Explicitly casting the value to 64 bits replaced the MUL with a UMLAL, which computes and returns the result on 64 bits, and so returns correctly the timestamps.
Prevent this overflow by explicitly casting the intermediate value to u64 to make sure that the whole computation is made on u64. While at it, apply the same cast on the other dwmac variant (GMAC4) method for snapshot retrieval.
Fixes: 477c3e1f6363 ("net: stmmac: Introduce dwmac1000 timestamping operations") Signed-off-by: Alexis Lothoré alexis.lothore@bootlin.com Reviewed-by: Maxime Chevallier maxime.chevallier@bootlin.com Link: https://patch.msgid.link/20250423-stmmac_ts-v2-2-e2cf2bbd61b1@bootlin.com Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 96bcda0856ec6..11c525b8d2698 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -560,7 +560,7 @@ void dwmac1000_get_ptptime(void __iomem *ptpaddr, u64 *ptp_time) u64 ns;
ns = readl(ptpaddr + GMAC_PTP_ATNR); - ns += readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC; + ns += (u64)readl(ptpaddr + GMAC_PTP_ATSR) * NSEC_PER_SEC;
*ptp_time = ns; } diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c index 0f59aa9826040..e2840fa241f29 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c @@ -222,7 +222,7 @@ static void get_ptptime(void __iomem *ptpaddr, u64 *ptp_time) u64 ns;
ns = readl(ptpaddr + PTP_ATNR); - ns += readl(ptpaddr + PTP_ATSR) * NSEC_PER_SEC; + ns += (u64)readl(ptpaddr + PTP_ATSR) * NSEC_PER_SEC;
*ptp_time = ns; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig hch@lst.de
[ Upstream commit 7b720c720253e2070459420b2628a7b9ee6733b3 ]
When the user increased the read-ahead size through sysfs this value currently get lost if the device is reprobe, including on a resume from suspend.
As there is no hardware limitation for the read-ahead size there is no real need to reset it or track a separate hardware limitation like for max_sectors.
This restores the pre-atomic queue limit behavior in the sd driver as sd did not use blk_queue_io_opt and thus never updated the read ahead size to the value based of the optimal I/O, but changes behavior for all other drivers. As the new behavior seems useful and sd is the driver for which the readahead size tweaks are most useful that seems like a worthwhile trade off.
Fixes: 804e498e0496 ("sd: convert to the atomic queue limits API") Reported-by: Holger Hoffstätte holger@applied-asynchrony.com Signed-off-by: Christoph Hellwig hch@lst.de Tested-by: Holger Hoffstätte holger@applied-asynchrony.com Reviewed-by: Hannes Reinecke hare@suse.de Link: https://lore.kernel.org/r/20250424082521.1967286-1-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk-settings.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/block/blk-settings.c b/block/blk-settings.c index 66721afeea546..67b119ffa1689 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -61,8 +61,14 @@ void blk_apply_bdi_limits(struct backing_dev_info *bdi, /* * For read-ahead of large files to be effective, we need to read ahead * at least twice the optimal I/O size. + * + * There is no hardware limitation for the read-ahead size and the user + * might have increased the read-ahead size through sysfs, so don't ever + * decrease it. */ - bdi->ra_pages = max(lim->io_opt * 2 / PAGE_SIZE, VM_READAHEAD_PAGES); + bdi->ra_pages = max3(bdi->ra_pages, + lim->io_opt * 2 / PAGE_SIZE, + VM_READAHEAD_PAGES); bdi->io_pages = lim->max_sectors >> PAGE_SECTORS_SHIFT; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luis Chamberlain mcgrof@kernel.org
[ Upstream commit 425fbcd62d2e1330e64d8d3bf89e554830ba997f ]
You can use lsblk to query for a block device block device block size:
lsblk -o MIN-IO /dev/nvme0n1 MIN-IO 4096
The min-io is the minimum IO the block device prefers for optimal performance. In turn we map this to the block device block size. The current block size exposed even for block devices with an LBA format of 16k is 4k. Likewise devices which support 4k LBA format but have a larger Indirection Unit of 16k have an exposed block size of 4k.
This incurs read-modify-writes on direct IO against devices with a min-io larger than the page size. To fix this, use the block device min io, which is the minimal optimal IO the device prefers.
With this we now get:
lsblk -o MIN-IO /dev/nvme0n1 MIN-IO 16384
And so userspace gets the appropriate information it needs for optimal performance. This is verified with blkalgn against mkfs against a device with LBA format of 4k but an NPWG of 16k (min io size)
mkfs.xfs -f -b size=16k /dev/nvme3n1 blkalgn -d nvme3n1 --ops Write
Block size : count distribution 0 -> 1 : 0 | | 2 -> 3 : 0 | | 4 -> 7 : 0 | | 8 -> 15 : 0 | | 16 -> 31 : 0 | | 32 -> 63 : 0 | | 64 -> 127 : 0 | | 128 -> 255 : 0 | | 256 -> 511 : 0 | | 512 -> 1023 : 0 | | 1024 -> 2047 : 0 | | 2048 -> 4095 : 0 | | 4096 -> 8191 : 0 | | 8192 -> 16383 : 0 | | 16384 -> 32767 : 66 |****************************************| 32768 -> 65535 : 0 | | 65536 -> 131071 : 0 | | 131072 -> 262143 : 2 |* | Block size: 14 - 66 Block size: 17 - 2
Algn size : count distribution 0 -> 1 : 0 | | 2 -> 3 : 0 | | 4 -> 7 : 0 | | 8 -> 15 : 0 | | 16 -> 31 : 0 | | 32 -> 63 : 0 | | 64 -> 127 : 0 | | 128 -> 255 : 0 | | 256 -> 511 : 0 | | 512 -> 1023 : 0 | | 1024 -> 2047 : 0 | | 2048 -> 4095 : 0 | | 4096 -> 8191 : 0 | | 8192 -> 16383 : 0 | | 16384 -> 32767 : 66 |****************************************| 32768 -> 65535 : 0 | | 65536 -> 131071 : 0 | | 131072 -> 262143 : 2 |* | Algn size: 14 - 66 Algn size: 17 - 2
Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Luis Chamberlain mcgrof@kernel.org Link: https://lore.kernel.org/r/20250221223823.1680616-9-mcgrof@kernel.org Reviewed-by: John Garry john.g.garry@oracle.com Signed-off-by: Christian Brauner brauner@kernel.org Stable-dep-of: 5f33b5226c9d ("block: don't autoload drivers on stat") Signed-off-by: Sasha Levin sashal@kernel.org --- block/bdev.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/block/bdev.c b/block/bdev.c index 9d73a8fbf7f99..8453f6a795d9a 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -1274,9 +1274,6 @@ void bdev_statx(struct path *path, struct kstat *stat, struct inode *backing_inode; struct block_device *bdev;
- if (!(request_mask & (STATX_DIOALIGN | STATX_WRITE_ATOMIC))) - return; - backing_inode = d_backing_inode(path->dentry);
/* @@ -1303,6 +1300,8 @@ void bdev_statx(struct path *path, struct kstat *stat, queue_atomic_write_unit_max_bytes(bd_queue)); }
+ stat->blksize = bdev_io_min(bdev); + blkdev_put_no_open(bdev); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig hch@lst.de
[ Upstream commit c63202140d4b411d27380805c4d68eb11407b7f2 ]
These are only to be used by block internal code. Remove the comment as we grew more users due to reworking block device node opening.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Christian Brauner brauner@kernel.org Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20250423053810.1683309-2-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: 5f33b5226c9d ("block: don't autoload drivers on stat") Signed-off-by: Sasha Levin sashal@kernel.org --- block/blk.h | 3 +++ include/linux/blkdev.h | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/block/blk.h b/block/blk.h index 9cf9a0099416d..c0120a3d9dc57 100644 --- a/block/blk.h +++ b/block/blk.h @@ -94,6 +94,9 @@ static inline void blk_wait_io(struct completion *done) wait_for_completion_io(done); }
+struct block_device *blkdev_get_no_open(dev_t dev); +void blkdev_put_no_open(struct block_device *bdev); + #define BIO_INLINE_VECS 4 struct bio_vec *bvec_alloc(mempool_t *pool, unsigned short *nr_vecs, gfp_t gfp_mask); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index d37751789bf58..6aa67e9b2ec08 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1649,10 +1649,6 @@ int bd_prepare_to_claim(struct block_device *bdev, void *holder, const struct blk_holder_ops *hops); void bd_abort_claiming(struct block_device *bdev, void *holder);
-/* just for blk-cgroup, don't use elsewhere */ -struct block_device *blkdev_get_no_open(dev_t dev); -void blkdev_put_no_open(struct block_device *bdev); - struct block_device *I_BDEV(struct inode *inode); struct block_device *file_bdev(struct file *bdev_file); bool disk_live(struct gendisk *disk);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig hch@lst.de
[ Upstream commit d13b7090b2510abaa83a25717466decca23e8226 ]
backing_inode is only used once, so remove it and update the comment describing the bdev lookup to be a bit more clear.
Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Christian Brauner brauner@kernel.org Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20250423053810.1683309-3-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: 5f33b5226c9d ("block: don't autoload drivers on stat") Signed-off-by: Sasha Levin sashal@kernel.org --- block/bdev.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/block/bdev.c b/block/bdev.c index 8453f6a795d9a..89235796e51a5 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -1271,18 +1271,15 @@ void sync_bdevs(bool wait) void bdev_statx(struct path *path, struct kstat *stat, u32 request_mask) { - struct inode *backing_inode; struct block_device *bdev;
- backing_inode = d_backing_inode(path->dentry); - /* - * Note that backing_inode is the inode of a block device node file, - * not the block device's internal inode. Therefore it is *not* valid - * to use I_BDEV() here; the block device has to be looked up by i_rdev + * Note that d_backing_inode() returns the block device node inode, not + * the block device's internal inode. Therefore it is *not* valid to + * use I_BDEV() here; the block device has to be looked up by i_rdev * instead. */ - bdev = blkdev_get_no_open(backing_inode->i_rdev); + bdev = blkdev_get_no_open(d_backing_inode(path->dentry)->i_rdev); if (!bdev) return;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoph Hellwig hch@lst.de
[ Upstream commit 5f33b5226c9d92359e58e91ad0bf0c1791da36a1 ]
blkdev_get_no_open can trigger the legacy autoload of block drivers. A simple stat of a block device has not historically done that, so disable this behavior again.
Fixes: 9abcfbd235f5 ("block: Add atomic write support for statx") Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Christian Brauner brauner@kernel.org Acked-by: Tejun Heo tj@kernel.org Link: https://lore.kernel.org/r/20250423053810.1683309-4-hch@lst.de Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- block/bdev.c | 8 ++++---- block/blk-cgroup.c | 2 +- block/blk.h | 2 +- block/fops.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/block/bdev.c b/block/bdev.c index 89235796e51a5..5aebcf437f17c 100644 --- a/block/bdev.c +++ b/block/bdev.c @@ -773,13 +773,13 @@ static void blkdev_put_part(struct block_device *part) blkdev_put_whole(whole); }
-struct block_device *blkdev_get_no_open(dev_t dev) +struct block_device *blkdev_get_no_open(dev_t dev, bool autoload) { struct block_device *bdev; struct inode *inode;
inode = ilookup(blockdev_superblock, dev); - if (!inode && IS_ENABLED(CONFIG_BLOCK_LEGACY_AUTOLOAD)) { + if (!inode && autoload && IS_ENABLED(CONFIG_BLOCK_LEGACY_AUTOLOAD)) { blk_request_module(dev); inode = ilookup(blockdev_superblock, dev); if (inode) @@ -1001,7 +1001,7 @@ struct file *bdev_file_open_by_dev(dev_t dev, blk_mode_t mode, void *holder, if (ret) return ERR_PTR(ret);
- bdev = blkdev_get_no_open(dev); + bdev = blkdev_get_no_open(dev, true); if (!bdev) return ERR_PTR(-ENXIO);
@@ -1279,7 +1279,7 @@ void bdev_statx(struct path *path, struct kstat *stat, * use I_BDEV() here; the block device has to be looked up by i_rdev * instead. */ - bdev = blkdev_get_no_open(d_backing_inode(path->dentry)->i_rdev); + bdev = blkdev_get_no_open(d_backing_inode(path->dentry)->i_rdev, false); if (!bdev) return;
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index 9ed93d91d754a..c94efae5bcfaf 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -796,7 +796,7 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx) return -EINVAL; input = skip_spaces(input);
- bdev = blkdev_get_no_open(MKDEV(major, minor)); + bdev = blkdev_get_no_open(MKDEV(major, minor), true); if (!bdev) return -ENODEV; if (bdev_is_partition(bdev)) { diff --git a/block/blk.h b/block/blk.h index c0120a3d9dc57..9dcc92c7f2b50 100644 --- a/block/blk.h +++ b/block/blk.h @@ -94,7 +94,7 @@ static inline void blk_wait_io(struct completion *done) wait_for_completion_io(done); }
-struct block_device *blkdev_get_no_open(dev_t dev); +struct block_device *blkdev_get_no_open(dev_t dev, bool autoload); void blkdev_put_no_open(struct block_device *bdev);
#define BIO_INLINE_VECS 4 diff --git a/block/fops.c b/block/fops.c index be9f1dbea9ce0..d23ddb2dc1138 100644 --- a/block/fops.c +++ b/block/fops.c @@ -642,7 +642,7 @@ static int blkdev_open(struct inode *inode, struct file *filp) if (ret) return ret;
- bdev = blkdev_get_no_open(inode->i_rdev); + bdev = blkdev_get_no_open(inode->i_rdev, true); if (!bdev) return -ENXIO;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson seanjc@google.com
[ Upstream commit 07172206a26dcf3f0bf7c3ecaadd4242b008ea54 ]
Return -EINVAL instead of success if amd_ir_set_vcpu_affinity() is invoked without use_vapic; lying to KVM about whether or not the IRTE was configured to post IRQs is all kinds of bad.
Fixes: d98de49a53e4 ("iommu/amd: Enable vAPIC interrupt remapping mode by default") Signed-off-by: Sean Christopherson seanjc@google.com Message-ID: 20250404193923.1413163-6-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/amd/iommu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/iommu/amd/iommu.c b/drivers/iommu/amd/iommu.c index cd5116d8c3b28..b3a01b7757ee1 100644 --- a/drivers/iommu/amd/iommu.c +++ b/drivers/iommu/amd/iommu.c @@ -3850,7 +3850,7 @@ static int amd_ir_set_vcpu_affinity(struct irq_data *data, void *vcpu_info) * we should not modify the IRTE */ if (!dev_data || !dev_data->use_vapic) - return 0; + return -EINVAL;
ir_data->cfg = irqd_cfg(data); pi_data->ir_data = ir_data;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel bjorn@rivosinc.com
[ Upstream commit 121f34341d396b666d8a90b24768b40e08ca0d61 ]
The flush_icache_range() function is implemented as a "function-like macro with unused parameters", which can result in "unused variables" warnings.
Replace the macro with a static inline function, as advised by Documentation/process/coding-style.rst.
Fixes: 08f051eda33b ("RISC-V: Flush I$ when making a dirty page executable") Signed-off-by: Björn Töpel bjorn@rivosinc.com Link: https://lore.kernel.org/r/20250419111402.1660267-1-bjorn@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/include/asm/cacheflush.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h index 8de73f91bfa37..b59ffeb668d6a 100644 --- a/arch/riscv/include/asm/cacheflush.h +++ b/arch/riscv/include/asm/cacheflush.h @@ -34,11 +34,6 @@ static inline void flush_dcache_page(struct page *page) flush_dcache_folio(page_folio(page)); }
-/* - * RISC-V doesn't have an instruction to flush parts of the instruction cache, - * so instead we just flush the whole thing. - */ -#define flush_icache_range(start, end) flush_icache_all() #define flush_icache_user_page(vma, pg, addr, len) \ do { \ if (vma->vm_flags & VM_EXEC) \ @@ -78,6 +73,16 @@ void flush_icache_mm(struct mm_struct *mm, bool local);
#endif /* CONFIG_SMP */
+/* + * RISC-V doesn't have an instruction to flush parts of the instruction cache, + * so instead we just flush the whole thing. + */ +#define flush_icache_range flush_icache_range +static inline void flush_icache_range(unsigned long start, unsigned long end) +{ + flush_icache_all(); +} + extern unsigned int riscv_cbom_block_size; extern unsigned int riscv_cboz_block_size; void riscv_init_cbo_blocksizes(void);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel bjorn@rivosinc.com
[ Upstream commit 7d1d19a11cfbfd8bae1d89cc010b2cc397cd0c48 ]
The XOL (execute out-of-line) buffer is used to single-step the replaced instruction(s) for uprobes. The RISC-V port was missing a proper fence.i (i$ flushing) after constructing the XOL buffer, which can result in incorrect execution of stale/broken instructions.
This was found running the BPF selftests "test_progs: uprobe_autoattach, attach_probe" on the Spacemit K1/X60, where the uprobes tests randomly blew up.
Reviewed-by: Guo Ren guoren@kernel.org Fixes: 74784081aac8 ("riscv: Add uprobes supported") Signed-off-by: Björn Töpel bjorn@rivosinc.com Link: https://lore.kernel.org/r/20250419111402.1660267-2-bjorn@kernel.org Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/kernel/probes/uprobes.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/arch/riscv/kernel/probes/uprobes.c b/arch/riscv/kernel/probes/uprobes.c index 4b3dc8beaf77d..cc15f7ca6cc17 100644 --- a/arch/riscv/kernel/probes/uprobes.c +++ b/arch/riscv/kernel/probes/uprobes.c @@ -167,6 +167,7 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, /* Initialize the slot */ void *kaddr = kmap_atomic(page); void *dst = kaddr + (vaddr & ~PAGE_MASK); + unsigned long start = (unsigned long)dst;
memcpy(dst, src, len);
@@ -176,13 +177,6 @@ void arch_uprobe_copy_ixol(struct page *page, unsigned long vaddr, *(uprobe_opcode_t *)dst = __BUG_INSN_32; }
+ flush_icache_range(start, start + len); kunmap_atomic(kaddr); - - /* - * We probably need flush_icache_user_page() but it needs vma. - * This should work on most of architectures by default. If - * architecture needs to do something different it can define - * its own version of the function. - */ - flush_dcache_page(page); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uday Shankar ushankar@purestorage.com
[ Upstream commit 989bcd623a8b0c32b76d9258767d8b37e53419e6 ]
The current I/O dispatch mechanism - queueing I/O by adding it to the io_cmds list (and poking task_work as needed), then dispatching it in ublk server task context by reversing io_cmds and completing the io_uring command associated to each one - was introduced by commit 7d4a93176e014 ("ublk_drv: don't forward io commands in reserve order") to ensure that the ublk server received I/O in the same order that the block layer submitted it to ublk_drv. This mechanism was only needed for the "raw" task_work submission mechanism, since the io_uring task work wrapper maintains FIFO ordering (using quite a similar mechanism in fact). The "raw" task_work submission mechanism is no longer supported in ublk_drv as of commit 29dc5d06613f2 ("ublk: kill queuing request by task_work_add"), so the explicit llist/reversal is no longer needed - it just duplicates logic already present in the underlying io_uring APIs. Remove it.
Signed-off-by: Uday Shankar ushankar@purestorage.com Reviewed-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20250318-ublk_io_cmds-v1-1-c1bb74798fef@purestorag... Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: d6aa0c178bf8 ("ublk: call ublk_dispatch_req() for handling UBLK_U_IO_NEED_GET_DATA") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 46 ++++++++++------------------------------ 1 file changed, 11 insertions(+), 35 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 971b793dedd03..f615b9bd82f5f 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -73,8 +73,6 @@ UBLK_PARAM_TYPE_DEVT | UBLK_PARAM_TYPE_ZONED)
struct ublk_rq_data { - struct llist_node node; - struct kref ref; };
@@ -141,8 +139,6 @@ struct ublk_queue { struct task_struct *ubq_daemon; char *io_cmd_buf;
- struct llist_head io_cmds; - unsigned long io_addr; /* mapped vm address */ unsigned int max_io_sz; bool force_abort; @@ -1114,7 +1110,7 @@ static void ublk_fail_rq_fn(struct kref *ref) }
/* - * Since __ublk_rq_task_work always fails requests immediately during + * Since ublk_rq_task_work_cb always fails requests immediately during * exiting, __ublk_fail_req() is only called from abort context during * exiting. So lock is unnecessary. * @@ -1163,11 +1159,14 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq, blk_mq_end_request(rq, BLK_STS_IOERR); }
-static inline void __ublk_rq_task_work(struct request *req, - unsigned issue_flags) +static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, + unsigned int issue_flags) { - struct ublk_queue *ubq = req->mq_hctx->driver_data; - int tag = req->tag; + struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); + struct ublk_queue *ubq = pdu->ubq; + int tag = pdu->tag; + struct request *req = blk_mq_tag_to_rq( + ubq->dev->tag_set.tags[ubq->q_id], tag); struct ublk_io *io = &ubq->ios[tag]; unsigned int mapped_bytes;
@@ -1242,34 +1241,11 @@ static inline void __ublk_rq_task_work(struct request *req, ubq_complete_io_cmd(io, UBLK_IO_RES_OK, issue_flags); }
-static inline void ublk_forward_io_cmds(struct ublk_queue *ubq, - unsigned issue_flags) -{ - struct llist_node *io_cmds = llist_del_all(&ubq->io_cmds); - struct ublk_rq_data *data, *tmp; - - io_cmds = llist_reverse_order(io_cmds); - llist_for_each_entry_safe(data, tmp, io_cmds, node) - __ublk_rq_task_work(blk_mq_rq_from_pdu(data), issue_flags); -} - -static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, unsigned issue_flags) -{ - struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); - struct ublk_queue *ubq = pdu->ubq; - - ublk_forward_io_cmds(ubq, issue_flags); -} - static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) { - struct ublk_rq_data *data = blk_mq_rq_to_pdu(rq); + struct ublk_io *io = &ubq->ios[rq->tag];
- if (llist_add(&data->node, &ubq->io_cmds)) { - struct ublk_io *io = &ubq->ios[rq->tag]; - - io_uring_cmd_complete_in_task(io->cmd, ublk_rq_task_work_cb); - } + io_uring_cmd_complete_in_task(io->cmd, ublk_rq_task_work_cb); }
static enum blk_eh_timer_return ublk_timeout(struct request *rq) @@ -1462,7 +1438,7 @@ static void ublk_abort_queue(struct ublk_device *ub, struct ublk_queue *ubq) struct request *rq;
/* - * Either we fail the request or ublk_rq_task_work_fn + * Either we fail the request or ublk_rq_task_work_cb * will do it */ rq = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], i);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 7e2fe01a69f6be3e284b38cfd2e4e0598a3b0a8f ]
In ublk_queue_rq(), ubq->canceling has to be handled after ->fail_io and ->force_abort are dealt with, otherwise the request may not be failed when deleting disk.
Add comment on this usage.
Signed-off-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20250327095123.179113-3-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: d6aa0c178bf8 ("ublk: call ublk_dispatch_req() for handling UBLK_U_IO_NEED_GET_DATA") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index f615b9bd82f5f..fbc397efff175 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1314,6 +1314,11 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort)) return BLK_STS_IOERR;
+ /* + * ->canceling has to be handled after ->force_abort and ->fail_io + * is dealt with, otherwise this request may not be failed in case + * of recovery, and cause hang when deleting disk + */ if (unlikely(ubq->canceling)) { __ublk_abort_rq(ubq, rq); return BLK_STS_OK;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
[ Upstream commit d796cea7b9f33b6315362f504b15fcc26d678493 ]
Implement ->queue_rqs() for improving perf in case of MQ.
In this way, we just need to call io_uring_cmd_complete_in_task() once for whole IO batch, then both io_uring and ublk server can get exact batch from ublk frontend.
Follows IOPS improvement:
- tests
tools/testing/selftests/ublk/kublk add -t null -q 2 [-z]
fio/t/io_uring -p0 /dev/ublkb0
- results:
more than 10% IOPS boost observed
Pass all ublk selftests, especially the io dispatch order test.
Cc: Uday Shankar ushankar@purestorage.com Signed-off-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20250327095123.179113-9-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: d6aa0c178bf8 ("ublk: call ublk_dispatch_req() for handling UBLK_U_IO_NEED_GET_DATA") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 131 +++++++++++++++++++++++++++++++++------ 1 file changed, 111 insertions(+), 20 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index fbc397efff175..e1388a9b1e2d1 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -77,6 +77,20 @@ struct ublk_rq_data { };
struct ublk_uring_cmd_pdu { + /* + * Store requests in same batch temporarily for queuing them to + * daemon context. + * + * It should have been stored to request payload, but we do want + * to avoid extra pre-allocation, and uring_cmd payload is always + * free for us + */ + struct request *req_list; + + /* + * The following two are valid in this cmd whole lifetime, and + * setup in ublk uring_cmd handler + */ struct ublk_queue *ubq; u16 tag; }; @@ -1159,14 +1173,12 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq, blk_mq_end_request(rq, BLK_STS_IOERR); }
-static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, - unsigned int issue_flags) +static void ublk_dispatch_req(struct ublk_queue *ubq, + struct io_uring_cmd *cmd, + struct request *req, + unsigned int issue_flags) { - struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); - struct ublk_queue *ubq = pdu->ubq; - int tag = pdu->tag; - struct request *req = blk_mq_tag_to_rq( - ubq->dev->tag_set.tags[ubq->q_id], tag); + int tag = req->tag; struct ublk_io *io = &ubq->ios[tag]; unsigned int mapped_bytes;
@@ -1241,6 +1253,18 @@ static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, ubq_complete_io_cmd(io, UBLK_IO_RES_OK, issue_flags); }
+static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, + unsigned int issue_flags) +{ + struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); + struct ublk_queue *ubq = pdu->ubq; + int tag = pdu->tag; + struct request *req = blk_mq_tag_to_rq( + ubq->dev->tag_set.tags[ubq->q_id], tag); + + ublk_dispatch_req(ubq, cmd, req, issue_flags); +} + static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) { struct ublk_io *io = &ubq->ios[rq->tag]; @@ -1248,6 +1272,35 @@ static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) io_uring_cmd_complete_in_task(io->cmd, ublk_rq_task_work_cb); }
+static void ublk_cmd_list_tw_cb(struct io_uring_cmd *cmd, + unsigned int issue_flags) +{ + struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(cmd); + struct request *rq = pdu->req_list; + struct ublk_queue *ubq = rq->mq_hctx->driver_data; + struct request *next; + + while (rq) { + struct ublk_io *io = &ubq->ios[rq->tag]; + + next = rq->rq_next; + rq->rq_next = NULL; + ublk_dispatch_req(ubq, io->cmd, rq, issue_flags); + rq = next; + } +} + +static void ublk_queue_cmd_list(struct ublk_queue *ubq, struct rq_list *l) +{ + struct request *rq = rq_list_peek(l); + struct ublk_io *io = &ubq->ios[rq->tag]; + struct ublk_uring_cmd_pdu *pdu = ublk_get_uring_cmd_pdu(io->cmd); + + pdu->req_list = rq; + rq_list_init(l); + io_uring_cmd_complete_in_task(io->cmd, ublk_cmd_list_tw_cb); +} + static enum blk_eh_timer_return ublk_timeout(struct request *rq) { struct ublk_queue *ubq = rq->mq_hctx->driver_data; @@ -1286,21 +1339,12 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq) return BLK_EH_RESET_TIMER; }
-static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, - const struct blk_mq_queue_data *bd) +static blk_status_t ublk_prep_req(struct ublk_queue *ubq, struct request *rq) { - struct ublk_queue *ubq = hctx->driver_data; - struct request *rq = bd->rq; blk_status_t res;
- if (unlikely(ubq->fail_io)) { + if (unlikely(ubq->fail_io)) return BLK_STS_TARGET; - } - - /* fill iod to slot in io cmd buffer */ - res = ublk_setup_iod(ubq, rq); - if (unlikely(res != BLK_STS_OK)) - return BLK_STS_IOERR;
/* With recovery feature enabled, force_abort is set in * ublk_stop_dev() before calling del_gendisk(). We have to @@ -1314,6 +1358,29 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort)) return BLK_STS_IOERR;
+ if (unlikely(ubq->canceling)) + return BLK_STS_IOERR; + + /* fill iod to slot in io cmd buffer */ + res = ublk_setup_iod(ubq, rq); + if (unlikely(res != BLK_STS_OK)) + return BLK_STS_IOERR; + + blk_mq_start_request(rq); + return BLK_STS_OK; +} + +static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, + const struct blk_mq_queue_data *bd) +{ + struct ublk_queue *ubq = hctx->driver_data; + struct request *rq = bd->rq; + blk_status_t res; + + res = ublk_prep_req(ubq, rq); + if (res != BLK_STS_OK) + return res; + /* * ->canceling has to be handled after ->force_abort and ->fail_io * is dealt with, otherwise this request may not be failed in case @@ -1324,12 +1391,35 @@ static blk_status_t ublk_queue_rq(struct blk_mq_hw_ctx *hctx, return BLK_STS_OK; }
- blk_mq_start_request(bd->rq); ublk_queue_cmd(ubq, rq); - return BLK_STS_OK; }
+static void ublk_queue_rqs(struct rq_list *rqlist) +{ + struct rq_list requeue_list = { }; + struct rq_list submit_list = { }; + struct ublk_queue *ubq = NULL; + struct request *req; + + while ((req = rq_list_pop(rqlist))) { + struct ublk_queue *this_q = req->mq_hctx->driver_data; + + if (ubq && ubq != this_q && !rq_list_empty(&submit_list)) + ublk_queue_cmd_list(ubq, &submit_list); + ubq = this_q; + + if (ublk_prep_req(ubq, req) == BLK_STS_OK) + rq_list_add_tail(&submit_list, req); + else + rq_list_add_tail(&requeue_list, req); + } + + if (ubq && !rq_list_empty(&submit_list)) + ublk_queue_cmd_list(ubq, &submit_list); + *rqlist = requeue_list; +} + static int ublk_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data, unsigned int hctx_idx) { @@ -1342,6 +1432,7 @@ static int ublk_init_hctx(struct blk_mq_hw_ctx *hctx, void *driver_data,
static const struct blk_mq_ops ublk_mq_ops = { .queue_rq = ublk_queue_rq, + .queue_rqs = ublk_queue_rqs, .init_hctx = ublk_init_hctx, .timeout = ublk_timeout, };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Caleb Sander Mateos csander@purestorage.com
[ Upstream commit dfbce8b798fb848a42706e2e544b78b3db22aaae ]
ublk_dispatch_req() never uses its struct io_uring_cmd *cmd argument. Drop it so callers don't have to pass a value.
Signed-off-by: Caleb Sander Mateos csander@purestorage.com Link: https://lore.kernel.org/r/20250328180411.2696494-2-csander@purestorage.com Signed-off-by: Jens Axboe axboe@kernel.dk Stable-dep-of: d6aa0c178bf8 ("ublk: call ublk_dispatch_req() for handling UBLK_U_IO_NEED_GET_DATA") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index e1388a9b1e2d1..437297022dcfa 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1174,7 +1174,6 @@ static inline void __ublk_abort_rq(struct ublk_queue *ubq, }
static void ublk_dispatch_req(struct ublk_queue *ubq, - struct io_uring_cmd *cmd, struct request *req, unsigned int issue_flags) { @@ -1262,7 +1261,7 @@ static void ublk_rq_task_work_cb(struct io_uring_cmd *cmd, struct request *req = blk_mq_tag_to_rq( ubq->dev->tag_set.tags[ubq->q_id], tag);
- ublk_dispatch_req(ubq, cmd, req, issue_flags); + ublk_dispatch_req(ubq, req, issue_flags); }
static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq) @@ -1281,11 +1280,9 @@ static void ublk_cmd_list_tw_cb(struct io_uring_cmd *cmd, struct request *next;
while (rq) { - struct ublk_io *io = &ubq->ios[rq->tag]; - next = rq->rq_next; rq->rq_next = NULL; - ublk_dispatch_req(ubq, io->cmd, rq, issue_flags); + ublk_dispatch_req(ubq, rq, issue_flags); rq = next; } }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
[ Upstream commit d6aa0c178bf81f30ae4a780b2bca653daa2eb633 ]
We call io_uring_cmd_complete_in_task() to schedule task_work for handling UBLK_U_IO_NEED_GET_DATA.
This way is really not necessary because the current context is exactly the ublk queue context, so call ublk_dispatch_req() directly for handling UBLK_U_IO_NEED_GET_DATA.
Fixes: 216c8f5ef0f2 ("ublk: replace monitor with cancelable uring_cmd") Tested-by: Jared Holzman jholzman@nvidia.com Signed-off-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20250425013742.1079549-2-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 437297022dcfa..c7761a5cfeec0 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1812,15 +1812,6 @@ static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq) mutex_unlock(&ub->mutex); }
-static void ublk_handle_need_get_data(struct ublk_device *ub, int q_id, - int tag) -{ - struct ublk_queue *ubq = ublk_get_queue(ub, q_id); - struct request *req = blk_mq_tag_to_rq(ub->tag_set.tags[q_id], tag); - - ublk_queue_cmd(ubq, req); -} - static inline int ublk_check_cmd_op(u32 cmd_op) { u32 ioc_type = _IOC_TYPE(cmd_op); @@ -1967,8 +1958,9 @@ static int __ublk_ch_uring_cmd(struct io_uring_cmd *cmd, if (!(io->flags & UBLK_IO_FLAG_OWNED_BY_SRV)) goto out; ublk_fill_io_cmd(io, cmd, ub_cmd->addr); - ublk_handle_need_get_data(ub, ub_cmd->q_id, ub_cmd->tag); - break; + req = blk_mq_tag_to_rq(ub->tag_set.tags[ub_cmd->q_id], tag); + ublk_dispatch_req(ubq, req, issue_flags); + return -EIOCBQUEUED; default: goto out; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: T.J. Mercier tjmercier@google.com
[ Upstream commit e6f141b332ddd9007756751b6afd24f799488fd8 ]
pipe_clear_nowait has two noinline macros, but we only need one.
I checked the whole tree, and this is the only occurrence:
$ grep -r "noinline .* noinline" fs/splice.c:static noinline void noinline pipe_clear_nowait(struct file *file) $
Fixes: 0f99fc513ddd ("splice: clear FMODE_NOWAIT on file if splice/vmsplice is used") Signed-off-by: "T.J. Mercier" tjmercier@google.com Link: https://lore.kernel.org/20250423180025.2627670-1-tjmercier@google.com Reviewed-by: Jens Axboe axboe@kernel.dk Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/splice.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/splice.c b/fs/splice.c index 23fa5561b9441..bd6e889133f5c 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -45,7 +45,7 @@ * here if set to avoid blocking other users of this pipe if splice is * being done on it. */ -static noinline void noinline pipe_clear_nowait(struct file *file) +static noinline void pipe_clear_nowait(struct file *file) { fmode_t fmode = READ_ONCE(file->f_mode);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara jack@suse.cz
[ Upstream commit f520bed25d17bb31c2d2d72b0a785b593a4e3179 ]
Currently, setxattrat(2) and getxattrat(2) are wrongly handling the calls of the from setxattrat(AF_FDCWD, NULL, AT_EMPTY_PATH, ...) and fail with -EBADF error instead of operating on CWD. Fix it.
Fixes: 6140be90ec70 ("fs/xattr: add *at family syscalls") Signed-off-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/20250424132246.16822-2-jack@suse.cz Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/xattr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/xattr.c b/fs/xattr.c index 02bee149ad967..fabb2a04501ee 100644 --- a/fs/xattr.c +++ b/fs/xattr.c @@ -703,7 +703,7 @@ static int path_setxattrat(int dfd, const char __user *pathname, return error;
filename = getname_maybe_null(pathname, at_flags); - if (!filename) { + if (!filename && dfd >= 0) { CLASS(fd, f)(dfd); if (fd_empty(f)) error = -EBADF; @@ -847,7 +847,7 @@ static ssize_t path_getxattrat(int dfd, const char __user *pathname, return error;
filename = getname_maybe_null(pathname, at_flags); - if (!filename) { + if (!filename && dfd >= 0) { CLASS(fd, f)(dfd); if (fd_empty(f)) return -EBADF;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Starovoitov ast@kernel.org
[ Upstream commit f88886de0927a2adf4c1b4c5c1f1d31d2023ef74 ]
Add namespace to BPF internal symbols used by light skeleton to prevent abuse and document with the code their allowed usage.
Fixes: b1d18a7574d0 ("bpf: Extend sys_bpf commands for bpf_syscall programs.") Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Kumar Kartikeya Dwivedi memxor@gmail.com Link: https://lore.kernel.org/bpf/20250425014542.62385-1-alexei.starovoitov@gmail.... Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/bpf/bpf_devel_QA.rst | 8 ++++++++ kernel/bpf/preload/bpf_preload_kern.c | 1 + kernel/bpf/syscall.c | 6 +++--- 3 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/Documentation/bpf/bpf_devel_QA.rst b/Documentation/bpf/bpf_devel_QA.rst index de27e1620821c..0acb4c9b8d90f 100644 --- a/Documentation/bpf/bpf_devel_QA.rst +++ b/Documentation/bpf/bpf_devel_QA.rst @@ -382,6 +382,14 @@ In case of new BPF instructions, once the changes have been accepted into the Linux kernel, please implement support into LLVM's BPF back end. See LLVM_ section below for further information.
+Q: What "BPF_INTERNAL" symbol namespace is for? +----------------------------------------------- +A: Symbols exported as BPF_INTERNAL can only be used by BPF infrastructure +like preload kernel modules with light skeleton. Most symbols outside +of BPF_INTERNAL are not expected to be used by code outside of BPF either. +Symbols may lack the designation because they predate the namespaces, +or due to an oversight. + Stable submission =================
diff --git a/kernel/bpf/preload/bpf_preload_kern.c b/kernel/bpf/preload/bpf_preload_kern.c index 0c63bc2cd895a..56a81df7a9d7c 100644 --- a/kernel/bpf/preload/bpf_preload_kern.c +++ b/kernel/bpf/preload/bpf_preload_kern.c @@ -89,4 +89,5 @@ static void __exit fini(void) } late_initcall(load); module_exit(fini); +MODULE_IMPORT_NS("BPF_INTERNAL"); MODULE_LICENSE("GPL"); diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index e1e42e918ba7f..1c2caae0d8946 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -1562,7 +1562,7 @@ struct bpf_map *bpf_map_get(u32 ufd)
return map; } -EXPORT_SYMBOL(bpf_map_get); +EXPORT_SYMBOL_NS(bpf_map_get, "BPF_INTERNAL");
struct bpf_map *bpf_map_get_with_uref(u32 ufd) { @@ -3345,7 +3345,7 @@ struct bpf_link *bpf_link_get_from_fd(u32 ufd) bpf_link_inc(link); return link; } -EXPORT_SYMBOL(bpf_link_get_from_fd); +EXPORT_SYMBOL_NS(bpf_link_get_from_fd, "BPF_INTERNAL");
static void bpf_tracing_link_release(struct bpf_link *link) { @@ -5981,7 +5981,7 @@ int kern_sys_bpf(int cmd, union bpf_attr *attr, unsigned int size) return ____bpf_sys_bpf(cmd, attr, size); } } -EXPORT_SYMBOL(kern_sys_bpf); +EXPORT_SYMBOL_NS(kern_sys_bpf, "BPF_INTERNAL");
static const struct bpf_func_proto bpf_sys_bpf_proto = { .func = bpf_sys_bpf,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Hewitt christianshewitt@gmail.com
[ Upstream commit f37bb5486ea536c1d61df89feeaeff3f84f0b560 ]
This reverts commit bfbc68e.
The patch does permit the offending YUV420 @ 59.94 phy_freq and vclk_freq mode to match in calculations. It also results in all fractional rates being unavailable for use. This was unintended and requires the patch to be reverted.
Fixes: bfbc68e4d869 ("drm/meson: vclk: fix calculation of 59.94 fractional rates") Cc: stable@vger.kernel.org Signed-off-by: Christian Hewitt christianshewitt@gmail.com Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250421201300.778955-2-martin.blumenstingl@google... Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250421201300.778955-2-martin.blumenstingl@google... Stable-dep-of: 1017560164b6 ("drm/meson: use unsigned long long / Hz for frequency types") Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/meson/meson_vclk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index 2a942dc6a6dc2..2a82119eb58ed 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -790,13 +790,13 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, FREQ_1000_1001(params[i].pixel_freq)); DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n", i, params[i].phy_freq, - FREQ_1000_1001(params[i].phy_freq/1000)*1000); + FREQ_1000_1001(params[i].phy_freq/10)*10); /* Match strict frequency */ if (phy_freq == params[i].phy_freq && vclk_freq == params[i].vclk_freq) return MODE_OK; /* Match 1000/1001 variant */ - if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/1000)*1000) && + if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) && vclk_freq == FREQ_1000_1001(params[i].vclk_freq)) return MODE_OK; } @@ -1070,7 +1070,7 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target,
for (freq = 0 ; params[freq].pixel_freq ; ++freq) { if ((phy_freq == params[freq].phy_freq || - phy_freq == FREQ_1000_1001(params[freq].phy_freq/1000)*1000) && + phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) && (vclk_freq == params[freq].vclk_freq || vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) { if (vclk_freq != params[freq].vclk_freq)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin Blumenstingl martin.blumenstingl@googlemail.com
[ Upstream commit 1017560164b6bbcbc93579266926e6e96675262a ]
Christian reports that 4K output using YUV420 encoding fails with the following error: Fatal Error, invalid HDMI vclk freq 593406
Modetest shows the following: 3840x2160 59.94 3840 4016 4104 4400 2160 2168 2178 2250 593407 flags: xxxx, xxxx, drm calculated value -------------------------------------^
This indicates that there's a (1kHz) mismatch between the clock calculated by the drm framework and the meson driver.
Relevant function call stack: (drm framework) -> meson_encoder_hdmi_atomic_enable() -> meson_encoder_hdmi_set_vclk() -> meson_vclk_setup()
The video clock requested by the drm framework is 593407kHz. This is passed by meson_encoder_hdmi_atomic_enable() to meson_encoder_hdmi_set_vclk() and the following formula is applied: - the frequency is halved (which would be 296703.5kHz) and rounded down to the next full integer, which is 296703kHz - TMDS clock is calculated (296703kHz * 10) - video encoder clock is calculated - this needs to match a table from meson_vclk.c and so it doubles the previously halved value again (resulting in 593406kHz) - meson_vclk_setup() can't find (either directly, or by deriving it from 594000kHz * 1000 / 1001 and rounding to the closest integer value - which is 593407kHz as originally requested by the drm framework) a matching clock in it's internal table and errors out with "invalid HDMI vclk freq"
Fix the division precision by switching the whole meson driver to use unsigned long long (64-bit) Hz values for clock frequencies instead of unsigned int (32-bit) kHz to fix the rouding error.
Fixes: e5fab2ec9ca4 ("drm/meson: vclk: add support for YUV420 setup") Reported-by: Christian Hewitt christianshewitt@gmail.com Signed-off-by: Martin Blumenstingl martin.blumenstingl@googlemail.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250421201300.778955-3-martin.blumenstingl@google... Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250421201300.778955-3-martin.blumenstingl@google... Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/meson/meson_drv.c | 2 +- drivers/gpu/drm/meson/meson_drv.h | 2 +- drivers/gpu/drm/meson/meson_encoder_hdmi.c | 29 +-- drivers/gpu/drm/meson/meson_vclk.c | 195 +++++++++++---------- drivers/gpu/drm/meson/meson_vclk.h | 13 +- 5 files changed, 126 insertions(+), 115 deletions(-)
diff --git a/drivers/gpu/drm/meson/meson_drv.c b/drivers/gpu/drm/meson/meson_drv.c index 81d2ee37e7732..49ff9f1f16d32 100644 --- a/drivers/gpu/drm/meson/meson_drv.c +++ b/drivers/gpu/drm/meson/meson_drv.c @@ -169,7 +169,7 @@ static const struct meson_drm_soc_attr meson_drm_soc_attrs[] = { /* S805X/S805Y HDMI PLL won't lock for HDMI PHY freq > 1,65GHz */ { .limits = { - .max_hdmi_phy_freq = 1650000, + .max_hdmi_phy_freq = 1650000000, }, .attrs = (const struct soc_device_attribute []) { { .soc_id = "GXL (S805*)", }, diff --git a/drivers/gpu/drm/meson/meson_drv.h b/drivers/gpu/drm/meson/meson_drv.h index 3f9345c14f31c..be4b0e4df6e13 100644 --- a/drivers/gpu/drm/meson/meson_drv.h +++ b/drivers/gpu/drm/meson/meson_drv.h @@ -37,7 +37,7 @@ struct meson_drm_match_data { };
struct meson_drm_soc_limits { - unsigned int max_hdmi_phy_freq; + unsigned long long max_hdmi_phy_freq; };
struct meson_drm { diff --git a/drivers/gpu/drm/meson/meson_encoder_hdmi.c b/drivers/gpu/drm/meson/meson_encoder_hdmi.c index 0593a1cde906f..ce8cea5d3a56b 100644 --- a/drivers/gpu/drm/meson/meson_encoder_hdmi.c +++ b/drivers/gpu/drm/meson/meson_encoder_hdmi.c @@ -70,12 +70,12 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, { struct meson_drm *priv = encoder_hdmi->priv; int vic = drm_match_cea_mode(mode); - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int hdmi_freq; + unsigned long long phy_freq; + unsigned long long vclk_freq; + unsigned long long venc_freq; + unsigned long long hdmi_freq;
- vclk_freq = mode->clock; + vclk_freq = mode->clock * 1000;
/* For 420, pixel clock is half unlike venc clock */ if (encoder_hdmi->output_bus_fmt == MEDIA_BUS_FMT_UYYVYY8_0_5X24) @@ -107,7 +107,8 @@ static void meson_encoder_hdmi_set_vclk(struct meson_encoder_hdmi *encoder_hdmi, if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2;
- dev_dbg(priv->dev, "vclk:%d phy=%d venc=%d hdmi=%d enci=%d\n", + dev_dbg(priv->dev, + "vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz enci=%d\n", phy_freq, vclk_freq, venc_freq, hdmi_freq, priv->venc.hdmi_use_enci);
@@ -122,10 +123,11 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri struct meson_encoder_hdmi *encoder_hdmi = bridge_to_meson_encoder_hdmi(bridge); struct meson_drm *priv = encoder_hdmi->priv; bool is_hdmi2_sink = display_info->hdmi.scdc.supported; - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int hdmi_freq; + unsigned long long clock = mode->clock * 1000; + unsigned long long phy_freq; + unsigned long long vclk_freq; + unsigned long long venc_freq; + unsigned long long hdmi_freq; int vic = drm_match_cea_mode(mode); enum drm_mode_status status;
@@ -144,12 +146,12 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri if (status != MODE_OK) return status;
- return meson_vclk_dmt_supported_freq(priv, mode->clock); + return meson_vclk_dmt_supported_freq(priv, clock); /* Check against supported VIC modes */ } else if (!meson_venc_hdmi_supported_vic(vic)) return MODE_BAD;
- vclk_freq = mode->clock; + vclk_freq = clock;
/* For 420, pixel clock is half unlike venc clock */ if (drm_mode_is_420_only(display_info, mode) || @@ -179,7 +181,8 @@ static enum drm_mode_status meson_encoder_hdmi_mode_valid(struct drm_bridge *bri if (mode->flags & DRM_MODE_FLAG_DBLCLK) venc_freq /= 2;
- dev_dbg(priv->dev, "%s: vclk:%d phy=%d venc=%d hdmi=%d\n", + dev_dbg(priv->dev, + "%s: vclk:%lluHz phy=%lluHz venc=%lluHz hdmi=%lluHz\n", __func__, phy_freq, vclk_freq, venc_freq, hdmi_freq);
return meson_vclk_vic_supported_freq(priv, phy_freq, vclk_freq); diff --git a/drivers/gpu/drm/meson/meson_vclk.c b/drivers/gpu/drm/meson/meson_vclk.c index 2a82119eb58ed..3325580d885d0 100644 --- a/drivers/gpu/drm/meson/meson_vclk.c +++ b/drivers/gpu/drm/meson/meson_vclk.c @@ -110,7 +110,10 @@ #define HDMI_PLL_LOCK BIT(31) #define HDMI_PLL_LOCK_G12A (3 << 30)
-#define FREQ_1000_1001(_freq) DIV_ROUND_CLOSEST(_freq * 1000, 1001) +#define PIXEL_FREQ_1000_1001(_freq) \ + DIV_ROUND_CLOSEST_ULL((_freq) * 1000ULL, 1001ULL) +#define PHY_FREQ_1000_1001(_freq) \ + (PIXEL_FREQ_1000_1001(DIV_ROUND_DOWN_ULL(_freq, 10ULL)) * 10)
/* VID PLL Dividers */ enum { @@ -360,11 +363,11 @@ enum { };
struct meson_vclk_params { - unsigned int pll_freq; - unsigned int phy_freq; - unsigned int vclk_freq; - unsigned int venc_freq; - unsigned int pixel_freq; + unsigned long long pll_freq; + unsigned long long phy_freq; + unsigned long long vclk_freq; + unsigned long long venc_freq; + unsigned long long pixel_freq; unsigned int pll_od1; unsigned int pll_od2; unsigned int pll_od3; @@ -372,11 +375,11 @@ struct meson_vclk_params { unsigned int vclk_div; } params[] = { [MESON_VCLK_HDMI_ENCI_54000] = { - .pll_freq = 4320000, - .phy_freq = 270000, - .vclk_freq = 54000, - .venc_freq = 54000, - .pixel_freq = 54000, + .pll_freq = 4320000000, + .phy_freq = 270000000, + .vclk_freq = 54000000, + .venc_freq = 54000000, + .pixel_freq = 54000000, .pll_od1 = 4, .pll_od2 = 4, .pll_od3 = 1, @@ -384,11 +387,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_DDR_54000] = { - .pll_freq = 4320000, - .phy_freq = 270000, - .vclk_freq = 54000, - .venc_freq = 54000, - .pixel_freq = 27000, + .pll_freq = 4320000000, + .phy_freq = 270000000, + .vclk_freq = 54000000, + .venc_freq = 54000000, + .pixel_freq = 27000000, .pll_od1 = 4, .pll_od2 = 4, .pll_od3 = 1, @@ -396,11 +399,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_DDR_148500] = { - .pll_freq = 2970000, - .phy_freq = 742500, - .vclk_freq = 148500, - .venc_freq = 148500, - .pixel_freq = 74250, + .pll_freq = 2970000000, + .phy_freq = 742500000, + .vclk_freq = 148500000, + .venc_freq = 148500000, + .pixel_freq = 74250000, .pll_od1 = 4, .pll_od2 = 1, .pll_od3 = 1, @@ -408,11 +411,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_74250] = { - .pll_freq = 2970000, - .phy_freq = 742500, - .vclk_freq = 74250, - .venc_freq = 74250, - .pixel_freq = 74250, + .pll_freq = 2970000000, + .phy_freq = 742500000, + .vclk_freq = 74250000, + .venc_freq = 74250000, + .pixel_freq = 74250000, .pll_od1 = 2, .pll_od2 = 2, .pll_od3 = 2, @@ -420,11 +423,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_148500] = { - .pll_freq = 2970000, - .phy_freq = 1485000, - .vclk_freq = 148500, - .venc_freq = 148500, - .pixel_freq = 148500, + .pll_freq = 2970000000, + .phy_freq = 1485000000, + .vclk_freq = 148500000, + .venc_freq = 148500000, + .pixel_freq = 148500000, .pll_od1 = 1, .pll_od2 = 2, .pll_od3 = 2, @@ -432,11 +435,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_297000] = { - .pll_freq = 5940000, - .phy_freq = 2970000, - .venc_freq = 297000, - .vclk_freq = 297000, - .pixel_freq = 297000, + .pll_freq = 5940000000, + .phy_freq = 2970000000, + .venc_freq = 297000000, + .vclk_freq = 297000000, + .pixel_freq = 297000000, .pll_od1 = 2, .pll_od2 = 1, .pll_od3 = 1, @@ -444,11 +447,11 @@ struct meson_vclk_params { .vclk_div = 2, }, [MESON_VCLK_HDMI_594000] = { - .pll_freq = 5940000, - .phy_freq = 5940000, - .venc_freq = 594000, - .vclk_freq = 594000, - .pixel_freq = 594000, + .pll_freq = 5940000000, + .phy_freq = 5940000000, + .venc_freq = 594000000, + .vclk_freq = 594000000, + .pixel_freq = 594000000, .pll_od1 = 1, .pll_od2 = 1, .pll_od3 = 2, @@ -456,11 +459,11 @@ struct meson_vclk_params { .vclk_div = 1, }, [MESON_VCLK_HDMI_594000_YUV420] = { - .pll_freq = 5940000, - .phy_freq = 2970000, - .venc_freq = 594000, - .vclk_freq = 594000, - .pixel_freq = 297000, + .pll_freq = 5940000000, + .phy_freq = 2970000000, + .venc_freq = 594000000, + .vclk_freq = 594000000, + .pixel_freq = 297000000, .pll_od1 = 2, .pll_od2 = 1, .pll_od3 = 1, @@ -617,16 +620,16 @@ static void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m, 3 << 20, pll_od_to_reg(od3) << 20); }
-#define XTAL_FREQ 24000 +#define XTAL_FREQ (24 * 1000 * 1000)
static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv, - unsigned int pll_freq) + unsigned long long pll_freq) { /* The GXBB PLL has a /2 pre-multiplier */ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) - pll_freq /= 2; + pll_freq = DIV_ROUND_DOWN_ULL(pll_freq, 2);
- return pll_freq / XTAL_FREQ; + return DIV_ROUND_DOWN_ULL(pll_freq, XTAL_FREQ); }
#define HDMI_FRAC_MAX_GXBB 4096 @@ -635,12 +638,13 @@ static unsigned int meson_hdmi_pll_get_m(struct meson_drm *priv,
static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, unsigned int m, - unsigned int pll_freq) + unsigned long long pll_freq) { - unsigned int parent_freq = XTAL_FREQ; + unsigned long long parent_freq = XTAL_FREQ; unsigned int frac_max = HDMI_FRAC_MAX_GXL; unsigned int frac_m; unsigned int frac; + u32 remainder;
/* The GXBB PLL has a /2 pre-multiplier and a larger FRAC width */ if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { @@ -652,11 +656,11 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, frac_max = HDMI_FRAC_MAX_G12A;
/* We can have a perfect match !*/ - if (pll_freq / m == parent_freq && - pll_freq % m == 0) + if (div_u64_rem(pll_freq, m, &remainder) == parent_freq && + remainder == 0) return 0;
- frac = div_u64((u64)pll_freq * (u64)frac_max, parent_freq); + frac = mul_u64_u64_div_u64(pll_freq, frac_max, parent_freq); frac_m = m * frac_max; if (frac_m > frac) return frac_max; @@ -666,7 +670,7 @@ static unsigned int meson_hdmi_pll_get_frac(struct meson_drm *priv, }
static bool meson_hdmi_pll_validate_params(struct meson_drm *priv, - unsigned int m, + unsigned long long m, unsigned int frac) { if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { @@ -694,7 +698,7 @@ static bool meson_hdmi_pll_validate_params(struct meson_drm *priv, }
static bool meson_hdmi_pll_find_params(struct meson_drm *priv, - unsigned int freq, + unsigned long long freq, unsigned int *m, unsigned int *frac, unsigned int *od) @@ -706,7 +710,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv, continue; *frac = meson_hdmi_pll_get_frac(priv, *m, freq * *od);
- DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d\n", + DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d\n", freq, *m, *frac, *od);
if (meson_hdmi_pll_validate_params(priv, *m, *frac)) @@ -718,7 +722,7 @@ static bool meson_hdmi_pll_find_params(struct meson_drm *priv,
/* pll_freq is the frequency after the OD dividers */ enum drm_mode_status -meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq) +meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq) { unsigned int od, m, frac;
@@ -741,7 +745,7 @@ EXPORT_SYMBOL_GPL(meson_vclk_dmt_supported_freq);
/* pll_freq is the frequency after the OD dividers */ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, - unsigned int pll_freq) + unsigned long long pll_freq) { unsigned int od, m, frac, od1, od2, od3;
@@ -756,7 +760,7 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, od1 = od / od2; }
- DRM_DEBUG_DRIVER("PLL params for %dkHz: m=%x frac=%x od=%d/%d/%d\n", + DRM_DEBUG_DRIVER("PLL params for %lluHz: m=%x frac=%x od=%d/%d/%d\n", pll_freq, m, frac, od1, od2, od3);
meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); @@ -764,17 +768,18 @@ static void meson_hdmi_pll_generic_set(struct meson_drm *priv, return; }
- DRM_ERROR("Fatal, unable to find parameters for PLL freq %d\n", + DRM_ERROR("Fatal, unable to find parameters for PLL freq %lluHz\n", pll_freq); }
enum drm_mode_status -meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, - unsigned int vclk_freq) +meson_vclk_vic_supported_freq(struct meson_drm *priv, + unsigned long long phy_freq, + unsigned long long vclk_freq) { int i;
- DRM_DEBUG_DRIVER("phy_freq = %d vclk_freq = %d\n", + DRM_DEBUG_DRIVER("phy_freq = %lluHz vclk_freq = %lluHz\n", phy_freq, vclk_freq);
/* Check against soc revision/package limits */ @@ -785,19 +790,19 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, }
for (i = 0 ; params[i].pixel_freq ; ++i) { - DRM_DEBUG_DRIVER("i = %d pixel_freq = %d alt = %d\n", + DRM_DEBUG_DRIVER("i = %d pixel_freq = %lluHz alt = %lluHz\n", i, params[i].pixel_freq, - FREQ_1000_1001(params[i].pixel_freq)); - DRM_DEBUG_DRIVER("i = %d phy_freq = %d alt = %d\n", + PIXEL_FREQ_1000_1001(params[i].pixel_freq)); + DRM_DEBUG_DRIVER("i = %d phy_freq = %lluHz alt = %lluHz\n", i, params[i].phy_freq, - FREQ_1000_1001(params[i].phy_freq/10)*10); + PHY_FREQ_1000_1001(params[i].phy_freq)); /* Match strict frequency */ if (phy_freq == params[i].phy_freq && vclk_freq == params[i].vclk_freq) return MODE_OK; /* Match 1000/1001 variant */ - if (phy_freq == (FREQ_1000_1001(params[i].phy_freq/10)*10) && - vclk_freq == FREQ_1000_1001(params[i].vclk_freq)) + if (phy_freq == PHY_FREQ_1000_1001(params[i].phy_freq) && + vclk_freq == PIXEL_FREQ_1000_1001(params[i].vclk_freq)) return MODE_OK; }
@@ -805,8 +810,9 @@ meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, } EXPORT_SYMBOL_GPL(meson_vclk_vic_supported_freq);
-static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, - unsigned int od1, unsigned int od2, unsigned int od3, +static void meson_vclk_set(struct meson_drm *priv, + unsigned long long pll_base_freq, unsigned int od1, + unsigned int od2, unsigned int od3, unsigned int vid_pll_div, unsigned int vclk_div, unsigned int hdmi_tx_div, unsigned int venc_div, bool hdmi_use_enci, bool vic_alternate_clock) @@ -826,15 +832,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, meson_hdmi_pll_generic_set(priv, pll_base_freq); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXBB)) { switch (pll_base_freq) { - case 2970000: + case 2970000000: m = 0x3d; frac = vic_alternate_clock ? 0xd02 : 0xe00; break; - case 4320000: + case 4320000000: m = vic_alternate_clock ? 0x59 : 0x5a; frac = vic_alternate_clock ? 0xe8f : 0; break; - case 5940000: + case 5940000000: m = 0x7b; frac = vic_alternate_clock ? 0xa05 : 0xc00; break; @@ -844,15 +850,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXM) || meson_vpu_is_compatible(priv, VPU_COMPATIBLE_GXL)) { switch (pll_base_freq) { - case 2970000: + case 2970000000: m = 0x7b; frac = vic_alternate_clock ? 0x281 : 0x300; break; - case 4320000: + case 4320000000: m = vic_alternate_clock ? 0xb3 : 0xb4; frac = vic_alternate_clock ? 0x347 : 0; break; - case 5940000: + case 5940000000: m = 0xf7; frac = vic_alternate_clock ? 0x102 : 0x200; break; @@ -861,15 +867,15 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, meson_hdmi_pll_set_params(priv, m, frac, od1, od2, od3); } else if (meson_vpu_is_compatible(priv, VPU_COMPATIBLE_G12A)) { switch (pll_base_freq) { - case 2970000: + case 2970000000: m = 0x7b; frac = vic_alternate_clock ? 0x140b4 : 0x18000; break; - case 4320000: + case 4320000000: m = vic_alternate_clock ? 0xb3 : 0xb4; frac = vic_alternate_clock ? 0x1a3ee : 0; break; - case 5940000: + case 5940000000: m = 0xf7; frac = vic_alternate_clock ? 0x8148 : 0x10000; break; @@ -1025,14 +1031,14 @@ static void meson_vclk_set(struct meson_drm *priv, unsigned int pll_base_freq, }
void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int phy_freq, unsigned int vclk_freq, - unsigned int venc_freq, unsigned int dac_freq, + unsigned long long phy_freq, unsigned long long vclk_freq, + unsigned long long venc_freq, unsigned long long dac_freq, bool hdmi_use_enci) { bool vic_alternate_clock = false; - unsigned int freq; - unsigned int hdmi_tx_div; - unsigned int venc_div; + unsigned long long freq; + unsigned long long hdmi_tx_div; + unsigned long long venc_div;
if (target == MESON_VCLK_TARGET_CVBS) { meson_venci_cvbs_clock_config(priv); @@ -1052,27 +1058,27 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, return; }
- hdmi_tx_div = vclk_freq / dac_freq; + hdmi_tx_div = DIV_ROUND_DOWN_ULL(vclk_freq, dac_freq);
if (hdmi_tx_div == 0) { - pr_err("Fatal Error, invalid HDMI-TX freq %d\n", + pr_err("Fatal Error, invalid HDMI-TX freq %lluHz\n", dac_freq); return; }
- venc_div = vclk_freq / venc_freq; + venc_div = DIV_ROUND_DOWN_ULL(vclk_freq, venc_freq);
if (venc_div == 0) { - pr_err("Fatal Error, invalid HDMI venc freq %d\n", + pr_err("Fatal Error, invalid HDMI venc freq %lluHz\n", venc_freq); return; }
for (freq = 0 ; params[freq].pixel_freq ; ++freq) { if ((phy_freq == params[freq].phy_freq || - phy_freq == FREQ_1000_1001(params[freq].phy_freq/10)*10) && + phy_freq == PHY_FREQ_1000_1001(params[freq].phy_freq)) && (vclk_freq == params[freq].vclk_freq || - vclk_freq == FREQ_1000_1001(params[freq].vclk_freq))) { + vclk_freq == PIXEL_FREQ_1000_1001(params[freq].vclk_freq))) { if (vclk_freq != params[freq].vclk_freq) vic_alternate_clock = true; else @@ -1098,7 +1104,8 @@ void meson_vclk_setup(struct meson_drm *priv, unsigned int target, }
if (!params[freq].pixel_freq) { - pr_err("Fatal Error, invalid HDMI vclk freq %d\n", vclk_freq); + pr_err("Fatal Error, invalid HDMI vclk freq %lluHz\n", + vclk_freq); return; }
diff --git a/drivers/gpu/drm/meson/meson_vclk.h b/drivers/gpu/drm/meson/meson_vclk.h index 60617aaf18dd1..7ac55744e5749 100644 --- a/drivers/gpu/drm/meson/meson_vclk.h +++ b/drivers/gpu/drm/meson/meson_vclk.h @@ -20,17 +20,18 @@ enum { };
/* 27MHz is the CVBS Pixel Clock */ -#define MESON_VCLK_CVBS 27000 +#define MESON_VCLK_CVBS (27 * 1000 * 1000)
enum drm_mode_status -meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned int freq); +meson_vclk_dmt_supported_freq(struct meson_drm *priv, unsigned long long freq); enum drm_mode_status -meson_vclk_vic_supported_freq(struct meson_drm *priv, unsigned int phy_freq, - unsigned int vclk_freq); +meson_vclk_vic_supported_freq(struct meson_drm *priv, + unsigned long long phy_freq, + unsigned long long vclk_freq);
void meson_vclk_setup(struct meson_drm *priv, unsigned int target, - unsigned int phy_freq, unsigned int vclk_freq, - unsigned int venc_freq, unsigned int dac_freq, + unsigned long long phy_freq, unsigned long long vclk_freq, + unsigned long long venc_freq, unsigned long long dac_freq, bool hdmi_use_enci);
#endif /* __MESON_VCLK_H */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luo Gengkun luogengkun@huaweicloud.com
[ Upstream commit 1a97fea9db9e9b9c4839d4232dde9f505ff5b4cc ]
Perf doesn't work at perf stat for hardware events on certain x86 platforms:
$perf stat -- sleep 1 Performance counter stats for 'sleep 1': 16.44 msec task-clock # 0.016 CPUs utilized 2 context-switches # 121.691 /sec 0 cpu-migrations # 0.000 /sec 54 page-faults # 3.286 K/sec <not supported> cycles <not supported> instructions <not supported> branches <not supported> branch-misses
The reason is that the check in x86_pmu_hw_config() for sampling events is unexpectedly applied to counting events as well.
It should only impact x86 platforms with limit_period used for non-PEBS events. For Intel platforms, it should only impact some older platforms, e.g., HSW, BDW and NHM.
Fixes: 88ec7eedbbd2 ("perf/x86: Fix low freqency setting issue") Signed-off-by: Luo Gengkun luogengkun@huaweicloud.com Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Kan Liang kan.liang@linux.intel.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Cc: Arnaldo Carvalho de Melo acme@redhat.com Cc: Jiri Olsa jolsa@redhat.com Cc: Mark Rutland mark.rutland@arm.com Cc: Namhyung Kim namhyung@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Ravi Bangoria ravi.bangoria@amd.com Link: https://lore.kernel.org/r/20250423064724.3716211-1-luogengkun@huaweicloud.co... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c index 3a27c50080f4f..ce8d4fdf54fbb 100644 --- a/arch/x86/events/core.c +++ b/arch/x86/events/core.c @@ -628,7 +628,7 @@ int x86_pmu_hw_config(struct perf_event *event) if (event->attr.type == event->pmu->type) event->hw.config |= x86_pmu_get_event_config(event);
- if (!event->attr.freq && x86_pmu.limit_period) { + if (is_sampling_event(event) && !event->attr.freq && x86_pmu.limit_period) { s64 left = event->attr.sample_period; x86_pmu.limit_period(event, &left); if (left > event->attr.sample_period)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuli Wang wangyuli@uniontech.com
[ Upstream commit fb8e9f59d6f292c3d9fea6c155c22ea5fc3053ab ]
As of commit dce44566192e ("mm/memtest: add ARCH_USE_MEMTEST"), architectures must select ARCH_USE_MEMTESET to enable CONFIG_MEMTEST.
Commit 628c3bb40e9a ("LoongArch: Add boot and setup routines") added support for early_memtest but did not select ARCH_USE_MEMTESET.
Fixes: 628c3bb40e9a ("LoongArch: Add boot and setup routines") Tested-by: Erpeng Xu xuerpeng@uniontech.com Tested-by: Yuli Wang wangyuli@uniontech.com Signed-off-by: Yuli Wang wangyuli@uniontech.com Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Sasha Levin sashal@kernel.org --- arch/loongarch/Kconfig | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index bdb989c49c094..b744bd73f08ee 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -71,6 +71,7 @@ config LOONGARCH select ARCH_SUPPORTS_RT select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF + select ARCH_USE_MEMTEST select ARCH_USE_QUEUED_RWLOCKS select ARCH_USE_QUEUED_SPINLOCKS select ARCH_WANT_DEFAULT_BPF_JIT
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit bb0511d59db9b3e40c8d51f0d151ccd0fd44071d ]
In the current code, the definition of regs_irqs_disabled() is actually "!(regs->csr_prmd & CSR_CRMD_IE)" because arch_irqs_disabled_flags() is defined as "!(flags & CSR_CRMD_IE)", it looks a little strange.
Define regs_irqs_disabled() as !(regs->csr_prmd & CSR_PRMD_PIE) directly to make it more clear, no functional change.
While at it, the return value of regs_irqs_disabled() is true or false, so change its type to reflect that and also make it always inline.
Fixes: 803b0fc5c3f2 ("LoongArch: Add process management") Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Sasha Levin sashal@kernel.org --- arch/loongarch/include/asm/ptrace.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h index f3ddaed9ef7f0..a5b63c84f8541 100644 --- a/arch/loongarch/include/asm/ptrace.h +++ b/arch/loongarch/include/asm/ptrace.h @@ -33,9 +33,9 @@ struct pt_regs { unsigned long __last[]; } __aligned(8);
-static inline int regs_irqs_disabled(struct pt_regs *regs) +static __always_inline bool regs_irqs_disabled(struct pt_regs *regs) { - return arch_irqs_disabled_flags(regs->csr_prmd); + return !(regs->csr_prmd & CSR_PRMD_PIE); }
static inline unsigned long kernel_stack_pointer(struct pt_regs *regs)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang yangtiezhu@loongson.cn
[ Upstream commit cc73cc6bcdb5f959670e3ff9abdc62461452ddff ]
Currently, interrupts need to be disabled before single-step mode is set, it requires that CSR_PRMD_PIE be cleared in save_local_irqflag() which is called by setup_singlestep(), this is reasonable.
But in the first kprobe breakpoint exception, if the irq is enabled at the beginning of do_bp(), it will not be disabled at the end of do_bp() due to the CSR_PRMD_PIE has been cleared in save_local_irqflag(). So for this case, it may corrupt exception context when restoring the exception after do_bp() in handle_bp(), this is not reasonable.
In order to restore exception safely in handle_bp(), it needs to ensure the irq is disabled at the end of do_bp(), so just add a local variable to record the original interrupt status in the parent context, then use it as the check condition to enable and disable irq in do_bp().
While at it, do the similar thing for other do_xyz() exception handlers to make them more robust.
Fixes: 6d4cc40fb5f5 ("LoongArch: Add kprobes support") Suggested-by: Jinyang He hejinyang@loongson.cn Suggested-by: Huacai Chen chenhuacai@loongson.cn Co-developed-by: Tianyang Zhang zhangtianyang@loongson.cn Signed-off-by: Tianyang Zhang zhangtianyang@loongson.cn Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Sasha Levin sashal@kernel.org --- arch/loongarch/kernel/traps.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/arch/loongarch/kernel/traps.c b/arch/loongarch/kernel/traps.c index 2ec3106c0da3d..47fc2de6d1501 100644 --- a/arch/loongarch/kernel/traps.c +++ b/arch/loongarch/kernel/traps.c @@ -553,9 +553,10 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs) die_if_kernel("Kernel ale access", regs); force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); #else + bool pie = regs_irqs_disabled(regs); unsigned int *pc;
- if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_enable();
perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); @@ -582,7 +583,7 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs) die_if_kernel("Kernel ale access", regs); force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); out: - if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_disable(); #endif irqentry_exit(regs, state); @@ -621,12 +622,13 @@ static void bug_handler(struct pt_regs *regs) asmlinkage void noinstr do_bce(struct pt_regs *regs) { bool user = user_mode(regs); + bool pie = regs_irqs_disabled(regs); unsigned long era = exception_era(regs); u64 badv = 0, lower = 0, upper = ULONG_MAX; union loongarch_instruction insn; irqentry_state_t state = irqentry_enter(regs);
- if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_enable();
current->thread.trap_nr = read_csr_excode(); @@ -692,7 +694,7 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs) force_sig_bnderr((void __user *)badv, (void __user *)lower, (void __user *)upper);
out: - if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_disable();
irqentry_exit(regs, state); @@ -710,11 +712,12 @@ asmlinkage void noinstr do_bce(struct pt_regs *regs) asmlinkage void noinstr do_bp(struct pt_regs *regs) { bool user = user_mode(regs); + bool pie = regs_irqs_disabled(regs); unsigned int opcode, bcode; unsigned long era = exception_era(regs); irqentry_state_t state = irqentry_enter(regs);
- if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_enable();
if (__get_inst(&opcode, (u32 *)era, user)) @@ -780,7 +783,7 @@ asmlinkage void noinstr do_bp(struct pt_regs *regs) }
out: - if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_disable();
irqentry_exit(regs, state); @@ -1015,6 +1018,7 @@ static void init_restore_lbt(void)
asmlinkage void noinstr do_lbt(struct pt_regs *regs) { + bool pie = regs_irqs_disabled(regs); irqentry_state_t state = irqentry_enter(regs);
/* @@ -1024,7 +1028,7 @@ asmlinkage void noinstr do_lbt(struct pt_regs *regs) * (including the user using 'MOVGR2GCSR' to turn on TM, which * will not trigger the BTE), we need to check PRMD first. */ - if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_enable();
if (!cpu_has_lbt) { @@ -1038,7 +1042,7 @@ asmlinkage void noinstr do_lbt(struct pt_regs *regs) preempt_enable();
out: - if (regs->csr_prmd & CSR_PRMD_PIE) + if (!pie) local_irq_disable();
irqentry_exit(regs, state);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Omar Sandoval osandov@fb.com
[ Upstream commit bbce3de72be56e4b5f68924b7da9630cc89aa1a8 ]
There is a code path in dequeue_entities() that can set the slice of a sched_entity to U64_MAX, which sometimes results in a crash.
The offending case is when dequeue_entities() is called to dequeue a delayed group entity, and then the entity's parent's dequeue is delayed. In that case:
1. In the if (entity_is_task(se)) else block at the beginning of dequeue_entities(), slice is set to cfs_rq_min_slice(group_cfs_rq(se)). If the entity was delayed, then it has no queued tasks, so cfs_rq_min_slice() returns U64_MAX. 2. The first for_each_sched_entity() loop dequeues the entity. 3. If the entity was its parent's only child, then the next iteration tries to dequeue the parent. 4. If the parent's dequeue needs to be delayed, then it breaks from the first for_each_sched_entity() loop _without updating slice_. 5. The second for_each_sched_entity() loop sets the parent's ->slice to the saved slice, which is still U64_MAX.
This throws off subsequent calculations with potentially catastrophic results. A manifestation we saw in production was:
6. In update_entity_lag(), se->slice is used to calculate limit, which ends up as a huge negative number. 7. limit is used in se->vlag = clamp(vlag, -limit, limit). Because limit is negative, vlag > limit, so se->vlag is set to the same huge negative number. 8. In place_entity(), se->vlag is scaled, which overflows and results in another huge (positive or negative) number. 9. The adjusted lag is subtracted from se->vruntime, which increases or decreases se->vruntime by a huge number. 10. pick_eevdf() calls entity_eligible()/vruntime_eligible(), which incorrectly returns false because the vruntime is so far from the other vruntimes on the queue, causing the (vruntime - cfs_rq->min_vruntime) * load calulation to overflow. 11. Nothing appears to be eligible, so pick_eevdf() returns NULL. 12. pick_next_entity() tries to dereference the return value of pick_eevdf() and crashes.
Dumping the cfs_rq states from the core dumps with drgn showed tell-tale huge vruntime ranges and bogus vlag values, and I also traced se->slice being set to U64_MAX on live systems (which was usually "benign" since the rest of the runqueue needed to be in a particular state to crash).
Fix it in dequeue_entities() by always setting slice from the first non-empty cfs_rq.
Fixes: aef6987d8954 ("sched/eevdf: Propagate min_slice up the cgroup hierarchy") Signed-off-by: Omar Sandoval osandov@fb.com Signed-off-by: Peter Zijlstra (Intel) peterz@infradead.org Signed-off-by: Ingo Molnar mingo@kernel.org Link: https://lkml.kernel.org/r/f0c2d1072be229e1bdddc73c0703919a8b00c652.174557099... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/sched/fair.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 89c7260103e18..3d9b68a347b76 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c @@ -7083,9 +7083,6 @@ static int dequeue_entities(struct rq *rq, struct sched_entity *se, int flags) h_nr_idle = task_has_idle_policy(p); if (task_sleep || task_delayed || !se->sched_delayed) h_nr_runnable = 1; - } else { - cfs_rq = group_cfs_rq(se); - slice = cfs_rq_min_slice(cfs_rq); }
for_each_sched_entity(se) { @@ -7095,6 +7092,7 @@ static int dequeue_entities(struct rq *rq, struct sched_entity *se, int flags) if (p && &p->se == se) return -1;
+ slice = cfs_rq_min_slice(cfs_rq); break; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit f732549eb303d7e382f5101b82bb6852ad4ad642 upstream.
Currently, the calls to phylink's suspend and resume functions are inside overly complex tests, and boil down to:
if (device_may_wakeup(priv->device) && priv->plat->pmt) { call phylink } else { call phylink and if (device_may_wakeup(priv->device)) do something else }
This results in phylink always being called, possibly with differing arguments for phylink_suspend().
Simplify this code, noting that each site is slightly different due to the order in which phylink is called and the "something else".
Reviewed-by: Andrew Lunn andrew@lunn.ch Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/E1tpQL1-005St4-Hn@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Cc: Jon Hunter jonathanh@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -7813,13 +7813,11 @@ int stmmac_suspend(struct device *dev) mutex_unlock(&priv->lock);
rtnl_lock(); - if (device_may_wakeup(priv->device) && priv->plat->pmt) { - phylink_suspend(priv->phylink, true); - } else { - if (device_may_wakeup(priv->device)) - phylink_speed_down(priv->phylink, false); - phylink_suspend(priv->phylink, false); - } + if (device_may_wakeup(priv->device) && !priv->plat->pmt) + phylink_speed_down(priv->phylink, false); + + phylink_suspend(priv->phylink, + device_may_wakeup(priv->device) && priv->plat->pmt); rtnl_unlock();
if (stmmac_fpe_supported(priv)) @@ -7909,13 +7907,9 @@ int stmmac_resume(struct device *dev) }
rtnl_lock(); - if (device_may_wakeup(priv->device) && priv->plat->pmt) { - phylink_resume(priv->phylink); - } else { - phylink_resume(priv->phylink); - if (device_may_wakeup(priv->device)) - phylink_speed_up(priv->phylink); - } + phylink_resume(priv->phylink); + if (device_may_wakeup(priv->device) && !priv->plat->pmt) + phylink_speed_up(priv->phylink); rtnl_unlock();
rtnl_lock();
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit 367f1854d442b33c4a0305b068ae40d67ccd7d6a upstream.
When the system is suspended, the PHY may be placed in low-power mode by setting the BMCR 0.11 Power down bit. IEEE 802.3 states that the behaviour of the PHY in this state is implementation specific, and the PHY is not required to meet the RX_CLK and TX_CLK requirements. Essentially, this means that a PHY may stop the clocks that it is generating while in power down state.
However, MACs exist which require the clocks from the PHY to be running in order to properly resume. phylink_prepare_resume() provides them with a way to clear the Power down bit early.
Note, however, that IEEE 802.3 gives PHYs up to 500ms grace before the transmit and receive clocks meet the requirements after clearing the power down bit.
Add a resume preparation function, which will ensure that the receive clock from the PHY is appropriately configured while resuming.
Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://patch.msgid.link/E1tvO6V-008Vjb-AP@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Cc: Jon Hunter jonathanh@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/phy/phylink.c | 25 +++++++++++++++++++++++++ include/linux/phylink.h | 1 + 2 files changed, 26 insertions(+)
--- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -2668,6 +2668,31 @@ void phylink_suspend(struct phylink *pl, EXPORT_SYMBOL_GPL(phylink_suspend);
/** + * phylink_prepare_resume() - prepare to resume a network device + * @pl: a pointer to a &struct phylink returned from phylink_create() + * + * Optional, but if called must be called prior to phylink_resume(). + * + * Prepare to resume a network device, preparing the PHY as necessary. + */ +void phylink_prepare_resume(struct phylink *pl) +{ + struct phy_device *phydev = pl->phydev; + + ASSERT_RTNL(); + + /* IEEE 802.3 22.2.4.1.5 allows PHYs to stop their receive clock + * when PDOWN is set. However, some MACs require RXC to be running + * in order to resume. If the MAC requires RXC, and we have a PHY, + * then resume the PHY. Note that 802.3 allows PHYs 500ms before + * the clock meets requirements. We do not implement this delay. + */ + if (pl->config->mac_requires_rxc && phydev && phydev->suspended) + phy_resume(phydev); +} +EXPORT_SYMBOL_GPL(phylink_prepare_resume); + +/** * phylink_resume() - handle a network device resume event * @pl: a pointer to a &struct phylink returned from phylink_create() * --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -679,6 +679,7 @@ void phylink_start(struct phylink *); void phylink_stop(struct phylink *);
void phylink_suspend(struct phylink *pl, bool mac_wol); +void phylink_prepare_resume(struct phylink *pl); void phylink_resume(struct phylink *pl);
void phylink_ethtool_get_wol(struct phylink *, struct ethtool_wolinfo *);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit ef43e5132895ad59b45e38855d32e966bb7434d9 upstream.
The Synopsys Designware GMAC core databook requires all clocks to be active in order to complete software reset, which we perform during resume.
However, IEEE 802.3 allows a PHY to stop its clocks when placed in low-power mode, which happens when the system is suspended and WoL is not enabled.
As an attempt to work around this, commit 36d18b5664ef ("net: stmmac: start phylink instance before stmmac_hw_setup()") started phylink early, but this has the side effect that the mac_link_up() method may be called before or during the initialisation of GMAC hardware.
We also have the socfpga glue driver directly calling phy_resume() also as an attempt to work around this.
In a previous commit, phylink_prepare_resume() has been introduced to give MAC drivers a way to ensure that the PHY is resumed prior to their initialisation of their MAC hardware. This commit adds the call, and moves the phylink_resume() call back to where it should be before the aforementioned commit.
Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://patch.msgid.link/E1tvO6a-008Vjh-FG@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Cc: Jon Hunter jonathanh@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -7907,12 +7907,12 @@ int stmmac_resume(struct device *dev) }
rtnl_lock(); - phylink_resume(priv->phylink); - if (device_may_wakeup(priv->device) && !priv->plat->pmt) - phylink_speed_up(priv->phylink); - rtnl_unlock();
- rtnl_lock(); + /* Prepare the PHY to resume, ensuring that its clocks which are + * necessary for the MAC DMA reset to complete are running + */ + phylink_prepare_resume(priv->phylink); + mutex_lock(&priv->lock);
stmmac_reset_queues_param(priv); @@ -7930,6 +7930,15 @@ int stmmac_resume(struct device *dev) stmmac_enable_all_dma_irq(priv);
mutex_unlock(&priv->lock); + + /* phylink_resume() must be called after the hardware has been + * initialised because it may bring the link up immediately in a + * workqueue thread, which will race with initialisation. + */ + phylink_resume(priv->phylink); + if (device_may_wakeup(priv->device) && !priv->plat->pmt) + phylink_speed_up(priv->phylink); + rtnl_unlock();
netif_device_attach(ndev);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit 366aeeba79088003307f0f12bb3575fb083cc72a upstream.
As the previous commit addressed DWGMAC resuming with a PHY in suspended state, there is now no need for socfpga to work around this. Remove this code.
Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://patch.msgid.link/E1tvO6f-008Vjn-J1@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Cc: Jon Hunter jonathanh@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 18 ------------------ 1 file changed, 18 deletions(-)
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c @@ -523,24 +523,6 @@ static int socfpga_dwmac_resume(struct d
dwmac_priv->ops->set_phy_mode(priv->plat->bsp_priv);
- /* Before the enet controller is suspended, the phy is suspended. - * This causes the phy clock to be gated. The enet controller is - * resumed before the phy, so the clock is still gated "off" when - * the enet controller is resumed. This code makes sure the phy - * is "resumed" before reinitializing the enet controller since - * the enet controller depends on an active phy clock to complete - * a DMA reset. A DMA reset will "time out" if executed - * with no phy clock input on the Synopsys enet controller. - * Verified through Synopsys Case #8000711656. - * - * Note that the phy clock is also gated when the phy is isolated. - * Phy "suspend" and "isolate" controls are located in phy basic - * control register 0, and can be modified by the phy driver - * framework. - */ - if (ndev->phydev) - phy_resume(ndev->phydev); - return stmmac_resume(dev); } #endif /* CONFIG_PM_SLEEP */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit ddf4bd3f738485c84edb98ff96a5759904498e70 upstream.
Some MACs require the PHY receive clock to be running to complete setup actions. This may fail if the PHY has negotiated EEE, the MAC supports receive clock stop, and the link has entered LPI state. Provide a pair of APIs that MAC drivers can use to temporarily block the PHY disabling the receive clock.
Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://patch.msgid.link/E1tvO6k-008Vjt-MZ@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Cc: Jon Hunter jonathanh@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/phy/phylink.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/phylink.h | 3 ++ 2 files changed, 62 insertions(+)
--- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -90,6 +90,7 @@ struct phylink { bool mac_enable_tx_lpi; bool mac_tx_clk_stop; u32 mac_tx_lpi_timer; + u8 mac_rx_clk_stop_blocked;
struct sfp_bus *sfp_bus; bool sfp_may_have_phy; @@ -2622,6 +2623,64 @@ void phylink_stop(struct phylink *pl) EXPORT_SYMBOL_GPL(phylink_stop);
/** + * phylink_rx_clk_stop_block() - block PHY ability to stop receive clock in LPI + * @pl: a pointer to a &struct phylink returned from phylink_create() + * + * Disable the PHY's ability to stop the receive clock while the receive path + * is in EEE LPI state, until the number of calls to phylink_rx_clk_stop_block() + * are balanced by calls to phylink_rx_clk_stop_unblock(). + */ +void phylink_rx_clk_stop_block(struct phylink *pl) +{ + ASSERT_RTNL(); + + if (pl->mac_rx_clk_stop_blocked == U8_MAX) { + phylink_warn(pl, "%s called too many times - ignoring\n", + __func__); + dump_stack(); + return; + } + + /* Disable PHY receive clock stop if this is the first time this + * function has been called and clock-stop was previously enabled. + */ + if (pl->mac_rx_clk_stop_blocked++ == 0 && + pl->mac_supports_eee_ops && pl->phydev && + pl->config->eee_rx_clk_stop_enable) + phy_eee_rx_clock_stop(pl->phydev, false); +} +EXPORT_SYMBOL_GPL(phylink_rx_clk_stop_block); + +/** + * phylink_rx_clk_stop_unblock() - unblock PHY ability to stop receive clock + * @pl: a pointer to a &struct phylink returned from phylink_create() + * + * All calls to phylink_rx_clk_stop_block() must be balanced with a + * corresponding call to phylink_rx_clk_stop_unblock() to restore the PHYs + * ability to stop the receive clock when the receive path is in EEE LPI mode. + */ +void phylink_rx_clk_stop_unblock(struct phylink *pl) +{ + ASSERT_RTNL(); + + if (pl->mac_rx_clk_stop_blocked == 0) { + phylink_warn(pl, "%s called too many times - ignoring\n", + __func__); + dump_stack(); + return; + } + + /* Re-enable PHY receive clock stop if the number of unblocks matches + * the number of calls to the block function above. + */ + if (--pl->mac_rx_clk_stop_blocked == 0 && + pl->mac_supports_eee_ops && pl->phydev && + pl->config->eee_rx_clk_stop_enable) + phy_eee_rx_clock_stop(pl->phydev, true); +} +EXPORT_SYMBOL_GPL(phylink_rx_clk_stop_unblock); + +/** * phylink_suspend() - handle a network device suspend event * @pl: a pointer to a &struct phylink returned from phylink_create() * @mac_wol: true if the MAC needs to receive packets for Wake-on-Lan --- a/include/linux/phylink.h +++ b/include/linux/phylink.h @@ -678,6 +678,9 @@ int phylink_pcs_pre_init(struct phylink void phylink_start(struct phylink *); void phylink_stop(struct phylink *);
+void phylink_rx_clk_stop_block(struct phylink *); +void phylink_rx_clk_stop_unblock(struct phylink *); + void phylink_suspend(struct phylink *pl, bool mac_wol); void phylink_prepare_resume(struct phylink *pl); void phylink_resume(struct phylink *pl);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Russell King (Oracle) rmk+kernel@armlinux.org.uk
commit dd557266cf5fb01a8cd85482dd258c1e172301d1 upstream.
The DesignWare core requires the receive clock to be running during certain operations. Ensure that we block PHY RXC clock-stop during these operations.
This is a best-efforts change - not everywhere can be covered by this because of net's core locking, which means we can't access the MDIO bus to configure the PHY to disable RXC clock-stop in certain areas. These are marked with FIXME comments.
Signed-off-by: Russell King (Oracle) rmk+kernel@armlinux.org.uk Link: https://patch.msgid.link/E1tvO6p-008Vjz-Qy@rmk-PC.armlinux.org.uk Signed-off-by: Jakub Kicinski kuba@kernel.org Cc: Jon Hunter jonathanh@nvidia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+)
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3448,9 +3448,18 @@ static int stmmac_hw_setup(struct net_de if (priv->hw->phylink_pcs) phylink_pcs_pre_init(priv->phylink, priv->hw->phylink_pcs);
+ /* Note that clk_rx_i must be running for reset to complete. This + * clock may also be required when setting the MAC address. + * + * Block the receive clock stop for LPI mode at the PHY in case + * the link is established with EEE mode active. + */ + phylink_rx_clk_stop_block(priv->phylink); + /* DMA initialization and SW reset */ ret = stmmac_init_dma_engine(priv); if (ret < 0) { + phylink_rx_clk_stop_unblock(priv->phylink); netdev_err(priv->dev, "%s: DMA engine initialization failed\n", __func__); return ret; @@ -3458,6 +3467,7 @@ static int stmmac_hw_setup(struct net_de
/* Copy the MAC addr into the HW */ stmmac_set_umac_addr(priv, priv->hw, dev->dev_addr, 0); + phylink_rx_clk_stop_unblock(priv->phylink);
/* PS and related bits will be programmed according to the speed */ if (priv->hw->pcs) { @@ -3568,7 +3578,9 @@ static int stmmac_hw_setup(struct net_de /* Start the ball rolling... */ stmmac_start_all_dma(priv);
+ phylink_rx_clk_stop_block(priv->phylink); stmmac_set_hw_vlan_mode(priv, priv->hw); + phylink_rx_clk_stop_unblock(priv->phylink);
return 0; } @@ -5853,6 +5865,9 @@ static void stmmac_tx_timeout(struct net * whenever multicast addresses must be enabled/disabled. * Return value: * void. + * + * FIXME: This may need RXC to be running, but it may be called with BH + * disabled, which means we can't call phylink_rx_clk_stop*(). */ static void stmmac_set_rx_mode(struct net_device *dev) { @@ -5985,7 +6000,9 @@ static int stmmac_set_features(struct ne else priv->hw->hw_vlan_en = false;
+ phylink_rx_clk_stop_block(priv->phylink); stmmac_set_hw_vlan_mode(priv, priv->hw); + phylink_rx_clk_stop_unblock(priv->phylink);
return 0; } @@ -6269,7 +6286,9 @@ static int stmmac_set_mac_address(struct if (ret) goto set_mac_error;
+ phylink_rx_clk_stop_block(priv->phylink); stmmac_set_umac_addr(priv, priv->hw, ndev->dev_addr, 0); + phylink_rx_clk_stop_unblock(priv->phylink);
set_mac_error: pm_runtime_put(priv->device); @@ -6625,6 +6644,9 @@ static int stmmac_vlan_update(struct stm return stmmac_update_vlan_hash(priv, priv->hw, hash, pmatch, is_double); }
+/* FIXME: This may need RXC to be running, but it may be called with BH + * disabled, which means we can't call phylink_rx_clk_stop*(). + */ static int stmmac_vlan_rx_add_vid(struct net_device *ndev, __be16 proto, u16 vid) { struct stmmac_priv *priv = netdev_priv(ndev); @@ -6656,6 +6678,9 @@ err_pm_put: return ret; }
+/* FIXME: This may need RXC to be running, but it may be called with BH + * disabled, which means we can't call phylink_rx_clk_stop*(). + */ static int stmmac_vlan_rx_kill_vid(struct net_device *ndev, __be16 proto, u16 vid) { struct stmmac_priv *priv = netdev_priv(ndev); @@ -7922,9 +7947,11 @@ int stmmac_resume(struct device *dev)
stmmac_hw_setup(ndev, false); stmmac_init_coalesce(priv); + phylink_rx_clk_stop_block(priv->phylink); stmmac_set_rx_mode(ndev);
stmmac_restore_hw_vlan_rx_fltr(priv, ndev, priv->hw); + phylink_rx_clk_stop_unblock(priv->phylink);
stmmac_enable_all_queues(priv); stmmac_enable_all_dma_irq(priv);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal fw@strlen.de
commit eaaff9b6702e99be5d79135f2afa9fc48a0d59e0 upstream.
In case the fib match is used from the input hook we can avoid the fib lookup if early demux assigned a socket for us: check that the input interface matches sk-cached one.
Rework the existing 'lo bypass' logic to first check sk, then for loopback interface type to elide the fib lookup.
This speeds up fib matching a little, before: 93.08 GBit/s (no rules at all) 75.1 GBit/s ("fib saddr . iif oif missing drop" in prerouting) 75.62 GBit/s ("fib saddr . iif oif missing drop" in input)
After: 92.48 GBit/s (no rules at all) 75.62 GBit/s (fib rule in prerouting) 90.37 GBit/s (fib rule in input).
Numbers for the 'no rules' and 'prerouting' are expected to closely match in-between runs, the 3rd/input test case exercises the the 'avoid lookup if cached ifindex in sk matches' case.
Test used iperf3 via veth interface, lo can't be used due to existing loopback test.
Signed-off-by: Florian Westphal fw@strlen.de Signed-off-by: Pablo Neira Ayuso pablo@netfilter.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- include/net/netfilter/nft_fib.h | 21 +++++++++++++++++++++ net/ipv4/netfilter/nft_fib_ipv4.c | 11 +++++------ net/ipv6/netfilter/nft_fib_ipv6.c | 19 ++++++++++--------- 3 files changed, 36 insertions(+), 15 deletions(-)
--- a/include/net/netfilter/nft_fib.h +++ b/include/net/netfilter/nft_fib.h @@ -18,6 +18,27 @@ nft_fib_is_loopback(const struct sk_buff return skb->pkt_type == PACKET_LOOPBACK || in->flags & IFF_LOOPBACK; }
+static inline bool nft_fib_can_skip(const struct nft_pktinfo *pkt) +{ + const struct net_device *indev = nft_in(pkt); + const struct sock *sk; + + switch (nft_hook(pkt)) { + case NF_INET_PRE_ROUTING: + case NF_INET_INGRESS: + case NF_INET_LOCAL_IN: + break; + default: + return false; + } + + sk = pkt->skb->sk; + if (sk && sk_fullsock(sk)) + return sk->sk_rx_dst_ifindex == indev->ifindex; + + return nft_fib_is_loopback(pkt->skb, indev); +} + int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr, bool reset); int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]); --- a/net/ipv4/netfilter/nft_fib_ipv4.c +++ b/net/ipv4/netfilter/nft_fib_ipv4.c @@ -71,6 +71,11 @@ void nft_fib4_eval(const struct nft_expr const struct net_device *oif; const struct net_device *found;
+ if (nft_fib_can_skip(pkt)) { + nft_fib_store_result(dest, priv, nft_in(pkt)); + return; + } + /* * Do not set flowi4_oif, it restricts results (for example, asking * for oif 3 will get RTN_UNICAST result even if the daddr exits @@ -85,12 +90,6 @@ void nft_fib4_eval(const struct nft_expr else oif = NULL;
- if (nft_hook(pkt) == NF_INET_PRE_ROUTING && - nft_fib_is_loopback(pkt->skb, nft_in(pkt))) { - nft_fib_store_result(dest, priv, nft_in(pkt)); - return; - } - iph = skb_header_pointer(pkt->skb, noff, sizeof(_iph), &_iph); if (!iph) { regs->verdict.code = NFT_BREAK; --- a/net/ipv6/netfilter/nft_fib_ipv6.c +++ b/net/ipv6/netfilter/nft_fib_ipv6.c @@ -170,6 +170,11 @@ void nft_fib6_eval(const struct nft_expr struct rt6_info *rt; int lookup_flags;
+ if (nft_fib_can_skip(pkt)) { + nft_fib_store_result(dest, priv, nft_in(pkt)); + return; + } + if (priv->flags & NFTA_FIB_F_IIF) oif = nft_in(pkt); else if (priv->flags & NFTA_FIB_F_OIF) @@ -181,17 +186,13 @@ void nft_fib6_eval(const struct nft_expr return; }
- lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif, iph); - - if (nft_hook(pkt) == NF_INET_PRE_ROUTING || - nft_hook(pkt) == NF_INET_INGRESS) { - if (nft_fib_is_loopback(pkt->skb, nft_in(pkt)) || - nft_fib_v6_skip_icmpv6(pkt->skb, pkt->tprot, iph)) { - nft_fib_store_result(dest, priv, nft_in(pkt)); - return; - } + if (nft_fib_v6_skip_icmpv6(pkt->skb, pkt->tprot, iph)) { + nft_fib_store_result(dest, priv, nft_in(pkt)); + return; }
+ lookup_flags = nft_fib6_flowi_init(&fl6, priv, pkt, oif, iph); + *dest = 0; rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, pkt->skb, lookup_flags);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Halil Pasic pasic@linux.ibm.com
commit fbd3039a64b01b769040677c4fc68badeca8e3b2 upstream.
As per virtio spec the fields cols and rows are specified as little endian. Although there is no legacy interface requirement that would state that cols and rows need to be handled as native endian when legacy interface is used, unlike for the fields of the adjacent struct virtio_console_control, I decided to err on the side of caution based on some non-conclusive virtio spec repo archaeology and opt for using virtio16_to_cpu() much like for virtio_console_control.event. Strictly by the letter of the spec virtio_le_to_cpu() would have been sufficient. But when the legacy interface is not used, it boils down to the same.
And when using the legacy interface, the device formatting these as little endian when the guest is big endian would surprise me more than it using guest native byte order (which would make it compatible with the current implementation). Nevertheless somebody trying to implement the spec following it to the letter could end up forcing little endian byte order when the legacy interface is in use. So IMHO this ultimately needs a judgement call by the maintainers.
Fixes: 8345adbf96fc1 ("virtio: console: Accept console size along with resize control message") Signed-off-by: Halil Pasic pasic@linux.ibm.com Cc: stable@vger.kernel.org # v2.6.35+ Message-Id: 20250322002954.3129282-1-pasic@linux.ibm.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/virtio_console.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1579,8 +1579,8 @@ static void handle_control_message(struc break; case VIRTIO_CONSOLE_RESIZE: { struct { - __u16 rows; - __u16 cols; + __virtio16 rows; + __virtio16 cols; } size;
if (!is_console_port(port)) @@ -1588,7 +1588,8 @@ static void handle_control_message(struc
memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt), sizeof(size)); - set_console_size(port, size.rows, size.cols); + set_console_size(port, virtio16_to_cpu(vdev, size.rows), + virtio16_to_cpu(vdev, size.cols));
port->cons.hvc->irq_requested = 1; resize_console(port);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao leitao@debian.org
commit 47068309b5777313b6ac84a77d8d10dc7312260a upstream.
Replace kzalloc with kvzalloc for the exit_dump buffer allocation, which can require large contiguous memory depending on the implementation. This change prevents allocation failures by allowing the system to fall back to vmalloc when contiguous memory allocation fails.
Since this buffer is only used for debugging purposes, physical memory contiguity is not required, making vmalloc a suitable alternative.
Cc: stable@vger.kernel.org Fixes: 07814a9439a3b0 ("sched_ext: Print debug dump after an error exit") Suggested-by: Rik van Riel riel@surriel.com Signed-off-by: Breno Leitao leitao@debian.org Acked-by: Andrea Righi arighi@nvidia.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- kernel/sched/ext.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/kernel/sched/ext.c +++ b/kernel/sched/ext.c @@ -4944,7 +4944,7 @@ unlock:
static void free_exit_info(struct scx_exit_info *ei) { - kfree(ei->dump); + kvfree(ei->dump); kfree(ei->msg); kfree(ei->bt); kfree(ei); @@ -4960,7 +4960,7 @@ static struct scx_exit_info *alloc_exit_
ei->bt = kcalloc(SCX_EXIT_BT_LEN, sizeof(ei->bt[0]), GFP_KERNEL); ei->msg = kzalloc(SCX_EXIT_MSG_LEN, GFP_KERNEL); - ei->dump = kzalloc(exit_dump_len, GFP_KERNEL); + ei->dump = kvzalloc(exit_dump_len, GFP_KERNEL);
if (!ei->bt || !ei->msg || !ei->dump) { free_exit_info(ei);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Behún kabel@kernel.org
commit 8006aff15516a170640239c5a8e6696c0ba18d8e upstream.
According to the review by Bill Cox [1], the Atmel SHA204A random number generator produces random numbers with very low entropy.
Set the lowest possible entropy for this chip just to be safe.
[1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html
Fixes: da001fb651b00e1d ("crypto: atmel-i2c - add support for SHA204A random number generator") Cc: stable@vger.kernel.org Signed-off-by: Marek Behún kabel@kernel.org Acked-by: Ard Biesheuvel ardb@kernel.org Reviewed-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/crypto/atmel-sha204a.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/crypto/atmel-sha204a.c +++ b/drivers/crypto/atmel-sha204a.c @@ -163,6 +163,12 @@ static int atmel_sha204a_probe(struct i2 i2c_priv->hwrng.name = dev_name(&client->dev); i2c_priv->hwrng.read = atmel_sha204a_rng_read;
+ /* + * According to review by Bill Cox [1], this HWRNG has very low entropy. + * [1] https://www.metzdowd.com/pipermail/cryptography/2014-December/023858.html + */ + i2c_priv->hwrng.quality = 1; + ret = devm_hwrng_register(&client->dev, &i2c_priv->hwrng); if (ret) dev_warn(&client->dev, "failed to register RNG (%d)\n", ret);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Nepomnyashih sdl@nppct.ru
commit cc3628dcd851ddd8d418bf0c897024b4621ddc92 upstream.
The function xdp_convert_buff_to_frame() may return NULL if it fails to correctly convert the XDP buffer into an XDP frame due to memory constraints, internal errors, or invalid data. Failing to check for NULL may lead to a NULL pointer dereference if the result is used later in processing, potentially causing crashes, data corruption, or undefined behavior.
On XDP redirect failure, the associated page must be released explicitly if it was previously retained via get_page(). Failing to do so may result in a memory leak, as the pages reference count is not decremented.
Cc: stable@vger.kernel.org # v5.9+ Fixes: 6c5aa6fc4def ("xen networking: add basic XDP support for xen-netfront") Signed-off-by: Alexey Nepomnyashih sdl@nppct.ru Link: https://patch.msgid.link/20250417122118.1009824-1-sdl@nppct.ru Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/xen-netfront.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
--- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -985,20 +985,27 @@ static u32 xennet_run_xdp(struct netfron act = bpf_prog_run_xdp(prog, xdp); switch (act) { case XDP_TX: - get_page(pdata); xdpf = xdp_convert_buff_to_frame(xdp); + if (unlikely(!xdpf)) { + trace_xdp_exception(queue->info->netdev, prog, act); + break; + } + get_page(pdata); err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0); - if (unlikely(!err)) + if (unlikely(err <= 0)) { + if (err < 0) + trace_xdp_exception(queue->info->netdev, prog, act); xdp_return_frame_rx_napi(xdpf); - else if (unlikely(err < 0)) - trace_xdp_exception(queue->info->netdev, prog, act); + } break; case XDP_REDIRECT: get_page(pdata); err = xdp_do_redirect(queue->info->netdev, xdp, prog); *need_xdp_flush = true; - if (unlikely(err)) + if (unlikely(err)) { trace_xdp_exception(queue->info->netdev, prog, act); + xdp_return_buff(xdp); + } break; case XDP_PASS: case XDP_DROP:
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel o.rempel@pengutronix.de
commit 9e8d1013b0c38910cbc9e60de74dbe883878469d upstream.
Zero-initialize TCP header via memset() to avoid garbage values that may affect checksum or behavior during test transmission.
Also zero-fill allocated payload and padding regions using memset() after skb_put(), ensuring deterministic content for all outgoing test packets.
Fixes: 3e1e58d64c3d ("net: add generic selftest support") Signed-off-by: Oleksij Rempel o.rempel@pengutronix.de Cc: stable@vger.kernel.org Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/20250416160125.2914724-1-o.rempel@pengutronix.de Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/core/selftests.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-)
--- a/net/core/selftests.c +++ b/net/core/selftests.c @@ -100,10 +100,10 @@ static struct sk_buff *net_test_get_skb( ehdr->h_proto = htons(ETH_P_IP);
if (attr->tcp) { + memset(thdr, 0, sizeof(*thdr)); thdr->source = htons(attr->sport); thdr->dest = htons(attr->dport); thdr->doff = sizeof(struct tcphdr) / 4; - thdr->check = 0; } else { uhdr->source = htons(attr->sport); uhdr->dest = htons(attr->dport); @@ -144,10 +144,18 @@ static struct sk_buff *net_test_get_skb( attr->id = net_test_next_id; shdr->id = net_test_next_id++;
- if (attr->size) - skb_put(skb, attr->size); - if (attr->max_size && attr->max_size > skb->len) - skb_put(skb, attr->max_size - skb->len); + if (attr->size) { + void *payload = skb_put(skb, attr->size); + + memset(payload, 0, attr->size); + } + + if (attr->max_size && attr->max_size > skb->len) { + size_t pad_len = attr->max_size - skb->len; + void *pad = skb_put(skb, pad_len); + + memset(pad, 0, pad_len); + }
skb->csum = 0; skb->ip_summed = CHECKSUM_PARTIAL;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fiona Klute fiona.klute@gmx.de
commit 30a41ed32d3088cd0d682a13d7f30b23baed7e93 upstream.
With lan88xx based devices the lan78xx driver can get stuck in an interrupt loop while bringing the device up, flooding the kernel log with messages like the following:
lan78xx 2-3:1.0 enp1s0u3: kevent 4 may have been dropped
Removing interrupt support from the lan88xx PHY driver forces the driver to use polling instead, which avoids the problem.
The issue has been observed with Raspberry Pi devices at least since 4.14 (see [1], bug report for their downstream kernel), as well as with Nvidia devices [2] in 2020, where disabling interrupts was the vendor-suggested workaround (together with the claim that phylib changes in 4.9 made the interrupt handling in lan78xx incompatible).
Iperf reports well over 900Mbits/sec per direction with client in --dualtest mode, so there does not seem to be a significant impact on throughput (lan88xx device connected via switch to the peer).
[1] https://github.com/raspberrypi/linux/issues/2447 [2] https://forums.developer.nvidia.com/t/jetson-xavier-and-lan7800-problem/1421...
Link: https://lore.kernel.org/0901d90d-3f20-4a10-b680-9c978e04ddda@lunn.ch Fixes: 792aec47d59d ("add microchip LAN88xx phy driver") Signed-off-by: Fiona Klute fiona.klute@gmx.de Cc: kernel-list@raspberrypi.com Cc: stable@vger.kernel.org Reviewed-by: Andrew Lunn andrew@lunn.ch Link: https://patch.msgid.link/20250416102413.30654-1-fiona.klute@gmx.de Signed-off-by: Paolo Abeni pabeni@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/phy/microchip.c | 46 ++------------------------------------------ 1 file changed, 3 insertions(+), 43 deletions(-)
--- a/drivers/net/phy/microchip.c +++ b/drivers/net/phy/microchip.c @@ -37,47 +37,6 @@ static int lan88xx_write_page(struct phy return __phy_write(phydev, LAN88XX_EXT_PAGE_ACCESS, page); }
-static int lan88xx_phy_config_intr(struct phy_device *phydev) -{ - int rc; - - if (phydev->interrupts == PHY_INTERRUPT_ENABLED) { - /* unmask all source and clear them before enable */ - rc = phy_write(phydev, LAN88XX_INT_MASK, 0x7FFF); - rc = phy_read(phydev, LAN88XX_INT_STS); - rc = phy_write(phydev, LAN88XX_INT_MASK, - LAN88XX_INT_MASK_MDINTPIN_EN_ | - LAN88XX_INT_MASK_LINK_CHANGE_); - } else { - rc = phy_write(phydev, LAN88XX_INT_MASK, 0); - if (rc) - return rc; - - /* Ack interrupts after they have been disabled */ - rc = phy_read(phydev, LAN88XX_INT_STS); - } - - return rc < 0 ? rc : 0; -} - -static irqreturn_t lan88xx_handle_interrupt(struct phy_device *phydev) -{ - int irq_status; - - irq_status = phy_read(phydev, LAN88XX_INT_STS); - if (irq_status < 0) { - phy_error(phydev); - return IRQ_NONE; - } - - if (!(irq_status & LAN88XX_INT_STS_LINK_CHANGE_)) - return IRQ_NONE; - - phy_trigger_machine(phydev); - - return IRQ_HANDLED; -} - static int lan88xx_suspend(struct phy_device *phydev) { struct lan88xx_priv *priv = phydev->priv; @@ -528,8 +487,9 @@ static struct phy_driver microchip_phy_d .config_aneg = lan88xx_config_aneg, .link_change_notify = lan88xx_link_change_notify,
- .config_intr = lan88xx_phy_config_intr, - .handle_interrupt = lan88xx_handle_interrupt, + /* Interrupt handling is broken, do not define related + * functions to force polling. + */
.suspend = lan88xx_suspend, .resume = genphy_resume,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mat Martineau martineau@kernel.org
commit 13b4ece33cf9def67966bb8716783c42cec20617 upstream.
When path manager entries are deleted from the local address list, they are first unlinked from the address list using list_del_rcu(). The entries must not be freed until after the RCU grace period, but the existing code immediately frees the entry.
Use kfree_rcu_mightsleep() and adjust sk_omem_alloc in open code instead of using the sock_kfree_s() helper. This code path is only called in a netlink handler, so the "might sleep" function is preferable to adding a rarely-used rcu_head member to struct mptcp_pm_addr_entry.
Fixes: 88d097316371 ("mptcp: drop free_list for deleting entries") Cc: stable@vger.kernel.org Signed-off-by: Mat Martineau martineau@kernel.org Reviewed-by: Matthieu Baerts (NGI0) matttbe@kernel.org Signed-off-by: Matthieu Baerts (NGI0) matttbe@kernel.org Link: https://patch.msgid.link/20250421-net-mptcp-pm-defer-freeing-v1-1-e731dc6e86... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/mptcp/pm_userspace.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/net/mptcp/pm_userspace.c +++ b/net/mptcp/pm_userspace.c @@ -352,7 +352,11 @@ int mptcp_pm_nl_remove_doit(struct sk_bu
release_sock(sk);
- sock_kfree_s(sk, match, sizeof(*match)); + kfree_rcu_mightsleep(match); + /* Adjust sk_omem_alloc like sock_kfree_s() does, to match + * with allocation of this memory by sock_kmemdup() + */ + atomic_sub(sizeof(*match), &sk->sk_omem_alloc);
err = 0; out:
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ranjan Kumar ranjan.kumar@broadcom.com
commit cdd445258db9919e9dde497a6d5c3477ea7faf4d upstream.
Commit 199510e33dea ("scsi: mpi3mr: Update consumer index of reply queues after every 100 replies") introduced a regression with the per-reply queue pending I/O counter which was erroneously decremented, leading to the counter going negative.
Drop the incorrect atomic decrement for the pending I/O counter.
Fixes: 199510e33dea ("scsi: mpi3mr: Update consumer index of reply queues after every 100 replies") Cc: stable@vger.kernel.org Co-developed-by: Sathya Prakash sathya.prakash@broadcom.com Signed-off-by: Sathya Prakash sathya.prakash@broadcom.com Signed-off-by: Ranjan Kumar ranjan.kumar@broadcom.com Link: https://lore.kernel.org/r/20250411111419.135485-2-ranjan.kumar@broadcom.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/mpi3mr/mpi3mr_fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -563,7 +563,7 @@ int mpi3mr_process_op_reply_q(struct mpi WRITE_ONCE(op_req_q->ci, le16_to_cpu(reply_desc->request_queue_ci)); mpi3mr_process_op_reply_desc(mrioc, reply_desc, &reply_dma, reply_qidx); - atomic_dec(&op_reply_q->pend_ios); + if (reply_dma) mpi3mr_repost_reply_buf(mrioc, reply_dma); num_op_reply++;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Schrefl chrisi.schrefl@gmail.com
commit 53bd97801632c940767f4c8407c2cbdeb56b40e7 upstream.
The `FwFunc` struct contains an function with a char pointer argument, for which a `*const u8` pointer was used. This is not really the "proper" type for this, so use a `*const kernel::ffi::c_char` pointer instead.
This has no real functionality changes, since now `kernel::ffi::c_char` (which bindgen uses for `char`) is now a type alias to `u8` anyways, but before commit 1bae8729e50a ("rust: map `long` to `isize` and `char` to `u8`") the concrete type of `kernel::ffi::c_char` depended on the architecture (However all supported architectures at the time mapped to `i8`).
This caused problems on the v6.13 tag when building for 32 bit arm (with my patches), since back then `*const i8` was used in the function argument and the function that bindgen generated used `*const core::ffi::c_char` which Rust mapped to `*const u8` on 32 bit arm. The stable v6.13.y branch does not have this issue since commit 1bae8729e50a ("rust: map `long` to `isize` and `char` to `u8`") was backported.
This caused the following build error: ``` error[E0308]: mismatched types --> rust/kernel/firmware.rs:20:4 | 20 | Self(bindings::request_firmware) | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item | | | arguments to this function are incorrect | = note: expected fn pointer `unsafe extern "C" fn(_, *const i8, _) -> _` found fn item `unsafe extern "C" fn(_, *const u8, _) -> _ {request_firmware}` note: tuple struct defined here --> rust/kernel/firmware.rs:14:8 | 14 | struct FwFunc( | ^^^^^^
error[E0308]: mismatched types --> rust/kernel/firmware.rs:24:14 | 24 | Self(bindings::firmware_request_nowarn) | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn pointer, found fn item | | | arguments to this function are incorrect | = note: expected fn pointer `unsafe extern "C" fn(_, *const i8, _) -> _` found fn item `unsafe extern "C" fn(_, *const u8, _) -> _ {firmware_request_nowarn}` note: tuple struct defined here --> rust/kernel/firmware.rs:14:8 | 14 | struct FwFunc( | ^^^^^^
error[E0308]: mismatched types --> rust/kernel/firmware.rs:64:45 | 64 | let ret = unsafe { func.0(pfw as _, name.as_char_ptr(), dev.as_raw()) }; | ------ ^^^^^^^^^^^^^^^^^^ expected `*const i8`, found `*const u8` | | | arguments to this function are incorrect | = note: expected raw pointer `*const i8` found raw pointer `*const u8`
error: aborting due to 3 previous errors ```
Fixes: de6582833db0 ("rust: add firmware abstractions") Cc: stable@vger.kernel.org Reviewed-by: Benno Lossin benno.lossin@proton.me Signed-off-by: Christian Schrefl chrisi.schrefl@gmail.com Acked-by: Miguel Ojeda ojeda@kernel.org Link: https://lore.kernel.org/r/20250413-rust_arm_fix_fw_abstaction-v3-1-8dd7c0bbc... [ Add firmware prefix to commit subject. - Danilo ] Signed-off-by: Danilo Krummrich dakr@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- rust/kernel/firmware.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/rust/kernel/firmware.rs +++ b/rust/kernel/firmware.rs @@ -4,7 +4,7 @@ //! //! C header: [`include/linux/firmware.h`](srctree/include/linux/firmware.h)
-use crate::{bindings, device::Device, error::Error, error::Result, str::CStr}; +use crate::{bindings, device::Device, error::Error, error::Result, ffi, str::CStr}; use core::ptr::NonNull;
/// # Invariants @@ -12,7 +12,11 @@ use core::ptr::NonNull; /// One of the following: `bindings::request_firmware`, `bindings::firmware_request_nowarn`, /// `bindings::firmware_request_platform`, `bindings::request_firmware_direct`. struct FwFunc( - unsafe extern "C" fn(*mut *const bindings::firmware, *const u8, *mut bindings::device) -> i32, + unsafe extern "C" fn( + *mut *const bindings::firmware, + *const ffi::c_char, + *mut bindings::device, + ) -> i32, );
impl FwFunc {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hugo Villeneuve hvilleneuve@dimonoff.com
commit 095c8e61f4c71cd4630ee11a82e82cc341b38464 upstream.
commit a8972d5a49b4 ("drm: panel: jd9365da-h3: fix reset signal polarity") fixed reset signal polarity in jadard_dsi_probe() and jadard_prepare().
It was not done in jadard_unprepare() because of an incorrect assumption about reset line handling in power off mode. After looking into the datasheet, it now appears that before disabling regulators, the reset line is deasserted first, and if reset_before_power_off_vcioo is true, then the reset line is asserted.
Fix reset polarity by inverting gpiod_set_value() second argument in in jadard_unprepare().
Fixes: 6b818c533dd8 ("drm: panel: Add Jadard JD9365DA-H3 DSI panel") Fixes: 2b976ad760dc ("drm/panel: jd9365da: Support for kd101ne3-40ti MIPI-DSI panel") Fixes: a8972d5a49b4 ("drm: panel: jd9365da-h3: fix reset signal polarity") Cc: stable@vger.kernel.org Signed-off-by: Hugo Villeneuve hvilleneuve@dimonoff.com Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250417195507.778731-1-hugo@hugovil.com Signed-off-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250417195507.778731-1-hugo@hugovil.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c +++ b/drivers/gpu/drm/panel/panel-jadard-jd9365da-h3.c @@ -129,11 +129,11 @@ static int jadard_unprepare(struct drm_p { struct jadard *jadard = panel_to_jadard(panel);
- gpiod_set_value(jadard->reset, 1); + gpiod_set_value(jadard->reset, 0); msleep(120);
if (jadard->desc->reset_before_power_off_vcioo) { - gpiod_set_value(jadard->reset, 0); + gpiod_set_value(jadard->reset, 1);
usleep_range(1000, 2000); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Li Roman.Li@amd.com
commit 7eb287beeb60be1e4437be2b4e4e9f0da89aab97 upstream.
[Why] The indexing of stream_status in dm_gpureset_commit_state() is incorrect. That leads to asserts in multi-display configuration after gpu reset.
[How] Adjust the indexing logic to align stream_status with surface_updates.
Fixes: cdaae8371aa9 ("drm/amd/display: Handle GPU reset for DC block") Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3808 Reviewed-by: Aurabindo Pillai aurabindo.pillai@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Roman Li Roman.Li@amd.com Signed-off-by: Zaeem Mohamed zaeem.mohamed@amd.com Tested-by: Mark Broadworth mark.broadworth@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit d91bc901398741d317d9b55c59ca949d4bc7394b) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -3293,16 +3293,16 @@ static void dm_gpureset_commit_state(str for (k = 0; k < dc_state->stream_count; k++) { bundle->stream_update.stream = dc_state->streams[k];
- for (m = 0; m < dc_state->stream_status->plane_count; m++) { + for (m = 0; m < dc_state->stream_status[k].plane_count; m++) { bundle->surface_updates[m].surface = - dc_state->stream_status->plane_states[m]; + dc_state->stream_status[k].plane_states[m]; bundle->surface_updates[m].surface->force_full_update = true; }
update_planes_and_stream_adapter(dm->dc, UPDATE_TYPE_FULL, - dc_state->stream_status->plane_count, + dc_state->stream_status[k].plane_count, dc_state->streams[k], &bundle->stream_update, bundle->surface_updates);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Li Roman.Li@amd.com
commit 67fe574651c73fe5cc176e35f28f2ec1ba498d14 upstream.
[Why] While system undergoing gpu reset always do full update to sync the dc state before and after reset.
[How] Return true in should_reset_plane() if gpu reset detected
Reviewed-by: Aurabindo Pillai aurabindo.pillai@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Roman Li Roman.Li@amd.com Signed-off-by: Zaeem Mohamed zaeem.mohamed@amd.com Tested-by: Mark Broadworth mark.broadworth@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 2ba8619b9a378ad218ad6c2e2ccaee8f531e08de) Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -10901,6 +10901,9 @@ static bool should_reset_plane(struct dr state->allow_modeset) return true;
+ if (amdgpu_in_reset(adev) && state->allow_modeset) + return true; + /* Exit early if we know that we're adding or removing the plane. */ if (old_plane_state->crtc != new_plane_state->crtc) return true;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
commit 870bea21fdf88f45c94c0a3dbb0e3cc1b219680f upstream.
[Why] The ACPI EDID in the BIOS of a Lenovo laptop includes 3 blocks, but dm_helpers_probe_acpi_edid() has a start that is 'char'. The 3rd block index starts after 255, so it can't be indexed properly. This leads to problems with the display when the EDID is parsed.
[How] Change the variable type to 'short' so that larger values can be indexed.
Cc: Renjith Pananchikkal renjith.pananchikkal@amd.com Reported-by: Mark Pearson mpearson@lenovo.com Suggested-by: David Ober dober@lenovo.com Fixes: c6a837088bed ("drm/amd/display: Fetch the EDID from _DDC if available for eDP") Reviewed-by: Alex Hung alex.hung@amd.com Signed-off-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Zaeem Mohamed zaeem.mohamed@amd.com Tested-by: Mark Broadworth mark.broadworth@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit a918bb4a90d423ced2976a794f2724c362c1f063) 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 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c @@ -912,7 +912,7 @@ dm_helpers_probe_acpi_edid(void *data, u { struct drm_connector *connector = data; struct acpi_device *acpidev = ACPI_COMPANION(connector->dev->dev); - unsigned char start = block * EDID_LENGTH; + unsigned short start = block * EDID_LENGTH; struct edid *edid; int r;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kirill A. Shutemov kirill.shutemov@linux.intel.com
commit 85fd85bc025a525354acb2241beb3c5387c551ec upstream.
insn_decoder_test found a problem with decoding APX CTEST instructions:
Found an x86 instruction decoder bug, please report this. ffffffff810021df 62 54 94 05 85 ff ctestneq objdump says 6 bytes, but insn_get_length() says 5
It happens because x86-opcode-map.txt doesn't specify arguments for the instruction and the decoder doesn't expect to see ModRM byte.
Fixes: 690ca3a3067f ("x86/insn: Add support for APX EVEX instructions to the opcode map") Signed-off-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Cc: H. Peter Anvin hpa@zytor.com Cc: Adrian Hunter adrian.hunter@intel.com Cc: stable@vger.kernel.org # v6.10+ Link: https://lore.kernel.org/r/20250423065815.2003231-1-kirill.shutemov@linux.int... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/lib/x86-opcode-map.txt | 4 ++-- tools/arch/x86/lib/x86-opcode-map.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/x86/lib/x86-opcode-map.txt +++ b/arch/x86/lib/x86-opcode-map.txt @@ -996,8 +996,8 @@ AVXcode: 4 83: Grp1 Ev,Ib (1A),(es) # CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL, # CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ -84: CTESTSCC (ev) -85: CTESTSCC (es) | CTESTSCC (66),(es) +84: CTESTSCC Eb,Gb (ev) +85: CTESTSCC Ev,Gv (es) | CTESTSCC Ev,Gv (66),(es) 88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es) 8f: POP2 Bq,Rq (000),(11B),(ev) a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es) --- a/tools/arch/x86/lib/x86-opcode-map.txt +++ b/tools/arch/x86/lib/x86-opcode-map.txt @@ -996,8 +996,8 @@ AVXcode: 4 83: Grp1 Ev,Ib (1A),(es) # CTESTSCC instructions are: CTESTB, CTESTBE, CTESTF, CTESTL, CTESTLE, CTESTNB, CTESTNBE, CTESTNL, # CTESTNLE, CTESTNO, CTESTNS, CTESTNZ, CTESTO, CTESTS, CTESTT, CTESTZ -84: CTESTSCC (ev) -85: CTESTSCC (es) | CTESTSCC (66),(es) +84: CTESTSCC Eb,Gb (ev) +85: CTESTSCC Ev,Gv (es) | CTESTSCC Ev,Gv (66),(es) 88: POPCNT Gv,Ev (es) | POPCNT Gv,Ev (66),(es) 8f: POP2 Bq,Rq (000),(11B),(ev) a5: SHLD Ev,Gv,CL (es) | SHLD Ev,Gv,CL (66),(es)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross jgross@suse.com
commit 4ce385f56434f3810ef103e1baea357ddcc6667e upstream.
Recently _pgd_alloc() was switched from using __get_free_pages() to pagetable_alloc_noprof(), which might return a compound page in case the allocation order is larger than 0.
On x86 this will be the case if CONFIG_MITIGATION_PAGE_TABLE_ISOLATION is set, even if PTI has been disabled at runtime.
When running as a Xen PV guest (this will always disable PTI), using a compound page for a PGD will result in VM_BUG_ON_PGFLAGS being triggered when the Xen code tries to pin the PGD.
Fix the Xen issue together with the not needed 8k allocation for a PGD with PTI disabled by replacing PGD_ALLOCATION_ORDER with an inline helper returning the needed order for PGD allocations.
Fixes: a9b3c355c2e6 ("asm-generic: pgalloc: provide generic __pgd_{alloc,free}") Reported-by: Petr Vaněk arkamar@atlas.cz Signed-off-by: Juergen Gross jgross@suse.com Signed-off-by: Dave Hansen dave.hansen@linux.intel.com Tested-by: Petr Vaněk arkamar@atlas.cz Cc:stable@vger.kernel.org Link: https://lore.kernel.org/all/20250422131717.25724-1-jgross%40suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/include/asm/pgalloc.h | 19 +++++++++++-------- arch/x86/kernel/machine_kexec_32.c | 4 ++-- arch/x86/mm/pgtable.c | 4 ++-- arch/x86/platform/efi/efi_64.c | 4 ++-- 4 files changed, 17 insertions(+), 14 deletions(-)
--- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h @@ -6,6 +6,8 @@ #include <linux/mm.h> /* for struct page */ #include <linux/pagemap.h>
+#include <asm/cpufeature.h> + #define __HAVE_ARCH_PTE_ALLOC_ONE #define __HAVE_ARCH_PGD_FREE #include <asm-generic/pgalloc.h> @@ -34,16 +36,17 @@ static inline void paravirt_release_p4d( */ extern gfp_t __userpte_alloc_gfp;
-#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION /* - * Instead of one PGD, we acquire two PGDs. Being order-1, it is - * both 8k in size and 8k-aligned. That lets us just flip bit 12 - * in a pointer to swap between the two 4k halves. + * In case of Page Table Isolation active, we acquire two PGDs instead of one. + * Being order-1, it is both 8k in size and 8k-aligned. That lets us just + * flip bit 12 in a pointer to swap between the two 4k halves. */ -#define PGD_ALLOCATION_ORDER 1 -#else -#define PGD_ALLOCATION_ORDER 0 -#endif +static inline unsigned int pgd_allocation_order(void) +{ + if (cpu_feature_enabled(X86_FEATURE_PTI)) + return 1; + return 0; +}
/* * Allocate and free page tables. --- a/arch/x86/kernel/machine_kexec_32.c +++ b/arch/x86/kernel/machine_kexec_32.c @@ -42,7 +42,7 @@ static void load_segments(void)
static void machine_kexec_free_page_tables(struct kimage *image) { - free_pages((unsigned long)image->arch.pgd, PGD_ALLOCATION_ORDER); + free_pages((unsigned long)image->arch.pgd, pgd_allocation_order()); image->arch.pgd = NULL; #ifdef CONFIG_X86_PAE free_page((unsigned long)image->arch.pmd0); @@ -59,7 +59,7 @@ static void machine_kexec_free_page_tabl static int machine_kexec_alloc_page_tables(struct kimage *image) { image->arch.pgd = (pgd_t *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, - PGD_ALLOCATION_ORDER); + pgd_allocation_order()); #ifdef CONFIG_X86_PAE image->arch.pmd0 = (pmd_t *)get_zeroed_page(GFP_KERNEL); image->arch.pmd1 = (pmd_t *)get_zeroed_page(GFP_KERNEL); --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -404,7 +404,7 @@ static inline pgd_t *_pgd_alloc(struct m * We allocate one page for pgd. */ if (!SHARED_KERNEL_PMD) - return __pgd_alloc(mm, PGD_ALLOCATION_ORDER); + return __pgd_alloc(mm, pgd_allocation_order());
/* * Now PAE kernel is not running as a Xen domain. We can allocate @@ -424,7 +424,7 @@ static inline void _pgd_free(struct mm_s
static inline pgd_t *_pgd_alloc(struct mm_struct *mm) { - return __pgd_alloc(mm, PGD_ALLOCATION_ORDER); + return __pgd_alloc(mm, pgd_allocation_order()); }
static inline void _pgd_free(struct mm_struct *mm, pgd_t *pgd) --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c @@ -73,7 +73,7 @@ int __init efi_alloc_page_tables(void) gfp_t gfp_mask;
gfp_mask = GFP_KERNEL | __GFP_ZERO; - efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, PGD_ALLOCATION_ORDER); + efi_pgd = (pgd_t *)__get_free_pages(gfp_mask, pgd_allocation_order()); if (!efi_pgd) goto fail;
@@ -96,7 +96,7 @@ free_p4d: if (pgtable_l5_enabled()) free_page((unsigned long)pgd_page_vaddr(*pgd)); free_pgd: - free_pages((unsigned long)efi_pgd, PGD_ALLOCATION_ORDER); + free_pages((unsigned long)efi_pgd, pgd_allocation_order()); fail: return -ENOMEM; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilpo Järvinen ilpo.jarvinen@linux.intel.com
commit 39e703ed3b48c4262be141072d4f42a8b89a10cc upstream.
Commit df6f8c4d72ae ("selftests/pcie_bwctrl: Add 'set_pcie_speed.sh' to TEST_PROGS") added set_pcie_speed.sh into TEST_PROGS but that script is a helper that is only being called by set_pcie_cooling_state.sh, not a test case itself. When set_pcie_speed.sh is in TEST_PROGS, selftest harness will execute also it leading to bwctrl selftest errors:
# selftests: pcie_bwctrl: set_pcie_speed.sh # cat: /cur_state: No such file or directory not ok 2 selftests: pcie_bwctrl: set_pcie_speed.sh # exit=1
Place set_pcie_speed.sh into TEST_FILES instead to have it included into installed test files but not execute it from the test harness.
Fixes: df6f8c4d72ae ("selftests/pcie_bwctrl: Add 'set_pcie_speed.sh' to TEST_PROGS") Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Bjorn Helgaas bhelgaas@google.com Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20250417124529.11391-1-ilpo.jarvinen@linux.intel.co... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/testing/selftests/pcie_bwctrl/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/tools/testing/selftests/pcie_bwctrl/Makefile +++ b/tools/testing/selftests/pcie_bwctrl/Makefile @@ -1,2 +1,3 @@ -TEST_PROGS = set_pcie_cooling_state.sh set_pcie_speed.sh +TEST_PROGS = set_pcie_cooling_state.sh +TEST_FILES = set_pcie_speed.sh include ../lib.mk
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suzuki K Poulose suzuki.poulose@arm.com
commit 3318dc299b072a0511d6dfd8367f3304fb6d9827 upstream.
With ACPI in place, gicv2m_get_fwnode() is registered with the pci subsystem as pci_msi_get_fwnode_cb(), which may get invoked at runtime during a PCI host bridge probe. But, the call back is wrongly marked as __init, causing it to be freed, while being registered with the PCI subsystem and could trigger:
Unable to handle kernel paging request at virtual address ffff8000816c0400 gicv2m_get_fwnode+0x0/0x58 (P) pci_set_bus_msi_domain+0x74/0x88 pci_register_host_bridge+0x194/0x548
This is easily reproducible on a Juno board with ACPI boot.
Retain the function for later use.
Fixes: 0644b3daca28 ("irqchip/gic-v2m: acpi: Introducing GICv2m ACPI support") Signed-off-by: Suzuki K Poulose suzuki.poulose@arm.com Signed-off-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Marc Zyngier maz@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/irqchip/irq-gic-v2m.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/irqchip/irq-gic-v2m.c +++ b/drivers/irqchip/irq-gic-v2m.c @@ -423,7 +423,7 @@ static int __init gicv2m_of_init(struct #ifdef CONFIG_ACPI static int acpi_num_msi;
-static __init struct fwnode_handle *gicv2m_get_fwnode(struct device *dev) +static struct fwnode_handle *gicv2m_get_fwnode(struct device *dev) { struct v2m_data *data;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carlos Llamas cmllamas@google.com
commit 170d1a3738908eef6a0dbf378ea77fb4ae8e294d upstream.
The vma start address should be substracted from the buffer's user data address and not the other way around.
Cc: Tiffany Y. Yang ynaffit@google.com Cc: stable stable@kernel.org Fixes: 162c79731448 ("binder: avoid user addresses in debug logs") Signed-off-by: Carlos Llamas cmllamas@google.com Reviewed-by: Tiffany Y. Yang ynaffit@google.com Link: https://lore.kernel.org/r/20250325184902.587138-1-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/android/binder.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/android/binder.c +++ b/drivers/android/binder.c @@ -6373,7 +6373,7 @@ static void print_binder_transaction_ilo seq_printf(m, " node %d", buffer->target_node->debug_id); seq_printf(m, " size %zd:%zd offset %lx\n", buffer->data_size, buffer->offsets_size, - proc->alloc.vm_start - buffer->user_data); + buffer->user_data - proc->alloc.vm_start); }
static void print_binder_work_ilocked(struct seq_file *m,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tiezhu Yang yangtiezhu@loongson.cn
commit 2ef174b13344b3b4554d3d28e6f9e2a2c1d3138f upstream.
Like the other relevant symbols, export some fp, lsx, lasx and lbt assembly symbols and put the function declarations in header files rather than source files.
While at it, use "asmlinkage" for the other existing C prototypes of assembly functions and also do not use the "extern" keyword with function declarations according to the document coding-style.rst.
Cc: stable@vger.kernel.org # 6.6+ Signed-off-by: Tiezhu Yang yangtiezhu@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/include/asm/fpu.h | 37 ++++++++++++++++++++++--------------- arch/loongarch/include/asm/lbt.h | 10 +++++++--- arch/loongarch/kernel/fpu.S | 6 ++++++ arch/loongarch/kernel/lbt.S | 4 ++++ arch/loongarch/kernel/signal.c | 21 --------------------- 5 files changed, 39 insertions(+), 39 deletions(-)
--- a/arch/loongarch/include/asm/fpu.h +++ b/arch/loongarch/include/asm/fpu.h @@ -22,22 +22,29 @@ struct sigcontext;
#define kernel_fpu_available() cpu_has_fpu -extern void kernel_fpu_begin(void); -extern void kernel_fpu_end(void);
-extern void _init_fpu(unsigned int); -extern void _save_fp(struct loongarch_fpu *); -extern void _restore_fp(struct loongarch_fpu *); - -extern void _save_lsx(struct loongarch_fpu *fpu); -extern void _restore_lsx(struct loongarch_fpu *fpu); -extern void _init_lsx_upper(void); -extern void _restore_lsx_upper(struct loongarch_fpu *fpu); - -extern void _save_lasx(struct loongarch_fpu *fpu); -extern void _restore_lasx(struct loongarch_fpu *fpu); -extern void _init_lasx_upper(void); -extern void _restore_lasx_upper(struct loongarch_fpu *fpu); +void kernel_fpu_begin(void); +void kernel_fpu_end(void); + +asmlinkage void _init_fpu(unsigned int); +asmlinkage void _save_fp(struct loongarch_fpu *); +asmlinkage void _restore_fp(struct loongarch_fpu *); +asmlinkage int _save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); +asmlinkage int _restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); + +asmlinkage void _save_lsx(struct loongarch_fpu *fpu); +asmlinkage void _restore_lsx(struct loongarch_fpu *fpu); +asmlinkage void _init_lsx_upper(void); +asmlinkage void _restore_lsx_upper(struct loongarch_fpu *fpu); +asmlinkage int _save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); +asmlinkage int _restore_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); + +asmlinkage void _save_lasx(struct loongarch_fpu *fpu); +asmlinkage void _restore_lasx(struct loongarch_fpu *fpu); +asmlinkage void _init_lasx_upper(void); +asmlinkage void _restore_lasx_upper(struct loongarch_fpu *fpu); +asmlinkage int _save_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); +asmlinkage int _restore_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr);
static inline void enable_lsx(void); static inline void disable_lsx(void); --- a/arch/loongarch/include/asm/lbt.h +++ b/arch/loongarch/include/asm/lbt.h @@ -12,9 +12,13 @@ #include <asm/loongarch.h> #include <asm/processor.h>
-extern void _init_lbt(void); -extern void _save_lbt(struct loongarch_lbt *); -extern void _restore_lbt(struct loongarch_lbt *); +asmlinkage void _init_lbt(void); +asmlinkage void _save_lbt(struct loongarch_lbt *); +asmlinkage void _restore_lbt(struct loongarch_lbt *); +asmlinkage int _save_lbt_context(void __user *regs, void __user *eflags); +asmlinkage int _restore_lbt_context(void __user *regs, void __user *eflags); +asmlinkage int _save_ftop_context(void __user *ftop); +asmlinkage int _restore_ftop_context(void __user *ftop);
static inline int is_lbt_enabled(void) { --- a/arch/loongarch/kernel/fpu.S +++ b/arch/loongarch/kernel/fpu.S @@ -458,6 +458,7 @@ SYM_FUNC_START(_save_fp_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_save_fp_context) +EXPORT_SYMBOL_GPL(_save_fp_context)
/* * a0: fpregs @@ -471,6 +472,7 @@ SYM_FUNC_START(_restore_fp_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_restore_fp_context) +EXPORT_SYMBOL_GPL(_restore_fp_context)
/* * a0: fpregs @@ -484,6 +486,7 @@ SYM_FUNC_START(_save_lsx_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_save_lsx_context) +EXPORT_SYMBOL_GPL(_save_lsx_context)
/* * a0: fpregs @@ -497,6 +500,7 @@ SYM_FUNC_START(_restore_lsx_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_restore_lsx_context) +EXPORT_SYMBOL_GPL(_restore_lsx_context)
/* * a0: fpregs @@ -510,6 +514,7 @@ SYM_FUNC_START(_save_lasx_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_save_lasx_context) +EXPORT_SYMBOL_GPL(_save_lasx_context)
/* * a0: fpregs @@ -523,6 +528,7 @@ SYM_FUNC_START(_restore_lasx_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_restore_lasx_context) +EXPORT_SYMBOL_GPL(_restore_lasx_context)
.L_fpu_fault: li.w a0, -EFAULT # failure --- a/arch/loongarch/kernel/lbt.S +++ b/arch/loongarch/kernel/lbt.S @@ -90,6 +90,7 @@ SYM_FUNC_START(_save_lbt_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_save_lbt_context) +EXPORT_SYMBOL_GPL(_save_lbt_context)
/* * a0: scr @@ -110,6 +111,7 @@ SYM_FUNC_START(_restore_lbt_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_restore_lbt_context) +EXPORT_SYMBOL_GPL(_restore_lbt_context)
/* * a0: ftop @@ -120,6 +122,7 @@ SYM_FUNC_START(_save_ftop_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_save_ftop_context) +EXPORT_SYMBOL_GPL(_save_ftop_context)
/* * a0: ftop @@ -150,6 +153,7 @@ SYM_FUNC_START(_restore_ftop_context) li.w a0, 0 # success jr ra SYM_FUNC_END(_restore_ftop_context) +EXPORT_SYMBOL_GPL(_restore_ftop_context)
.L_lbt_fault: li.w a0, -EFAULT # failure --- a/arch/loongarch/kernel/signal.c +++ b/arch/loongarch/kernel/signal.c @@ -51,27 +51,6 @@ #define lock_lbt_owner() ({ preempt_disable(); pagefault_disable(); }) #define unlock_lbt_owner() ({ pagefault_enable(); preempt_enable(); })
-/* Assembly functions to move context to/from the FPU */ -extern asmlinkage int -_save_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); -extern asmlinkage int -_restore_fp_context(void __user *fpregs, void __user *fcc, void __user *csr); -extern asmlinkage int -_save_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); -extern asmlinkage int -_restore_lsx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); -extern asmlinkage int -_save_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); -extern asmlinkage int -_restore_lasx_context(void __user *fpregs, void __user *fcc, void __user *fcsr); - -#ifdef CONFIG_CPU_HAS_LBT -extern asmlinkage int _save_lbt_context(void __user *regs, void __user *eflags); -extern asmlinkage int _restore_lbt_context(void __user *regs, void __user *eflags); -extern asmlinkage int _save_ftop_context(void __user *ftop); -extern asmlinkage int _restore_ftop_context(void __user *ftop); -#endif - struct rt_sigframe { struct siginfo rs_info; struct ucontext rs_uctx;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Wang wangming01@loongson.cn
commit bd51834d1cf65a2c801295d230c220aeebf87a73 upstream.
LoongArch's huge_pte_offset() currently returns a pointer to a PMD slot even if the underlying entry points to invalid_pte_table (indicating no mapping). Callers like smaps_hugetlb_range() fetch this invalid entry value (the address of invalid_pte_table) via this pointer.
The generic is_swap_pte() check then incorrectly identifies this address as a swap entry on LoongArch, because it satisfies the "!pte_present() && !pte_none()" conditions. This misinterpretation, combined with a coincidental match by is_migration_entry() on the address bits, leads to kernel crashes in pfn_swap_entry_to_page().
Fix this at the architecture level by modifying huge_pte_offset() to check the PMD entry's content using pmd_none() before returning. If the entry is invalid (i.e., it points to invalid_pte_table), return NULL instead of the pointer to the slot.
Cc: stable@vger.kernel.org Acked-by: Peter Xu peterx@redhat.com Co-developed-by: Hongchen Zhang zhanghongchen@loongson.cn Signed-off-by: Hongchen Zhang zhanghongchen@loongson.cn Signed-off-by: Ming Wang wangming01@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/mm/hugetlbpage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/loongarch/mm/hugetlbpage.c +++ b/arch/loongarch/mm/hugetlbpage.c @@ -47,7 +47,7 @@ pte_t *huge_pte_offset(struct mm_struct pmd = pmd_offset(pud, addr); } } - return (pte_t *) pmd; + return pmd_none(pmdp_get(pmd)) ? NULL : (pte_t *) pmd; }
uint64_t pmd_to_entrylo(unsigned long pmd_val)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Tesarik ptesarik@suse.com
commit c37325cbd91abe3bfab280b3b09947155abe8e07 upstream.
Remove dead code. LoongArch does not have a DMA memory zone (24bit DMA). The architecture does not even define MAX_DMA_PFN.
Cc: stable@vger.kernel.org Reviewed-by: Mike Rapoport (Microsoft) rppt@kernel.org Signed-off-by: Petr Tesarik ptesarik@suse.com Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/mm/init.c | 3 --- 1 file changed, 3 deletions(-)
--- a/arch/loongarch/mm/init.c +++ b/arch/loongarch/mm/init.c @@ -65,9 +65,6 @@ void __init paging_init(void) { unsigned long max_zone_pfns[MAX_NR_ZONES];
-#ifdef CONFIG_ZONE_DMA - max_zone_pfns[ZONE_DMA] = MAX_DMA_PFN; -#endif #ifdef CONFIG_ZONE_DMA32 max_zone_pfns[ZONE_DMA32] = MAX_DMA32_PFN; #endif
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yulong Han wheatfox17@icloud.com
commit 8b2d01fec800081dd68271c01e4d239ef4d7115e upstream.
Fix multiple typos inside arch/loongarch/kvm.
Cc: stable@vger.kernel.org Reviewed-by: Yuli Wang wangyuli@uniontech.com Reviewed-by: Bibo Mao maobibo@loongson.cn Signed-off-by: Yulong Han wheatfox17@icloud.com Signed-off-by: Huacai Chen chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/loongarch/kvm/intc/ipi.c | 4 ++-- arch/loongarch/kvm/main.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
--- a/arch/loongarch/kvm/intc/ipi.c +++ b/arch/loongarch/kvm/intc/ipi.c @@ -111,7 +111,7 @@ static int send_ipi_data(struct kvm_vcpu ret = kvm_io_bus_read(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); srcu_read_unlock(&vcpu->kvm->srcu, idx); if (unlikely(ret)) { - kvm_err("%s: : read date from addr %llx failed\n", __func__, addr); + kvm_err("%s: : read data from addr %llx failed\n", __func__, addr); return ret; } /* Construct the mask by scanning the bit 27-30 */ @@ -127,7 +127,7 @@ static int send_ipi_data(struct kvm_vcpu ret = kvm_io_bus_write(vcpu, KVM_IOCSR_BUS, addr, sizeof(val), &val); srcu_read_unlock(&vcpu->kvm->srcu, idx); if (unlikely(ret)) - kvm_err("%s: : write date to addr %llx failed\n", __func__, addr); + kvm_err("%s: : write data to addr %llx failed\n", __func__, addr);
return ret; } --- a/arch/loongarch/kvm/main.c +++ b/arch/loongarch/kvm/main.c @@ -296,10 +296,10 @@ int kvm_arch_enable_virtualization_cpu(v /* * Enable virtualization features granting guest direct control of * certain features: - * GCI=2: Trap on init or unimplement cache instruction. + * GCI=2: Trap on init or unimplemented cache instruction. * TORU=0: Trap on Root Unimplement. * CACTRL=1: Root control cache. - * TOP=0: Trap on Previlege. + * TOP=0: Trap on Privilege. * TOE=0: Trap on Exception. * TIT=0: Trap on Timer. */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit 9ea86232a5520d9d21832d06031ea80f055a6ff8 upstream.
Some registers such as LOONGARCH_CSR_ESTAT and LOONGARCH_CSR_GINTC are partly cleared with function _kvm_setcsr(). This comes from the hardware specification, some bits are read only in VM mode, and however they can be written in host mode. So they are partly cleared in VM mode, and can be fully cleared in host mode.
These read only bits show pending interrupt or exception status. When VM reset, the read-only bits should be cleared, otherwise vCPU will receive unknown interrupts in boot stage.
Here registers LOONGARCH_CSR_ESTAT/LOONGARCH_CSR_GINTC are fully cleared in ioctl KVM_REG_LOONGARCH_VCPU_RESET vCPU reset path.
Cc: stable@vger.kernel.org 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/vcpu.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -874,6 +874,13 @@ static int kvm_set_one_reg(struct kvm_vc vcpu->arch.st.guest_addr = 0; memset(&vcpu->arch.irq_pending, 0, sizeof(vcpu->arch.irq_pending)); memset(&vcpu->arch.irq_clear, 0, sizeof(vcpu->arch.irq_clear)); + + /* + * When vCPU reset, clear the ESTAT and GINTC registers + * Other CSR registers are cleared with function _kvm_setcsr(). + */ + kvm_write_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_GINTC, 0); + kvm_write_sw_gcsr(vcpu->arch.csr, LOONGARCH_CSR_ESTAT, 0); break; default: ret = -EINVAL;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bibo Mao maobibo@loongson.cn
commit 5add0dbbebd60628b55e5eb8426612dedab7311a upstream.
In function kvm_pre_enter_guest(), it prepares to enter guest and check whether there are pending signals or events. And it will not enter guest if there are, PMU pass-through preparation for guest should be cancelled and host should own PMU hardware.
Cc: stable@vger.kernel.org Fixes: f4e40ea9f78f ("LoongArch: KVM: Add PMU support for guest") 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/vcpu.c | 1 + 1 file changed, 1 insertion(+)
--- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -294,6 +294,7 @@ static int kvm_pre_enter_guest(struct kv vcpu->arch.aux_inuse &= ~KVM_LARCH_SWCSR_LATEST;
if (kvm_request_pending(vcpu) || xfer_to_guest_mode_work_pending()) { + kvm_lose_pmu(vcpu); /* make sure the vcpu mode has been written */ smp_store_mb(vcpu->mode, OUTSIDE_GUEST_MODE); local_irq_enable();
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe axboe@kernel.dk
commit edd43f4d6f50ec3de55a0c9e9df6348d1da51965 upstream.
A previous commit added a 'sync' parameter to io_fallback_tw(), which if true, means the caller wants to wait on the fallback thread handling it. But the logic is somewhat messed up, ensure that ctxs are swapped and flushed appropriately.
Cc: stable@vger.kernel.org Fixes: dfbe5561ae93 ("io_uring: flush offloaded and delayed task_work on exit") Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- io_uring/io_uring.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
--- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1080,21 +1080,22 @@ static __cold void __io_fallback_tw(stru while (node) { req = container_of(node, struct io_kiocb, io_task_work.node); node = node->next; - if (sync && last_ctx != req->ctx) { + if (last_ctx != req->ctx) { if (last_ctx) { - flush_delayed_work(&last_ctx->fallback_work); + if (sync) + flush_delayed_work(&last_ctx->fallback_work); percpu_ref_put(&last_ctx->refs); } last_ctx = req->ctx; percpu_ref_get(&last_ctx->refs); } - if (llist_add(&req->io_task_work.node, - &req->ctx->fallback_llist)) - schedule_delayed_work(&req->ctx->fallback_work, 1); + if (llist_add(&req->io_task_work.node, &last_ctx->fallback_llist)) + schedule_delayed_work(&last_ctx->fallback_work, 1); }
if (last_ctx) { - flush_delayed_work(&last_ctx->fallback_work); + if (sync) + flush_delayed_work(&last_ctx->fallback_work); percpu_ref_put(&last_ctx->refs); } }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson seanjc@google.com
commit 7537deda36521fa8fff9133b39c46e31893606f2 upstream.
Allocate SVM's interrupt remapping metadata using GFP_ATOMIC as svm_ir_list_add() is called with IRQs are disabled and irqfs.lock held when kvm_irq_routing_update() reacts to GSI routing changes.
Fixes: 411b44ba80ab ("svm: Implements update_pi_irte hook to setup posted interrupt") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-ID: 20250404193923.1413163-2-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/svm/avic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -820,7 +820,7 @@ static int svm_ir_list_add(struct vcpu_s * Allocating new amd_iommu_pi_data, which will get * add to the per-vcpu ir_list. */ - ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_KERNEL_ACCOUNT); + ir = kzalloc(sizeof(struct amd_svm_iommu_ir), GFP_ATOMIC | __GFP_ACCOUNT); if (!ir) { ret = -ENOMEM; goto out;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Smita Koralahalli Smita.KoralahalliChannabasappa@amd.com
commit 078d3ee7c162cd66d76171579c02d7890bd77daf upstream.
According to CXL r3.2 section 8.2.1.2, the PCI_COMMAND register fields, including Memory Space Enable bit, have no effect on the behavior of an RCD Upstream Port. Retaining this check may incorrectly cause cxl_pci_probe() to fail on a valid RCD upstream Port.
While the specification is explicit only for RCD Upstream Ports, this check is solely for accessing the RCRB, which is always mapped through memory space. Therefore, its safe to remove the check entirely. In practice, firmware reliably enables the Memory Space Enable bit for RCH Downstream Ports and no failures have been observed.
Removing the check simplifies the code and avoids unnecessary special-casing, while relying on BIOS/firmware to configure devices correctly. Moreover, any failures due to inaccessible RCRB regions will still be caught either in __rcrb_to_component() or while parsing the component register block.
The following failure was observed in dmesg when the check was present: cxl_pci 0000:7f:00.0: No component registers (-6)
Fixes: d5b1a27143cb ("cxl/acpi: Extract component registers of restricted hosts from RCRB") Signed-off-by: Smita Koralahalli Smita.KoralahalliChannabasappa@amd.com Cc: stable@vger.kernel.org Reviewed-by: Ira Weiny ira.weiny@intel.com Reviewed-by: Terry Bowman terry.bowman@amd.com Reviewed-by: Dave Jiang dave.jiang@intel.com Reviewed-by: Robert Richter rrichter@amd.com Link: https://patch.msgid.link/20250407192734.70631-1-Smita.KoralahalliChannabasap... Signed-off-by: Dave Jiang dave.jiang@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/cxl/core/regs.c | 4 ---- 1 file changed, 4 deletions(-)
--- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -581,7 +581,6 @@ resource_size_t __rcrb_to_component(stru resource_size_t rcrb = ri->base; void __iomem *addr; u32 bar0, bar1; - u16 cmd; u32 id;
if (which == CXL_RCRB_UPSTREAM) @@ -603,7 +602,6 @@ resource_size_t __rcrb_to_component(stru }
id = readl(addr + PCI_VENDOR_ID); - cmd = readw(addr + PCI_COMMAND); bar0 = readl(addr + PCI_BASE_ADDRESS_0); bar1 = readl(addr + PCI_BASE_ADDRESS_1); iounmap(addr); @@ -618,8 +616,6 @@ resource_size_t __rcrb_to_component(stru dev_err(dev, "Failed to access Downstream Port RCRB\n"); return CXL_RESOURCE_NONE; } - if (!(cmd & PCI_COMMAND_MEMORY)) - return CXL_RESOURCE_NONE; /* The RCRB is a Memory Window, and the MEM_TYPE_1M bit is obsolete */ if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO)) return CXL_RESOURCE_NONE;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li haoxiang_li2024@163.com
commit 7c7f1bfdb2249f854a736d9b79778c7e5a29a150 upstream.
In chameleon_parse_gdd(), if mcb_device_register() fails, 'mdev' would be released in mcb_device_register() via put_device(). Thus, goto 'err' label and free 'mdev' again causes a double free. Just return if mcb_device_register() fails.
Fixes: 3764e82e5150 ("drivers: Introduce MEN Chameleon Bus") Cc: stable stable@kernel.org Signed-off-by: Haoxiang Li haoxiang_li2024@163.com Signed-off-by: Johannes Thumshirn jth@kernel.org Link: https://lore.kernel.org/r/6201d09e2975ae5789879f79a6de4c38de9edd4a.174159622... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/mcb/mcb-parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/mcb/mcb-parse.c +++ b/drivers/mcb/mcb-parse.c @@ -96,7 +96,7 @@ static int chameleon_parse_gdd(struct mc
ret = mcb_device_register(bus, mdev); if (ret < 0) - goto err; + return ret;
return 0;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal dlemoal@kernel.org
commit 17e897a456752ec9c2d7afb3d9baf268b442451b upstream.
With ATA devices supporting the CDL feature, using CDL requires that the feature be enabled with a SET FEATURES command. This command is issued as the translated command for the MODE SELECT command issued by scsi_cdl_enable() when the user enables CDL through the device cdl_enable sysfs attribute.
Currently, ata_mselect_control_ata_feature() always translates a MODE SELECT command for the ATA features subpage of the control mode page to a SET FEATURES command to enable or disable CDL based on the cdl_ctrl field. However, there is no need to issue the SET FEATURES command if: 1) The MODE SELECT command requests disabling CDL and CDL is already disabled. 2) The MODE SELECT command requests enabling CDL and CDL is already enabled.
Fix ata_mselect_control_ata_feature() to issue the SET FEATURES command only when necessary. Since enabling CDL also implies a reset of the CDL statistics log page, avoiding useless CDL enable operations also avoids clearing the CDL statistics log.
Also add debug messages to clearly signal when CDL is being enabled or disabled using a SET FEATURES command.
Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal dlemoal@kernel.org Reviewed-by: Niklas Cassel cassel@kernel.org Reviewed-by: Igor Pylypiv ipylypiv@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-scsi.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
--- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3909,17 +3909,27 @@ static unsigned int ata_mselect_control_ /* Check cdl_ctrl */ switch (buf[0] & 0x03) { case 0: - /* Disable CDL */ + /* Disable CDL if it is enabled */ + if (!(dev->flags & ATA_DFLAG_CDL_ENABLED)) + return 0; + ata_dev_dbg(dev, "Disabling CDL\n"); cdl_action = 0; dev->flags &= ~ATA_DFLAG_CDL_ENABLED; break; case 0x02: - /* Enable CDL T2A/T2B: NCQ priority must be disabled */ + /* + * Enable CDL if not already enabled. Since this is mutually + * exclusive with NCQ priority, allow this only if NCQ priority + * is disabled. + */ + if (dev->flags & ATA_DFLAG_CDL_ENABLED) + return 0; if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) { ata_dev_err(dev, "NCQ priority must be disabled to enable CDL\n"); return -EINVAL; } + ata_dev_dbg(dev, "Enabling CDL\n"); cdl_action = 1; dev->flags |= ATA_DFLAG_CDL_ENABLED; break;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal dlemoal@kernel.org
commit db91586b1e8f36122a9e5b8fbced11741488dd22 upstream.
The function ata_mselect_control_ata_feature() has a return type defined as unsigned int but this function may return negative error codes, which are correctly propagated up the call chain as integers.
Fix ata_mselect_control_ata_feature() to have the correct int return type.
While at it, also fix a typo in this function description comment.
Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal dlemoal@kernel.org Reviewed-by: Niklas Cassel cassel@kernel.org Reviewed-by: Igor Pylypiv ipylypiv@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-scsi.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
--- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -3886,12 +3886,11 @@ static int ata_mselect_control_spg0(stru }
/* - * Translate MODE SELECT control mode page, sub-pages f2h (ATA feature mode + * Translate MODE SELECT control mode page, sub-page f2h (ATA feature mode * page) into a SET FEATURES command. */ -static unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, - const u8 *buf, int len, - u16 *fp) +static int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, + const u8 *buf, int len, u16 *fp) { struct ata_device *dev = qc->dev; struct ata_taskfile *tf = &qc->tf;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal dlemoal@kernel.org
commit 88474ad734fb2000805c63e01cc53ea930adf2c7 upstream.
For the ATA features subpage of the control mode page, the T10 SAT-6 specifications state that:
For a MODE SENSE command, the SATL shall return the CDL_CTRL field value that was last set by an application client.
However, the function ata_msense_control_ata_feature() always sets the CDL_CTRL field to the 0x02 value to indicate support for the CDL T2A and T2B pages. This is thus incorrect and the value 0x02 must be reported only after the user enables the CDL feature, which is indicated with the ATA_DFLAG_CDL_ENABLED device flag. When this flag is not set, the CDL_CTRL field of the ATA feature subpage of the control mode page must report a value of 0x00.
Fix ata_msense_control_ata_feature() to report the correct values for the CDL_CTRL field, according to the enable/disable state of the device CDL feature.
Fixes: df60f9c64576 ("scsi: ata: libata: Add ATA feature control sub-page translation") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal dlemoal@kernel.org Reviewed-by: Niklas Cassel cassel@kernel.org Reviewed-by: Igor Pylypiv ipylypiv@google.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/ata/libata-scsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2453,8 +2453,8 @@ static unsigned int ata_msense_control_a */ put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]);
- if (dev->flags & ATA_DFLAG_CDL) - buf[4] = 0x02; /* Support T2A and T2B pages */ + if (dev->flags & ATA_DFLAG_CDL_ENABLED) + buf[4] = 0x02; /* T2A and T2B pages enabled */ else buf[4] = 0;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
commit 9ab75eee1a056f896b87d139044dd103adc532b9 upstream.
Version 1.60 specifically needs this quirk. Version 2.00 is known good.
Cc: stable stable@kernel.org Signed-off-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/20250403180004.343133-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/storage/unusual_uas.h | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/usb/storage/unusual_uas.h +++ b/drivers/usb/storage/unusual_uas.h @@ -83,6 +83,13 @@ UNUSUAL_DEV(0x0bc2, 0x331a, 0x0000, 0x99 USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_REPORT_LUNS),
+/* Reported-by: Oliver Neukum oneukum@suse.com */ +UNUSUAL_DEV(0x125f, 0xa94a, 0x0160, 0x0160, + "ADATA", + "Portable HDD CH94", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_NO_ATA_1X), + /* Reported-by: Benjamin Tissoires benjamin.tissoires@redhat.com */ UNUSUAL_DEV(0x13fd, 0x3940, 0x0000, 0x9999, "Initio Corporation",
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal dlemoal@kernel.org
commit 14a3cc755825ef7b34c986aa2786ea815023e9c5 upstream.
With ATA devices supporting the CDL feature, using CDL requires that the feature be enabled with a SET FEATURES command. This command is issued as the translated command for the MODE SELECT command issued by scsi_cdl_enable() when the user enables CDL through the device cdl_enable sysfs attribute.
However, the implementation of scsi_cdl_enable() always issues a MODE SELECT command for ATA devices when the enable argument is true, even if CDL is already enabled on the device. While this does not cause any issue with using CDL descriptors with read/write commands (the CDL feature will be enabled on the drive), issuing the MODE SELECT command even when the device CDL feature is already enabled will cause a reset of the ATA device CDL statistics log page (as defined in ACS, any CDL enable action must reset the device statistics).
Avoid this needless actions (and the implied statistics log page reset) by modifying scsi_cdl_enable() to issue the MODE SELECT command to enable CDL if and only if CDL is not reported as already enabled on the device.
And while at it, simplify the initialization of the is_ata boolean variable and move the declaration of the scsi mode data and sense header variables to within the scope of ATA device handling.
Fixes: 1b22cfb14142 ("scsi: core: Allow enabling and disabling command duration limits") Cc: stable@vger.kernel.org Signed-off-by: Damien Le Moal dlemoal@kernel.org Reviewed-by: Niklas Cassel cassel@kernel.org Reviewed-by: Igor Pylypiv ipylypiv@google.com Reviewed-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/scsi/scsi.c | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-)
--- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -695,26 +695,23 @@ void scsi_cdl_check(struct scsi_device * */ int scsi_cdl_enable(struct scsi_device *sdev, bool enable) { - struct scsi_mode_data data; - struct scsi_sense_hdr sshdr; - struct scsi_vpd *vpd; - bool is_ata = false; char buf[64]; + bool is_ata; int ret;
if (!sdev->cdl_supported) return -EOPNOTSUPP;
rcu_read_lock(); - vpd = rcu_dereference(sdev->vpd_pg89); - if (vpd) - is_ata = true; + is_ata = rcu_dereference(sdev->vpd_pg89); rcu_read_unlock();
/* * For ATA devices, CDL needs to be enabled with a SET FEATURES command. */ if (is_ata) { + struct scsi_mode_data data; + struct scsi_sense_hdr sshdr; char *buf_data; int len;
@@ -723,16 +720,30 @@ int scsi_cdl_enable(struct scsi_device * if (ret) return -EINVAL;
- /* Enable CDL using the ATA feature page */ + /* Enable or disable CDL using the ATA feature page */ len = min_t(size_t, sizeof(buf), data.length - data.header_length - data.block_descriptor_length); buf_data = buf + data.header_length + data.block_descriptor_length; - if (enable) - buf_data[4] = 0x02; - else - buf_data[4] = 0; + + /* + * If we want to enable CDL and CDL is already enabled on the + * device, do nothing. This avoids needlessly resetting the CDL + * statistics on the device as that is implied by the CDL enable + * action. Similar to this, there is no need to do anything if + * we want to disable CDL and CDL is already disabled. + */ + if (enable) { + if ((buf_data[4] & 0x03) == 0x02) + goto out; + buf_data[4] &= ~0x03; + buf_data[4] |= 0x02; + } else { + if ((buf_data[4] & 0x03) == 0x00) + goto out; + buf_data[4] &= ~0x03; + }
ret = scsi_mode_select(sdev, 1, 0, buf_data, len, 5 * HZ, 3, &data, &sshdr); @@ -744,6 +755,7 @@ int scsi_cdl_enable(struct scsi_device * } }
+out: sdev->cdl_enable = enable;
return 0;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Usyskin alexander.usyskin@intel.com
commit 86ce5c0a1dec02e21b4c864b2bc0cc5880a2c13c upstream.
Add Panther Lake H device id.
Cc: stable stable@kernel.org Co-developed-by: Tomas Winkler tomasw@gmail.com Signed-off-by: Tomas Winkler tomasw@gmail.com Signed-off-by: Alexander Usyskin alexander.usyskin@intel.com Link: https://lore.kernel.org/r/20250408130005.1358140-1-alexander.usyskin@intel.c... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/mei/hw-me-regs.h | 1 + drivers/misc/mei/pci-me.c | 1 + 2 files changed, 2 insertions(+)
--- a/drivers/misc/mei/hw-me-regs.h +++ b/drivers/misc/mei/hw-me-regs.h @@ -117,6 +117,7 @@
#define MEI_DEV_ID_LNL_M 0xA870 /* Lunar Lake Point M */
+#define MEI_DEV_ID_PTL_H 0xE370 /* Panther Lake H */ #define MEI_DEV_ID_PTL_P 0xE470 /* Panther Lake P */
/* --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -124,6 +124,7 @@ static const struct pci_device_id mei_me
{MEI_PCI_DEVICE(MEI_DEV_ID_LNL_M, MEI_ME_PCH15_CFG)},
+ {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_H, MEI_ME_PCH15_CFG)}, {MEI_PCI_DEVICE(MEI_DEV_ID_PTL_P, MEI_ME_PCH15_CFG)},
/* required last entry */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
commit 00f1cc14da0f06d2897b8c528df7c7dcf1b8da50 upstream.
gcc 15 honors the __counted_by(len) attribute on vsc_tp_packet.buf[] and the vsc-tp.c code is using this in a wrong way. len does not contain the available size in the buffer, it contains the actual packet length *without* the crc. So as soon as vsc_tp_xfer() tries to add the crc to buf[] the fortify-panic handler gets triggered:
[ 80.842193] memcpy: detected buffer overflow: 4 byte write of buffer size 0 [ 80.842243] WARNING: CPU: 4 PID: 272 at lib/string_helpers.c:1032 __fortify_report+0x45/0x50 ... [ 80.843175] __fortify_panic+0x9/0xb [ 80.843186] vsc_tp_xfer.cold+0x67/0x67 [mei_vsc_hw] [ 80.843210] ? seqcount_lockdep_reader_access.constprop.0+0x82/0x90 [ 80.843229] ? lockdep_hardirqs_on+0x7c/0x110 [ 80.843250] mei_vsc_hw_start+0x98/0x120 [mei_vsc] [ 80.843270] mei_reset+0x11d/0x420 [mei]
The easiest fix would be to just drop the counted-by but with the exception of the ack buffer in vsc_tp_xfer_helper() which only contains enough room for the packet-header, all other uses of vsc_tp_packet always use a buffer of VSC_TP_MAX_XFER_SIZE bytes for the packet.
Instead of just dropping the counted-by, split the vsc_tp_packet struct definition into a header and a full-packet definition and use a fixed size buf[] in the packet definition, this way fortify-source buffer overrun checking still works when enabled.
Fixes: 566f5ca97680 ("mei: Add transport driver for IVSC device") Cc: stable@kernel.org Signed-off-by: Hans de Goede hdegoede@redhat.com Reviewed-by: Alexander Usyskin alexander.usyskin@intel.com Reviewed-by: Sakari Ailus sakari.ailus@linux.intel.com Link: https://lore.kernel.org/r/20250318141203.94342-2-hdegoede@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/mei/vsc-tp.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-)
--- a/drivers/misc/mei/vsc-tp.c +++ b/drivers/misc/mei/vsc-tp.c @@ -36,20 +36,24 @@ #define VSC_TP_XFER_TIMEOUT_BYTES 700 #define VSC_TP_PACKET_PADDING_SIZE 1 #define VSC_TP_PACKET_SIZE(pkt) \ - (sizeof(struct vsc_tp_packet) + le16_to_cpu((pkt)->len) + VSC_TP_CRC_SIZE) + (sizeof(struct vsc_tp_packet_hdr) + le16_to_cpu((pkt)->hdr.len) + VSC_TP_CRC_SIZE) #define VSC_TP_MAX_PACKET_SIZE \ - (sizeof(struct vsc_tp_packet) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE) + (sizeof(struct vsc_tp_packet_hdr) + VSC_TP_MAX_MSG_SIZE + VSC_TP_CRC_SIZE) #define VSC_TP_MAX_XFER_SIZE \ (VSC_TP_MAX_PACKET_SIZE + VSC_TP_XFER_TIMEOUT_BYTES) #define VSC_TP_NEXT_XFER_LEN(len, offset) \ - (len + sizeof(struct vsc_tp_packet) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE) + (len + sizeof(struct vsc_tp_packet_hdr) + VSC_TP_CRC_SIZE - offset + VSC_TP_PACKET_PADDING_SIZE)
-struct vsc_tp_packet { +struct vsc_tp_packet_hdr { __u8 sync; __u8 cmd; __le16 len; __le32 seq; - __u8 buf[] __counted_by(len); +}; + +struct vsc_tp_packet { + struct vsc_tp_packet_hdr hdr; + __u8 buf[VSC_TP_MAX_XFER_SIZE - sizeof(struct vsc_tp_packet_hdr)]; };
struct vsc_tp { @@ -158,12 +162,12 @@ static int vsc_tp_dev_xfer(struct vsc_tp static int vsc_tp_xfer_helper(struct vsc_tp *tp, struct vsc_tp_packet *pkt, void *ibuf, u16 ilen) { - int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet); + int ret, offset = 0, cpy_len, src_len, dst_len = sizeof(struct vsc_tp_packet_hdr); int next_xfer_len = VSC_TP_PACKET_SIZE(pkt) + VSC_TP_XFER_TIMEOUT_BYTES; u8 *src, *crc_src, *rx_buf = tp->rx_buf; int count_down = VSC_TP_MAX_XFER_COUNT; u32 recv_crc = 0, crc = ~0; - struct vsc_tp_packet ack; + struct vsc_tp_packet_hdr ack; u8 *dst = (u8 *)&ack; bool synced = false;
@@ -280,10 +284,10 @@ int vsc_tp_xfer(struct vsc_tp *tp, u8 cm
guard(mutex)(&tp->mutex);
- pkt->sync = VSC_TP_PACKET_SYNC; - pkt->cmd = cmd; - pkt->len = cpu_to_le16(olen); - pkt->seq = cpu_to_le32(++tp->seq); + pkt->hdr.sync = VSC_TP_PACKET_SYNC; + pkt->hdr.cmd = cmd; + pkt->hdr.len = cpu_to_le16(olen); + pkt->hdr.seq = cpu_to_le32(++tp->seq); memcpy(pkt->buf, obuf, olen);
crc = ~crc32(~0, (u8 *)pkt, sizeof(pkt) + olen);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson seanjc@google.com
commit bcda70c56f3e718465cab2aad260cf34183ce1ce upstream.
Explicitly treat type differences as GSI routing changes, as comparing MSI data between two entries could get a false negative, e.g. if userspace changed the type but left the type-specific data as-is.
Fixes: 515a0c79e796 ("kvm: irqfd: avoid update unmodified entries of the routing") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-ID: 20250404193923.1413163-4-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -13611,7 +13611,8 @@ int kvm_arch_update_irqfd_routing(struct bool kvm_arch_irqfd_route_changed(struct kvm_kernel_irq_routing_entry *old, struct kvm_kernel_irq_routing_entry *new) { - if (new->type != KVM_IRQ_ROUTING_MSI) + if (old->type != KVM_IRQ_ROUTING_MSI || + new->type != KVM_IRQ_ROUTING_MSI) return true;
return !!memcmp(&old->msi, &new->msi, sizeof(new->msi));
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson seanjc@google.com
commit 9bcac97dc42d2f4da8229d18feb0fe2b1ce523a2 upstream.
Restore an IRTE back to host control (remapped or posted MSI mode) if the *new* GSI route prevents posting the IRQ directly to a vCPU, regardless of the GSI routing type. Updating the IRTE if and only if the new GSI is an MSI results in KVM leaving an IRTE posting to a vCPU.
The dangling IRTE can result in interrupts being incorrectly delivered to the guest, and in the worst case scenario can result in use-after-free, e.g. if the VM is torn down, but the underlying host IRQ isn't freed.
Fixes: efc644048ecd ("KVM: x86: Update IRTE for posted-interrupts") Fixes: 411b44ba80ab ("svm: Implements update_pi_irte hook to setup posted interrupt") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-ID: 20250404193923.1413163-3-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/svm/avic.c | 58 +++++++++++++++++++++-------------------- arch/x86/kvm/vmx/posted_intr.c | 28 +++++++------------ 2 files changed, 41 insertions(+), 45 deletions(-)
--- a/arch/x86/kvm/svm/avic.c +++ b/arch/x86/kvm/svm/avic.c @@ -896,6 +896,7 @@ int avic_pi_update_irte(struct kvm *kvm, { struct kvm_kernel_irq_routing_entry *e; struct kvm_irq_routing_table *irq_rt; + bool enable_remapped_mode = true; int idx, ret = 0;
if (!kvm_arch_has_assigned_device(kvm) || @@ -933,6 +934,8 @@ int avic_pi_update_irte(struct kvm *kvm, kvm_vcpu_apicv_active(&svm->vcpu)) { struct amd_iommu_pi_data pi;
+ enable_remapped_mode = false; + /* Try to enable guest_mode in IRTE */ pi.base = __sme_set(page_to_phys(svm->avic_backing_page) & AVIC_HPA_MASK); @@ -951,33 +954,6 @@ int avic_pi_update_irte(struct kvm *kvm, */ if (!ret && pi.is_guest_mode) svm_ir_list_add(svm, &pi); - } else { - /* Use legacy mode in IRTE */ - struct amd_iommu_pi_data pi; - - /** - * Here, pi is used to: - * - Tell IOMMU to use legacy mode for this interrupt. - * - Retrieve ga_tag of prior interrupt remapping data. - */ - pi.prev_ga_tag = 0; - pi.is_guest_mode = false; - ret = irq_set_vcpu_affinity(host_irq, &pi); - - /** - * Check if the posted interrupt was previously - * setup with the guest_mode by checking if the ga_tag - * was cached. If so, we need to clean up the per-vcpu - * ir_list. - */ - if (!ret && pi.prev_ga_tag) { - int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag); - struct kvm_vcpu *vcpu; - - vcpu = kvm_get_vcpu_by_id(kvm, id); - if (vcpu) - svm_ir_list_del(to_svm(vcpu), &pi); - } }
if (!ret && svm) { @@ -993,6 +969,34 @@ int avic_pi_update_irte(struct kvm *kvm, }
ret = 0; + if (enable_remapped_mode) { + /* Use legacy mode in IRTE */ + struct amd_iommu_pi_data pi; + + /** + * Here, pi is used to: + * - Tell IOMMU to use legacy mode for this interrupt. + * - Retrieve ga_tag of prior interrupt remapping data. + */ + pi.prev_ga_tag = 0; + pi.is_guest_mode = false; + ret = irq_set_vcpu_affinity(host_irq, &pi); + + /** + * Check if the posted interrupt was previously + * setup with the guest_mode by checking if the ga_tag + * was cached. If so, we need to clean up the per-vcpu + * ir_list. + */ + if (!ret && pi.prev_ga_tag) { + int id = AVIC_GATAG_TO_VCPUID(pi.prev_ga_tag); + struct kvm_vcpu *vcpu; + + vcpu = kvm_get_vcpu_by_id(kvm, id); + if (vcpu) + svm_ir_list_del(to_svm(vcpu), &pi); + } + } out: srcu_read_unlock(&kvm->irq_srcu, idx); return ret; --- a/arch/x86/kvm/vmx/posted_intr.c +++ b/arch/x86/kvm/vmx/posted_intr.c @@ -274,6 +274,7 @@ int vmx_pi_update_irte(struct kvm *kvm, { struct kvm_kernel_irq_routing_entry *e; struct kvm_irq_routing_table *irq_rt; + bool enable_remapped_mode = true; struct kvm_lapic_irq irq; struct kvm_vcpu *vcpu; struct vcpu_data vcpu_info; @@ -312,21 +313,8 @@ int vmx_pi_update_irte(struct kvm *kvm,
kvm_set_msi_irq(kvm, e, &irq); if (!kvm_intr_is_single_vcpu(kvm, &irq, &vcpu) || - !kvm_irq_is_postable(&irq)) { - /* - * Make sure the IRTE is in remapped mode if - * we don't handle it in posted mode. - */ - ret = irq_set_vcpu_affinity(host_irq, NULL); - if (ret < 0) { - printk(KERN_INFO - "failed to back to remapped mode, irq: %u\n", - host_irq); - goto out; - } - + !kvm_irq_is_postable(&irq)) continue; - }
vcpu_info.pi_desc_addr = __pa(vcpu_to_pi_desc(vcpu)); vcpu_info.vector = irq.vector; @@ -334,11 +322,12 @@ int vmx_pi_update_irte(struct kvm *kvm, trace_kvm_pi_irte_update(host_irq, vcpu->vcpu_id, e->gsi, vcpu_info.vector, vcpu_info.pi_desc_addr, set);
- if (set) - ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); - else - ret = irq_set_vcpu_affinity(host_irq, NULL); + if (!set) + continue;
+ enable_remapped_mode = false; + + ret = irq_set_vcpu_affinity(host_irq, &vcpu_info); if (ret < 0) { printk(KERN_INFO "%s: failed to update PI IRTE\n", __func__); @@ -346,6 +335,9 @@ int vmx_pi_update_irte(struct kvm *kvm, } }
+ if (enable_remapped_mode) + ret = irq_set_vcpu_affinity(host_irq, NULL); + ret = 0; out: srcu_read_unlock(&kvm->irq_srcu, idx);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson seanjc@google.com
commit f1fb088d9cecde5c3066d8ff8846789667519b7d upstream.
Take irqfds.lock when adding/deleting an IRQ bypass producer to ensure irqfd->producer isn't modified while kvm_irq_routing_update() is running. The only lock held when a producer is added/removed is irqbypass's mutex.
Fixes: 872768800652 ("KVM: x86: select IRQ_BYPASS_MANAGER") Cc: stable@vger.kernel.org Signed-off-by: Sean Christopherson seanjc@google.com Message-ID: 20250404193923.1413163-5-seanjc@google.com Signed-off-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/x86/kvm/x86.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
--- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -13565,15 +13565,22 @@ int kvm_arch_irq_bypass_add_producer(str { struct kvm_kernel_irqfd *irqfd = container_of(cons, struct kvm_kernel_irqfd, consumer); + struct kvm *kvm = irqfd->kvm; int ret;
- irqfd->producer = prod; kvm_arch_start_assignment(irqfd->kvm); + + spin_lock_irq(&kvm->irqfds.lock); + irqfd->producer = prod; + ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, prod->irq, irqfd->gsi, 1); if (ret) kvm_arch_end_assignment(irqfd->kvm);
+ spin_unlock_irq(&kvm->irqfds.lock); + + return ret; }
@@ -13583,9 +13590,9 @@ void kvm_arch_irq_bypass_del_producer(st int ret; struct kvm_kernel_irqfd *irqfd = container_of(cons, struct kvm_kernel_irqfd, consumer); + struct kvm *kvm = irqfd->kvm;
WARN_ON(irqfd->producer != prod); - irqfd->producer = NULL;
/* * When producer of consumer is unregistered, we change back to @@ -13593,12 +13600,18 @@ void kvm_arch_irq_bypass_del_producer(st * when the irq is masked/disabled or the consumer side (KVM * int this case doesn't want to receive the interrupts. */ + spin_lock_irq(&kvm->irqfds.lock); + irqfd->producer = NULL; + ret = kvm_x86_call(pi_update_irte)(irqfd->kvm, prod->irq, irqfd->gsi, 0); if (ret) printk(KERN_INFO "irq bypass consumer (token %p) unregistration" " fails: %d\n", irqfd->consumer.token, ret);
+ spin_unlock_irq(&kvm->irqfds.lock); + + kvm_arch_end_assignment(irqfd->kvm); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thadeu Lima de Souza Cascardo cascardo@igalia.com
commit c876be906ce7e518d9ef9926478669c151999e69 upstream.
register_chrdev will only register the first 256 minors of a major chrdev. That means that dynamically allocated misc devices with minor above 255 will fail to open with -ENXIO.
This was found by kernel test robot when testing a different change that makes all dynamically allocated minors be above 255. This has, however, been separately tested by creating 256 serio_raw devices with the help of userio driver.
Ever since allowing misc devices with minors above 128, this has been possible.
Fix it by registering all minor numbers from 0 to MINORMASK + 1 for MISC_MAJOR.
Reported-by: kernel test robot oliver.sang@intel.com Cc: stable stable@kernel.org Closes: https://lore.kernel.org/oe-lkp/202503171507.6c8093d0-lkp@intel.com Fixes: ab760791c0cf ("char: misc: Increase the maximum number of dynamic misc devices to 1048448") Signed-off-by: Thadeu Lima de Souza Cascardo cascardo@igalia.com Tested-by: Hou Wenlong houwenlong.hwl@antgroup.com Link: https://lore.kernel.org/r/20250317-misc-chrdev-v1-1-6cd05da11aef@igalia.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/char/misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -315,7 +315,7 @@ static int __init misc_init(void) goto fail_remove;
err = -EIO; - if (register_chrdev(MISC_MAJOR, "misc", &misc_fops)) + if (__register_chrdev(MISC_MAJOR, 0, MINORMASK + 1, "misc", &misc_fops)) goto fail_printk; return 0;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rengarajan S rengarajan.s@microchip.com
commit 18eb77c75ed01439f96ae5c0f33461eb5134b907 upstream.
Resolve kernel panic while accessing IRQ handler associated with the generated IRQ. This is done by acquiring the spinlock and storing the current interrupt state before handling the interrupt request using generic_handle_irq.
A previous fix patch was submitted where 'generic_handle_irq' was replaced with 'handle_nested_irq'. However, this change also causes the kernel panic where after determining which GPIO triggered the interrupt and attempting to call handle_nested_irq with the mapped IRQ number, leads to a failure in locating the registered handler.
Fixes: 194f9f94a516 ("misc: microchip: pci1xxxx: Resolve kernel panic during GPIO IRQ handling") Cc: stable stable@kernel.org Signed-off-by: Rengarajan S rengarajan.s@microchip.com Link: https://lore.kernel.org/r/20250313170856.20868-2-rengarajan.s@microchip.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c +++ b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c @@ -37,6 +37,7 @@ struct pci1xxxx_gpio { struct auxiliary_device *aux_dev; void __iomem *reg_base; + raw_spinlock_t wa_lock; struct gpio_chip gpio; spinlock_t lock; int irq_base; @@ -257,6 +258,7 @@ static irqreturn_t pci1xxxx_gpio_irq_han struct pci1xxxx_gpio *priv = dev_id; struct gpio_chip *gc = &priv->gpio; unsigned long int_status = 0; + unsigned long wa_flags; unsigned long flags; u8 pincount; int bit; @@ -280,7 +282,9 @@ static irqreturn_t pci1xxxx_gpio_irq_han writel(BIT(bit), priv->reg_base + INTR_STATUS_OFFSET(gpiobank)); spin_unlock_irqrestore(&priv->lock, flags); irq = irq_find_mapping(gc->irq.domain, (bit + (gpiobank * 32))); - handle_nested_irq(irq); + raw_spin_lock_irqsave(&priv->wa_lock, wa_flags); + generic_handle_irq(irq); + raw_spin_unlock_irqrestore(&priv->wa_lock, wa_flags); } } spin_lock_irqsave(&priv->lock, flags);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rengarajan S rengarajan.s@microchip.com
commit e9d7748a7468581859d2b85b378135f9688a0aff upstream.
Under irq_ack, pci1xxxx_assign_bit reads the current interrupt status, modifies and writes the entire value back. Since, the IRQ status bit gets cleared on writing back, the better approach is to directly write the bitmask to the register in order to preserve the value.
Fixes: 1f4d8ae231f4 ("misc: microchip: pci1xxxx: Add gpio irq handler and irq helper functions irq_ack, irq_mask, irq_unmask and irq_set_type of irq_chip.") Cc: stable stable@kernel.org Signed-off-by: Rengarajan S rengarajan.s@microchip.com Link: https://lore.kernel.org/r/20250313170856.20868-3-rengarajan.s@microchip.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c +++ b/drivers/misc/mchp_pci1xxxx/mchp_pci1xxxx_gpio.c @@ -168,7 +168,7 @@ static void pci1xxxx_gpio_irq_ack(struct unsigned long flags;
spin_lock_irqsave(&priv->lock, flags); - pci1xxx_assign_bit(priv->reg_base, INTR_STAT_OFFSET(gpio), (gpio % 32), true); + writel(BIT(gpio % 32), priv->reg_base + INTR_STAT_OFFSET(gpio)); spin_unlock_irqrestore(&priv->lock, flags); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mahesh Rao mahesh.rao@intel.com
commit 4d239f447f96bd2cb646f89431e9db186c1ccfd4 upstream.
Add of_platform_default_populate() to stratix10-svc driver as the firmware/svc node was moved out of soc. This fixes the failed probing of child drivers of svc node.
Cc: stable@vger.kernel.org Fixes: 23c3ebed382a ("arm64: dts: socfpga: agilex: move firmware out of soc node") Reviewed-by: Krzysztof Kozlowski krzysztof.kozlowski@linaro.org Reviewed-by: Xu Yilun yilun.xu@intel.com Signed-off-by: Mahesh Rao mahesh.rao@intel.com Signed-off-by: Dinh Nguyen dinguyen@kernel.org Link: https://lore.kernel.org/r/20250326115446.36123-1-dinguyen@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/firmware/stratix10-svc.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
--- a/drivers/firmware/stratix10-svc.c +++ b/drivers/firmware/stratix10-svc.c @@ -1224,22 +1224,28 @@ static int stratix10_svc_drv_probe(struc if (!svc->intel_svc_fcs) { dev_err(dev, "failed to allocate %s device\n", INTEL_FCS); ret = -ENOMEM; - goto err_unregister_dev; + goto err_unregister_rsu_dev; }
ret = platform_device_add(svc->intel_svc_fcs); if (ret) { platform_device_put(svc->intel_svc_fcs); - goto err_unregister_dev; + goto err_unregister_rsu_dev; }
+ ret = of_platform_default_populate(dev_of_node(dev), NULL, dev); + if (ret) + goto err_unregister_fcs_dev; + dev_set_drvdata(dev, svc);
pr_info("Intel Service Layer Driver Initialized\n");
return 0;
-err_unregister_dev: +err_unregister_fcs_dev: + platform_device_unregister(svc->intel_svc_fcs); +err_unregister_rsu_dev: platform_device_unregister(svc->stratix10_svc_rsu); err_free_kfifo: kfifo_free(&controller->svc_fifo); @@ -1253,6 +1259,8 @@ static void stratix10_svc_drv_remove(str struct stratix10_svc *svc = dev_get_drvdata(&pdev->dev); struct stratix10_svc_controller *ctrl = platform_get_drvdata(pdev);
+ of_platform_depopulate(ctrl->dev); + platform_device_unregister(svc->intel_svc_fcs); platform_device_unregister(svc->stratix10_svc_rsu);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Günther Noack gnoack3000@gmail.com
commit ee6a44da3c87cf64d67dd02be8c0127a5bf56175 upstream.
This requirement was overeagerly loosened in commit 2f83e38a095f ("tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN"), but as it turns out,
(1) the logic I implemented there was inconsistent (apologies!),
(2) TIOCL_SELMOUSEREPORT might actually be a small security risk after all, and
(3) TIOCL_SELMOUSEREPORT is only meant to be used by the mouse daemon (GPM or Consolation), which runs as CAP_SYS_ADMIN already.
In more detail:
1. The previous patch has inconsistent logic:
In commit 2f83e38a095f ("tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN"), we checked for sel_mode == TIOCL_SELMOUSEREPORT, but overlooked that the lower four bits of this "mode" parameter were actually used as an additional way to pass an argument. So the patch did actually still require CAP_SYS_ADMIN, if any of the mouse button bits are set, but did not require it if none of the mouse buttons bits are set.
This logic is inconsistent and was not intentional. We should have the same policies for using TIOCL_SELMOUSEREPORT independent of the value of the "hidden" mouse button argument.
I sent a separate documentation patch to the man page list with more details on TIOCL_SELMOUSEREPORT: https://lore.kernel.org/all/20250223091342.35523-2-gnoack3000@gmail.com/
2. TIOCL_SELMOUSEREPORT is indeed a potential security risk which can let an attacker simulate "keyboard" input to command line applications on the same terminal, like TIOCSTI and some other TIOCLINUX "selection mode" IOCTLs.
By enabling mouse reporting on a terminal and then injecting mouse reports through TIOCL_SELMOUSEREPORT, an attacker can simulate mouse movements on the same terminal, similar to the TIOCSTI keystroke injection attacks that were previously possible with TIOCSTI and other TIOCL_SETSEL selection modes.
Many programs (including libreadline/bash) are then prone to misinterpret these mouse reports as normal keyboard input because they do not expect input in the X11 mouse protocol form. The attacker does not have complete control over the escape sequence, but they can at least control the values of two consecutive bytes in the binary mouse reporting escape sequence.
I went into more detail on that in the discussion at https://lore.kernel.org/all/20250221.0a947528d8f3@gnoack.org/
It is not equally trivial to simulate arbitrary keystrokes as it was with TIOCSTI (commit 83efeeeb3d04 ("tty: Allow TIOCSTI to be disabled")), but the general mechanism is there, and together with the small number of existing legit use cases (see below), it would be better to revert back to requiring CAP_SYS_ADMIN for TIOCL_SELMOUSEREPORT, as it was already the case before commit 2f83e38a095f ("tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN").
3. TIOCL_SELMOUSEREPORT is only used by the mouse daemons (GPM or Consolation), and they are the only legit use case:
To quote console_codes(4):
The mouse tracking facility is intended to return xterm(1)-compatible mouse status reports. Because the console driver has no way to know the device or type of the mouse, these reports are returned in the console input stream only when the virtual terminal driver receives a mouse update ioctl. These ioctls must be generated by a mouse-aware user-mode application such as the gpm(8) daemon.
Jared Finder has also confirmed in https://lore.kernel.org/all/491f3df9de6593df8e70dbe77614b026@finder.org/ that Emacs does not call TIOCL_SELMOUSEREPORT directly, and it would be difficult to find good reasons for doing that, given that it would interfere with the reports that GPM is sending.
More information on the interaction between GPM, terminals and the kernel with additional pointers is also available in this patch: https://lore.kernel.org/all/a773e48920aa104a65073671effbdee665c105fc.1603963...
For background on who else uses TIOCL_SELMOUSEREPORT: Debian Code search finds one page of results, the only two known callers are the two mouse daemons GPM and Consolation. (GPM does not show up in the search results because it uses literal numbers to refer to TIOCLINUX-related enums. I looked through GPM by hand instead. TIOCL_SELMOUSEREPORT is also not used from libgpm.) https://codesearch.debian.net/search?q=TIOCL_SELMOUSEREPORT
Cc: Jared Finder jared@finder.org Cc: Jann Horn jannh@google.com Cc: Hanno Böck hanno@hboeck.de Cc: Jiri Slaby jirislaby@kernel.org Cc: Kees Cook kees@kernel.org Cc: stable stable@kernel.org Fixes: 2f83e38a095f ("tty: Permit some TIOCL_SETSEL modes without CAP_SYS_ADMIN") Signed-off-by: Günther Noack gnoack3000@gmail.com Link: https://lore.kernel.org/r/20250411070144.3959-2-gnoack3000@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/vt/selection.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/tty/vt/selection.c +++ b/drivers/tty/vt/selection.c @@ -193,13 +193,12 @@ int set_selection_user(const struct tioc return -EFAULT;
/* - * TIOCL_SELCLEAR, TIOCL_SELPOINTER and TIOCL_SELMOUSEREPORT are OK to - * use without CAP_SYS_ADMIN as they do not modify the selection. + * TIOCL_SELCLEAR and TIOCL_SELPOINTER are OK to use without + * CAP_SYS_ADMIN as they do not modify the selection. */ switch (v.sel_mode) { case TIOCL_SELCLEAR: case TIOCL_SELPOINTER: - case TIOCL_SELMOUSEREPORT: break; default: if (!capable(CAP_SYS_ADMIN))
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stephan Gerhold stephan.gerhold@linaro.org
commit 7094832b5ac861b0bd7ed8866c93cb15ef619996 upstream.
The MSM UART DM controller supports different working modes, e.g. DMA or the "single-character mode", where all reads/writes operate on a single character rather than 4 chars (32-bit) at once. When using earlycon, __msm_console_write() always writes 4 characters at a time, but we don't know which mode the bootloader was using and we don't set the mode either.
This causes garbled output if the bootloader was using the single-character mode, because only every 4th character appears in the serial console, e.g.
"[ 00oni pi 000xf0[ 00i s 5rm9(l)l s 1 1 SPMTA 7:C 5[ 00A ade k d[ 00ano:ameoi .Q1B[ 00ac _idaM00080oo'"
If the bootloader was using the DMA ("DM") mode, output would likely fail entirely. Later, when the full serial driver probes, the port is re-initialized and output works as expected.
Fix this also for earlycon by clearing the DMEN register and reset+re-enable the transmitter to apply the change. This ensures the transmitter is in the expected state before writing any output.
Cc: stable stable@kernel.org Fixes: 0efe72963409 ("tty: serial: msm: Add earlycon support") Signed-off-by: Stephan Gerhold stephan.gerhold@linaro.org Reviewed-by: Neil Armstrong neil.armstrong@linaro.org Link: https://lore.kernel.org/r/20250408-msm-serial-earlycon-v1-1-429080127530@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/msm_serial.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/tty/serial/msm_serial.c +++ b/drivers/tty/serial/msm_serial.c @@ -1746,6 +1746,12 @@ msm_serial_early_console_setup_dm(struct if (!device->port.membase) return -ENODEV;
+ /* Disable DM / single-character modes */ + msm_write(&device->port, 0, UARTDM_DMEN); + msm_write(&device->port, MSM_UART_CR_CMD_RESET_RX, MSM_UART_CR); + msm_write(&device->port, MSM_UART_CR_CMD_RESET_TX, MSM_UART_CR); + msm_write(&device->port, MSM_UART_CR_TX_ENABLE, MSM_UART_CR); + device->con->write = msm_serial_early_write_dm; return 0; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryo Takakura ryotkkr98@gmail.com
commit e1ca3ff28ab1e2c1e70713ef3fa7943c725742c3 upstream.
startup()/shutdown() callbacks access SIFIVE_SERIAL_IE_OFFS. The register is also accessed from write() callback.
If console were printing and startup()/shutdown() callback gets called, its access to the register could be overwritten.
Add port->lock to startup()/shutdown() callbacks to make sure their access to SIFIVE_SERIAL_IE_OFFS is synchronized against write() callback.
Fixes: 45c054d0815b ("tty: serial: add driver for the SiFive UART") Signed-off-by: Ryo Takakura ryotkkr98@gmail.com Reviewed-by: Petr Mladek pmladek@suse.com Cc: stable@vger.kernel.org Reviewed-by: John Ogness john.ogness@linutronix.de Rule: add Link: https://lore.kernel.org/stable/20250330003522.386632-1-ryotkkr98%40gmail.com Link: https://lore.kernel.org/r/20250412001847.183221-1-ryotkkr98@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/tty/serial/sifive.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/tty/serial/sifive.c +++ b/drivers/tty/serial/sifive.c @@ -563,8 +563,11 @@ static void sifive_serial_break_ctl(stru static int sifive_serial_startup(struct uart_port *port) { struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); + unsigned long flags;
+ uart_port_lock_irqsave(&ssp->port, &flags); __ssp_enable_rxwm(ssp); + uart_port_unlock_irqrestore(&ssp->port, flags);
return 0; } @@ -572,9 +575,12 @@ static int sifive_serial_startup(struct static void sifive_serial_shutdown(struct uart_port *port) { struct sifive_serial_port *ssp = port_to_sifive_serial_port(port); + unsigned long flags;
+ uart_port_lock_irqsave(&ssp->port, &flags); __ssp_disable_rxwm(ssp); __ssp_disable_txwm(ssp); + uart_port_unlock_irqrestore(&ssp->port, flags); }
/**
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Ehrenreich michideep@gmail.com
commit b399078f882b6e5d32da18b6c696cc84b12f90d5 upstream.
Abacus Electrics makes optical probes for interacting with smart meters over an optical interface.
At least one version uses an FT232B chip (as detected by ftdi_sio) with a custom USB PID, which needs to be added to the list to make the device work in a plug-and-play fashion.
Signed-off-by: Michael Ehrenreich michideep@gmail.com Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio_ids.h | 5 +++++ 2 files changed, 7 insertions(+)
--- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1093,6 +1093,8 @@ static const struct usb_device_id id_tab { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 1) }, { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 2) }, { USB_DEVICE_INTERFACE_NUMBER(ALTERA_VID, ALTERA_UB3_602E_PID, 3) }, + /* Abacus Electrics */ + { USB_DEVICE(FTDI_VID, ABACUS_OPTICAL_PROBE_PID) }, { } /* Terminating entry */ };
--- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h @@ -443,6 +443,11 @@ #define LINX_FUTURE_2_PID 0xF44C /* Linx future device */
/* + * Abacus Electrics + */ +#define ABACUS_OPTICAL_PROBE_PID 0xf458 /* ABACUS ELECTRICS Optical Probe */ + +/* * Oceanic product ids */ #define FTDI_OCEANIC_PID 0xF460 /* Oceanic dive instrument */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Xue zxue@semtech.com
commit 968e1cbb1f6293c3add9607f80b5ce3d29f57583 upstream.
Add Sierra Wireless EM9291.
Interface 0: MBIM control 1: MBIM data 3: AT port 4: Diagnostic port
T: Bus=01 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 2 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=1199 ProdID=90e3 Rev=00.06 S: Manufacturer=Sierra Wireless, Incorporated S: Product=Sierra Wireless EM9291 S: SerialNumber=xxxxxxxxxxxxxxxx C: #Ifs= 4 Cfg#= 1 Atr=a0 MxPwr=500mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I: If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=(none) E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms I: If#= 4 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=(none) E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Signed-off-by: Adam Xue zxue@semtech.com Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -611,6 +611,7 @@ static void option_instat_callback(struc /* Sierra Wireless products */ #define SIERRA_VENDOR_ID 0x1199 #define SIERRA_PRODUCT_EM9191 0x90d3 +#define SIERRA_PRODUCT_EM9291 0x90e3
/* UNISOC (Spreadtrum) products */ #define UNISOC_VENDOR_ID 0x1782 @@ -2432,6 +2433,8 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x30) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9191, 0xff, 0, 0) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x30) }, + { USB_DEVICE_AND_INTERFACE_INFO(SIERRA_VENDOR_ID, SIERRA_PRODUCT_EM9291, 0xff, 0xff, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, TOZED_PRODUCT_LT70C, 0xff, 0, 0) }, { USB_DEVICE_AND_INTERFACE_INFO(UNISOC_VENDOR_ID, LUAT_PRODUCT_AIR720U, 0xff, 0, 0) }, { USB_DEVICE_INTERFACE_CLASS(0x1bbb, 0x0530, 0xff), /* TCL IK512 MBIM */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Craig Hesling craig@hesling.com
commit 4cc01410e1c1dd075df10f750775c81d1cb6672b upstream.
Add serial support for OWON HDS200 series oscilloscopes and likely many other pieces of OWON test equipment.
OWON HDS200 series devices host two USB endpoints, designed to facilitate bidirectional SCPI. SCPI is a predominately ASCII text protocol for test/measurement equipment. Having a serial/tty interface for these devices lowers the barrier to entry for anyone trying to write programs to communicate with them.
The following shows the USB descriptor for the OWON HDS272S running firmware V5.7.1:
Bus 001 Device 068: ID 5345:1234 Owon PDS6062T Oscilloscope Negotiated speed: Full Speed (12Mbps) Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 [unknown] bDeviceSubClass 0 [unknown] bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x5345 Owon idProduct 0x1234 PDS6062T Oscilloscope bcdDevice 1.00 iManufacturer 1 oscilloscope iProduct 2 oscilloscope iSerial 3 oscilloscope bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x0029 bNumInterfaces 1 bConfigurationValue 1 iConfiguration 0 bmAttributes 0x80 (Bus Powered) MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 2 bInterfaceClass 5 Physical Interface Device bInterfaceSubClass 0 [unknown] bInterfaceProtocol 0 iInterface 0 ** UNRECOGNIZED: 09 21 11 01 00 01 22 5f 00 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 32 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bmAttributes 2 Transfer Type Bulk Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 32 Device Status: 0x0000 (Bus Powered)
OWON appears to be using the same USB Vendor and Product ID for many of their oscilloscopes. Looking at the discussion about the USB vendor/product ID, in the link bellow, suggests that this VID/PID is shared with VDS, SDS, PDS, and now the HDS series oscilloscopes. Available documentation for these devices seems to indicate that all use a similar SCPI protocol, some with RS232 options. It is likely that this same simple serial setup would work correctly for them all.
Link: https://usb-ids.gowdy.us/read/UD/5345/1234 Signed-off-by: Craig Hesling craig@hesling.com Cc: stable@vger.kernel.org Signed-off-by: Johan Hovold johan@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/serial/usb-serial-simple.c | 7 +++++++ 1 file changed, 7 insertions(+)
--- a/drivers/usb/serial/usb-serial-simple.c +++ b/drivers/usb/serial/usb-serial-simple.c @@ -100,6 +100,11 @@ DEVICE(nokia, NOKIA_IDS); { USB_DEVICE(0x09d7, 0x0100) } /* NovAtel FlexPack GPS */ DEVICE_N(novatel_gps, NOVATEL_IDS, 3);
+/* OWON electronic test and measurement equipment driver */ +#define OWON_IDS() \ + { USB_DEVICE(0x5345, 0x1234) } /* HDS200 oscilloscopes and others */ +DEVICE(owon, OWON_IDS); + /* Siemens USB/MPI adapter */ #define SIEMENS_IDS() \ { USB_DEVICE(0x908, 0x0004) } @@ -134,6 +139,7 @@ static struct usb_serial_driver * const &motorola_tetra_device, &nokia_device, &novatel_gps_device, + &owon_device, &siemens_mpi_device, &suunto_device, &vivopay_device, @@ -153,6 +159,7 @@ static const struct usb_device_id id_tab MOTOROLA_TETRA_IDS(), NOKIA_IDS(), NOVATEL_IDS(), + OWON_IDS(), SIEMENS_IDS(), SUUNTO_IDS(), VIVOPAY_IDS(),
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman mathias.nyman@linux.intel.com
commit bea5892d0ed274e03655223d1977cf59f9aff2f2 upstream.
Current xhci bus resume implementation prevents xHC host from generating interrupts during high-speed USB 2 and super-speed USB 3 bus resume.
Only reason to disable interrupts during bus resume would be to prevent the interrupt handler from interfering with the resume process of USB 2 ports.
Host initiated resume of USB 2 ports is done in two stages.
The xhci driver first transitions the port from 'U3' to 'Resume' state, then wait in Resume for 20ms, and finally moves port to U0 state. xhci driver can't prevent interrupts by keeping the xhci spinlock due to this 20ms sleep.
Limit interrupt disabling to the USB 2 port resume case only. resuming USB 2 ports in bus resume is only done in special cases where USB 2 ports had to be forced to suspend during bus suspend.
The current way of preventing interrupts by clearing the 'Interrupt Enable' (INTE) bit in USBCMD register won't prevent the Interrupter registers 'Interrupt Pending' (IP), 'Event Handler Busy' (EHB) and USBSTS register Event Interrupt (EINT) bits from being set.
New interrupts can't be issued before those bits are properly clered.
Disable interrupts by clearing the interrupter register 'Interrupt Enable' (IE) bit instead. This way IP, EHB and INTE won't be set before IE is enabled again and a new interrupt is triggered.
Reported-by: Devyn Liu liudingyuan@huawei.com Closes: https://lore.kernel.org/linux-usb/b1a9e2d51b4d4ff7a304f77c5be8164e@huawei.co... Cc: stable@vger.kernel.org Tested-by: Devyn Liu liudingyuan@huawei.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20250410151828.2868740-6-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-hub.c | 30 ++++++++++++++++-------------- drivers/usb/host/xhci.c | 4 ++-- drivers/usb/host/xhci.h | 2 ++ 3 files changed, 20 insertions(+), 16 deletions(-)
--- a/drivers/usb/host/xhci-hub.c +++ b/drivers/usb/host/xhci-hub.c @@ -1878,9 +1878,10 @@ int xhci_bus_resume(struct usb_hcd *hcd) int max_ports, port_index; int sret; u32 next_state; - u32 temp, portsc; + u32 portsc; struct xhci_hub *rhub; struct xhci_port **ports; + bool disabled_irq = false;
rhub = xhci_get_rhub(hcd); ports = rhub->ports; @@ -1896,17 +1897,20 @@ int xhci_bus_resume(struct usb_hcd *hcd) return -ESHUTDOWN; }
- /* delay the irqs */ - temp = readl(&xhci->op_regs->command); - temp &= ~CMD_EIE; - writel(temp, &xhci->op_regs->command); - /* bus specific resume for ports we suspended at bus_suspend */ - if (hcd->speed >= HCD_USB3) + if (hcd->speed >= HCD_USB3) { next_state = XDEV_U0; - else + } else { next_state = XDEV_RESUME; - + if (bus_state->bus_suspended) { + /* + * prevent port event interrupts from interfering + * with usb2 port resume process + */ + xhci_disable_interrupter(xhci->interrupters[0]); + disabled_irq = true; + } + } port_index = max_ports; while (port_index--) { portsc = readl(ports[port_index]->addr); @@ -1974,11 +1978,9 @@ int xhci_bus_resume(struct usb_hcd *hcd) (void) readl(&xhci->op_regs->command);
bus_state->next_statechange = jiffies + msecs_to_jiffies(5); - /* re-enable irqs */ - temp = readl(&xhci->op_regs->command); - temp |= CMD_EIE; - writel(temp, &xhci->op_regs->command); - temp = readl(&xhci->op_regs->command); + /* re-enable interrupter */ + if (disabled_irq) + xhci_enable_interrupter(xhci->interrupters[0]);
spin_unlock_irqrestore(&xhci->lock, flags); return 0; --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -322,7 +322,7 @@ static void xhci_zero_64b_regs(struct xh xhci_info(xhci, "Fault detected\n"); }
-static int xhci_enable_interrupter(struct xhci_interrupter *ir) +int xhci_enable_interrupter(struct xhci_interrupter *ir) { u32 iman;
@@ -335,7 +335,7 @@ static int xhci_enable_interrupter(struc return 0; }
-static int xhci_disable_interrupter(struct xhci_interrupter *ir) +int xhci_disable_interrupter(struct xhci_interrupter *ir) { u32 iman;
--- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1890,6 +1890,8 @@ int xhci_alloc_tt_info(struct xhci_hcd * struct usb_tt *tt, gfp_t mem_flags); int xhci_set_interrupter_moderation(struct xhci_interrupter *ir, u32 imod_interval); +int xhci_enable_interrupter(struct xhci_interrupter *ir); +int xhci_disable_interrupter(struct xhci_interrupter *ir);
/* xHCI ring, segment, TRB, and TD functions */ dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio michal.pecio@gmail.com
commit 1ea050da5562af9b930d17cbbe9632d30f5df43a upstream.
This check is performed before prepare_transfer() and prepare_ring(), so enqueue can already point at the final link TRB of a segment. And indeed it will, some 0.4% of times this code is called.
Then enqueue + 1 is an invalid pointer. It will crash the kernel right away or load some junk which may look like a link TRB and cause the real link TRB to be replaced with a NOOP. This wouldn't end well.
Use a functionally equivalent test which doesn't dereference the pointer and always gives correct result.
Something has crashed my machine twice in recent days while playing with an Etron HC, and a control transfer stress test ran for confirmation has just crashed it again. The same test passes with this patch applied.
Fixes: 5e1c67abc930 ("xhci: Fix control transfer error on Etron xHCI host") Cc: stable@vger.kernel.org Signed-off-by: Michal Pecio michal.pecio@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Reviewed-by: Kuangyi Chiang ki.chiang65@gmail.com Link: https://lore.kernel.org/r/20250410151828.2868740-5-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -3780,7 +3780,7 @@ int xhci_queue_ctrl_tx(struct xhci_hcd * * enqueue a No Op TRB, this can prevent the Setup and Data Stage * TRB to be breaked by the Link TRB. */ - if (trb_is_link(ep_ring->enqueue + 1)) { + if (last_trb_on_seg(ep_ring->enq_seg, ep_ring->enqueue + 1)) { field = TRB_TYPE(TRB_TR_NOOP) | ep_ring->cycle_state; queue_trb(xhci, ep_ring, false, 0, 0, TRB_INTR_TARGET(0), field);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ralph Siemsen ralph.siemsen@linaro.org
commit a1059896f2bfdcebcdc7153c3be2307ea319501f upstream.
The cdns3 driver has the same NCM deadlock as fixed in cdnsp by commit 58f2fcb3a845 ("usb: cdnsp: Fix deadlock issue during using NCM gadget").
Under PREEMPT_RT the deadlock can be readily triggered by heavy network traffic, for example using "iperf --bidir" over NCM ethernet link.
The deadlock occurs because the threaded interrupt handler gets preempted by a softirq, but both are protected by the same spinlock. Prevent deadlock by disabling softirq during threaded irq handler.
Cc: stable stable@kernel.org Fixes: 7733f6c32e36 ("usb: cdns3: Add Cadence USB3 DRD Driver") Signed-off-by: Ralph Siemsen ralph.siemsen@linaro.org Acked-by: Peter Chen peter.chen@kernel.org Reviewed-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Link: https://lore.kernel.org/r/20250318-rfs-cdns3-deadlock-v2-1-bfd9cfcee732@lina... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/cdns3/cdns3-gadget.c | 2 ++ 1 file changed, 2 insertions(+)
--- a/drivers/usb/cdns3/cdns3-gadget.c +++ b/drivers/usb/cdns3/cdns3-gadget.c @@ -1963,6 +1963,7 @@ static irqreturn_t cdns3_device_thread_i unsigned int bit; unsigned long reg;
+ local_bh_disable(); spin_lock_irqsave(&priv_dev->lock, flags);
reg = readl(&priv_dev->regs->usb_ists); @@ -2004,6 +2005,7 @@ static irqreturn_t cdns3_device_thread_i irqend: writel(~0, &priv_dev->regs->ep_ien); spin_unlock_irqrestore(&priv_dev->lock, flags); + local_bh_enable();
return ret; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin pchelkin@ispras.ru
commit 4e28f79e3dffa52d327b46d1a78dac16efb5810b upstream.
usbmisc is an optional device property so it is totally valid for the corresponding data->usbmisc_data to have a NULL value.
Check that before dereferencing the pointer.
Found by Linux Verification Center (linuxtesting.org) with Svace static analysis tool.
Fixes: 74adad500346 ("usb: chipidea: ci_hdrc_imx: decrement device's refcount in .remove() and in the error path of .probe()") Cc: stable stable@kernel.org Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Acked-by: Peter Chen peter.chen@kernel.org Link: https://lore.kernel.org/r/20250316102658.490340-2-pchelkin@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/chipidea/ci_hdrc_imx.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -534,7 +534,8 @@ disable_hsic_regulator: cpu_latency_qos_remove_request(&data->pm_qos_req); data->ci_pdev = NULL; err_put: - put_device(data->usbmisc_data->dev); + if (data->usbmisc_data) + put_device(data->usbmisc_data->dev); return ret; }
@@ -559,7 +560,8 @@ static void ci_hdrc_imx_remove(struct pl if (data->hsic_pad_regulator) regulator_disable(data->hsic_pad_regulator); } - put_device(data->usbmisc_data->dev); + if (data->usbmisc_data) + put_device(data->usbmisc_data->dev); }
static void ci_hdrc_imx_shutdown(struct platform_device *pdev)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin pchelkin@ispras.ru
commit 8cab0e9a3f3e8d700179e0d6141643d54a267fd5 upstream.
Upon encountering errors during the HSIC pinctrl handling section the regulator should be disabled.
Use devm_add_action_or_reset() to let the regulator-disabling routine be handled by device resource management stack.
Found by Linux Verification Center (linuxtesting.org).
Fixes: 4d6141288c33 ("usb: chipidea: imx: pinctrl for HSIC is optional") Cc: stable stable@kernel.org Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Acked-by: Peter Chen peter.chen@kernel.org Link: https://lore.kernel.org/r/20250316102658.490340-3-pchelkin@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/chipidea/ci_hdrc_imx.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-)
--- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -336,6 +336,13 @@ static int ci_hdrc_imx_notify_event(stru return ret; }
+static void ci_hdrc_imx_disable_regulator(void *arg) +{ + struct ci_hdrc_imx_data *data = arg; + + regulator_disable(data->hsic_pad_regulator); +} + static int ci_hdrc_imx_probe(struct platform_device *pdev) { struct ci_hdrc_imx_data *data; @@ -394,6 +401,13 @@ static int ci_hdrc_imx_probe(struct plat "Failed to enable HSIC pad regulator\n"); goto err_put; } + ret = devm_add_action_or_reset(dev, + ci_hdrc_imx_disable_regulator, data); + if (ret) { + dev_err(dev, + "Failed to add regulator devm action\n"); + goto err_put; + } } }
@@ -432,11 +446,11 @@ static int ci_hdrc_imx_probe(struct plat
ret = imx_get_clks(dev); if (ret) - goto disable_hsic_regulator; + goto qos_remove_request;
ret = imx_prepare_enable_clks(dev); if (ret) - goto disable_hsic_regulator; + goto qos_remove_request;
ret = clk_prepare_enable(data->clk_wakeup); if (ret) @@ -526,10 +540,7 @@ err_clk: clk_disable_unprepare(data->clk_wakeup); err_wakeup_clk: imx_disable_unprepare_clks(dev); -disable_hsic_regulator: - if (data->hsic_pad_regulator) - /* don't overwrite original ret (cf. EPROBE_DEFER) */ - regulator_disable(data->hsic_pad_regulator); +qos_remove_request: if (pdata.flags & CI_HDRC_PMQOS) cpu_latency_qos_remove_request(&data->pm_qos_req); data->ci_pdev = NULL; @@ -557,8 +568,6 @@ static void ci_hdrc_imx_remove(struct pl clk_disable_unprepare(data->clk_wakeup); if (data->plat_data->flags & CI_HDRC_PMQOS) cpu_latency_qos_remove_request(&data->pm_qos_req); - if (data->hsic_pad_regulator) - regulator_disable(data->hsic_pad_regulator); } if (data->usbmisc_data) put_device(data->usbmisc_data->dev);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fedor Pchelkin pchelkin@ispras.ru
commit 8c531e0a8c2d82509ad97c6d3a1e6217c7ed136d upstream.
usb_phy_init() may return an error code if e.g. its implementation fails to prepare/enable some clocks. And properly rollback on probe error path by calling the counterpart usb_phy_shutdown().
Found by Linux Verification Center (linuxtesting.org).
Fixes: be9cae2479f4 ("usb: chipidea: imx: Fix ULPI on imx53") Cc: stable stable@kernel.org Signed-off-by: Fedor Pchelkin pchelkin@ispras.ru Acked-by: Peter Chen peter.chen@kernel.org Link: https://lore.kernel.org/r/20250316102658.490340-4-pchelkin@ispras.ru Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/chipidea/ci_hdrc_imx.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)
--- a/drivers/usb/chipidea/ci_hdrc_imx.c +++ b/drivers/usb/chipidea/ci_hdrc_imx.c @@ -484,7 +484,11 @@ static int ci_hdrc_imx_probe(struct plat of_usb_get_phy_mode(np) == USBPHY_INTERFACE_MODE_ULPI) { pdata.flags |= CI_HDRC_OVERRIDE_PHY_CONTROL; data->override_phy_control = true; - usb_phy_init(pdata.usb_phy); + ret = usb_phy_init(pdata.usb_phy); + if (ret) { + dev_err(dev, "Failed to init phy\n"); + goto err_clk; + } }
if (pdata.flags & CI_HDRC_SUPPORTS_RUNTIME_PM) @@ -493,7 +497,7 @@ static int ci_hdrc_imx_probe(struct plat ret = imx_usbmisc_init(data->usbmisc_data); if (ret) { dev_err(dev, "usbmisc init failed, ret=%d\n", ret); - goto err_clk; + goto phy_shutdown; }
data->ci_pdev = ci_hdrc_add_device(dev, @@ -502,7 +506,7 @@ static int ci_hdrc_imx_probe(struct plat if (IS_ERR(data->ci_pdev)) { ret = PTR_ERR(data->ci_pdev); dev_err_probe(dev, ret, "ci_hdrc_add_device failed\n"); - goto err_clk; + goto phy_shutdown; }
if (data->usbmisc_data) { @@ -536,6 +540,9 @@ static int ci_hdrc_imx_probe(struct plat
disable_device: ci_hdrc_remove_device(data->ci_pdev); +phy_shutdown: + if (data->override_phy_control) + usb_phy_shutdown(data->phy); err_clk: clk_disable_unprepare(data->clk_wakeup); err_wakeup_clk:
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huacai Chen chenhuacai@loongson.cn
commit bcb60d438547355b8f9ad48645909139b64d3482 upstream.
The OHCI controller (rev 0x02) under LS7A PCI host has a hardware flaw. MMIO register with offset 0x60/0x64 is treated as legacy PS2-compatible keyboard/mouse interface, which confuse the OHCI controller. Since OHCI only use a 4KB BAR resource indeed, the LS7A OHCI controller's 32KB BAR is wrapped around (the second 4KB BAR space is the same as the first 4KB internally). So we can add an 4KB offset (0x1000) to the OHCI registers (from the PCI BAR resource) as a quirk.
Cc: stable stable@kernel.org Suggested-by: Bjorn Helgaas bhelgaas@google.com Reviewed-by: Alan Stern stern@rowland.harvard.edu Tested-by: Mingcong Bai baimingcong@loongson.cn Signed-off-by: Huacai Chen chenhuacai@loongson.cn Link: https://lore.kernel.org/r/20250328040059.3672979-1-chenhuacai@loongson.cn Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/ohci-pci.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
--- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c @@ -165,6 +165,25 @@ static int ohci_quirk_amd700(struct usb_ return 0; }
+static int ohci_quirk_loongson(struct usb_hcd *hcd) +{ + struct pci_dev *pdev = to_pci_dev(hcd->self.controller); + + /* + * Loongson's LS7A OHCI controller (rev 0x02) has a + * flaw. MMIO register with offset 0x60/64 is treated + * as legacy PS2-compatible keyboard/mouse interface. + * Since OHCI only use 4KB BAR resource, LS7A OHCI's + * 32KB BAR is wrapped around (the 2nd 4KB BAR space + * is the same as the 1st 4KB internally). So add 4KB + * offset (0x1000) to the OHCI registers as a quirk. + */ + if (pdev->revision == 0x2) + hcd->regs += SZ_4K; /* SZ_4K = 0x1000 */ + + return 0; +} + static int ohci_quirk_qemu(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); @@ -225,6 +244,10 @@ static const struct pci_device_id ohci_p .driver_data = (unsigned long)ohci_quirk_amd700, }, { + PCI_DEVICE(PCI_VENDOR_ID_LOONGSON, 0x7a24), + .driver_data = (unsigned long)ohci_quirk_loongson, + }, + { .vendor = PCI_VENDOR_ID_APPLE, .device = 0x003f, .subvendor = PCI_SUBVENDOR_ID_REDHAT_QUMRANET,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frode Isaksen frode@meta.com
commit 63ccd26cd1f6600421795f6ca3e625076be06c9f upstream.
The event count is read from register DWC3_GEVNTCOUNT. There is a check for the count being zero, but not for exceeding the event buffer length. Check that event count does not exceed event buffer length, avoiding an out-of-bounds access when memcpy'ing the event. Crash log: Unable to handle kernel paging request at virtual address ffffffc0129be000 pc : __memcpy+0x114/0x180 lr : dwc3_check_event_buf+0xec/0x348 x3 : 0000000000000030 x2 : 000000000000dfc4 x1 : ffffffc0129be000 x0 : ffffff87aad60080 Call trace: __memcpy+0x114/0x180 dwc3_interrupt+0x24/0x34
Signed-off-by: Frode Isaksen frode@meta.com Fixes: 72246da40f37 ("usb: Introduce DesignWare USB3 DRD Driver") Cc: stable stable@kernel.org Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/20250403072907.448524-1-fisaksen@baylibre.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/gadget.c | 6 ++++++ 1 file changed, 6 insertions(+)
--- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -4564,6 +4564,12 @@ static irqreturn_t dwc3_check_event_buf( if (!count) return IRQ_NONE;
+ if (count > evt->length) { + dev_err_ratelimited(dwc->dev, "invalid count(%u) > evt->length(%u)\n", + count, evt->length); + return IRQ_NONE; + } + evt->count = count; evt->flags |= DWC3_EVENT_PENDING;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mike Looijmans mike.looijmans@topic.nl
commit 38d6e60b6f3a99f8f13bee22eab616136c2c0675 upstream.
The "reset" GPIO controls the RESET signal to an external, usually ULPI PHY, chip. The original code path acquires the signal in LOW state, and then immediately asserts it HIGH again, if the reset signal defaulted to asserted, there'd be a short "spike" before the reset.
Here is what happens depending on the pre-existing state of the reset signal: Reset (previously asserted): ~~~|_|~~~~|_______ Reset (previously deasserted): _____|~~~~|_______ ^ ^ ^ A B C
At point A, the low going transition is because the reset line is requested using GPIOD_OUT_LOW. If the line is successfully requested, the first thing we do is set it high _without_ any delay. This is point B. So, a glitch occurs between A and B.
Requesting the line using GPIOD_OUT_HIGH eliminates the A and B transitions. Instead we get:
Reset (previously asserted) : ~~~~~~~~~~|______ Reset (previously deasserted): ____|~~~~~|______ ^ ^ A C
Where A and C are the points described above in the code. Point B has been eliminated.
The issue was found during code inspection.
Also remove the cryptic "toggle ulpi .." comment.
Fixes: ca05b38252d7 ("usb: dwc3: xilinx: Add gpio-reset support") Cc: stable stable@kernel.org Signed-off-by: Mike Looijmans mike.looijmans@topic.nl Reviewed-by: Radhey Shyam Pandey radhey.shyam.pandey@amd.com Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/20250318064518.9320-1-mike.looijmans@topic.nl Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/dwc3/dwc3-xilinx.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/usb/dwc3/dwc3-xilinx.c +++ b/drivers/usb/dwc3/dwc3-xilinx.c @@ -207,15 +207,13 @@ static int dwc3_xlnx_init_zynqmp(struct
skip_usb3_phy: /* ulpi reset via gpio-modepin or gpio-framework driver */ - reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); if (IS_ERR(reset_gpio)) { return dev_err_probe(dev, PTR_ERR(reset_gpio), "Failed to request reset GPIO\n"); }
if (reset_gpio) { - /* Toggle ulpi to reset the phy. */ - gpiod_set_value_cansleep(reset_gpio, 1); usleep_range(5000, 10000); gpiod_set_value_cansleep(reset_gpio, 0); usleep_range(5000, 10000);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miao Li limiao@kylinos.cn
commit 2932b6b547ec36ad2ed60fbf2117c0e46bb7d40a upstream.
Silicon Motion Flash Drive connects to Huawei hisi platforms and performs a system reboot test for two thousand circles, it will randomly work incorrectly on boot, set DELAY_INIT quirk can workaround this issue.
Signed-off-by: Miao Li limiao@kylinos.cn Cc: stable stable@kernel.org Link: https://lore.kernel.org/r/20250401023027.44894-1-limiao870622@163.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -383,6 +383,9 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0904, 0x6103), .driver_info = USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL },
+ /* Silicon Motion Flash Drive */ + { USB_DEVICE(0x090c, 0x1000), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Sound Devices USBPre2 */ { USB_DEVICE(0x0926, 0x0202), .driver_info = USB_QUIRK_ENDPOINT_IGNORE },
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miao Li limiao@kylinos.cn
commit 37ffdbd695c02189dbf23d6e7d2385e0299587ca upstream.
The SanDisk 3.2Gen1 Flash Drive, which VID:PID is in 0781:55a3, just like Silicon Motion Flash Drive: https://lore.kernel.org/r/20250401023027.44894-1-limiao870622@163.com also needs the DELAY_INIT quirk, or it will randomly work incorrectly (e.g.: lsusb and can't list this device info) when connecting Huawei hisi platforms and doing thousand of reboot test circles.
Cc: stable stable@kernel.org Signed-off-by: Miao Li limiao@kylinos.cn Signed-off-by: Lei Huang huanglei@kylinos.cn Link: https://lore.kernel.org/r/20250414062935.159024-1-limiao870622@163.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -369,6 +369,9 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0781, 0x5583), .driver_info = USB_QUIRK_NO_LPM }, { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM },
+ /* SanDisk Corp. SanDisk 3.2Gen1 */ + { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT }, + /* Realforce 87U Keyboard */ { USB_DEVICE(0x0853, 0x011b), .driver_info = USB_QUIRK_NO_LPM },
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
commit e00b39a4f3552c730f1e24c8d62c4a8c6aad4e5d upstream.
This device needs the NO_LPM quirk.
Cc: stable stable@kernel.org Signed-off-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/20250408135800.792515-1-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+)
--- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -545,6 +545,9 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x2040, 0x7200), .driver_info = USB_QUIRK_CONFIG_INTF_STRINGS },
+ /* VLI disk */ + { USB_DEVICE(0x2109, 0x0711), .driver_info = USB_QUIRK_NO_LPM }, + /* Raydium Touchscreen */ { USB_DEVICE(0x2386, 0x3114), .driver_info = USB_QUIRK_NO_LPM },
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrei Kuchynski akuchynski@chromium.org
commit ec27386de23a511008c53aa2f3434ad180a3ca9a upstream.
Concurrent calls to typec_partner_unlink_device can lead to a NULL pointer dereference. This patch adds a mutex to protect USB device pointers and prevent this issue. The same mutex protects both the device pointers and the partner device registration.
Cc: stable@vger.kernel.org Fixes: 59de2a56d127 ("usb: typec: Link enumerated USB devices with Type-C partner") Signed-off-by: Andrei Kuchynski akuchynski@chromium.org Reviewed-by: Benson Leung bleung@chromium.org Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20250321143728.4092417-2-akuchynski@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/typec/class.c | 15 +++++++++++++-- drivers/usb/typec/class.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-)
--- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1052,6 +1052,7 @@ struct typec_partner *typec_register_par partner->usb_mode = USB_MODE_USB3; }
+ mutex_lock(&port->partner_link_lock); ret = device_register(&partner->dev); if (ret) { dev_err(&port->dev, "failed to register partner (%d)\n", ret); @@ -1063,6 +1064,7 @@ struct typec_partner *typec_register_par typec_partner_link_device(partner, port->usb2_dev); if (port->usb3_dev) typec_partner_link_device(partner, port->usb3_dev); + mutex_unlock(&port->partner_link_lock);
return partner; } @@ -1083,12 +1085,14 @@ void typec_unregister_partner(struct typ
port = to_typec_port(partner->dev.parent);
+ mutex_lock(&port->partner_link_lock); if (port->usb2_dev) typec_partner_unlink_device(partner, port->usb2_dev); if (port->usb3_dev) typec_partner_unlink_device(partner, port->usb3_dev);
device_unregister(&partner->dev); + mutex_unlock(&port->partner_link_lock); } EXPORT_SYMBOL_GPL(typec_unregister_partner);
@@ -2041,10 +2045,11 @@ static struct typec_partner *typec_get_p static void typec_partner_attach(struct typec_connector *con, struct device *dev) { struct typec_port *port = container_of(con, struct typec_port, con); - struct typec_partner *partner = typec_get_partner(port); + struct typec_partner *partner; struct usb_device *udev = to_usb_device(dev); enum usb_mode usb_mode;
+ mutex_lock(&port->partner_link_lock); if (udev->speed < USB_SPEED_SUPER) { usb_mode = USB_MODE_USB2; port->usb2_dev = dev; @@ -2053,18 +2058,22 @@ static void typec_partner_attach(struct port->usb3_dev = dev; }
+ partner = typec_get_partner(port); if (partner) { typec_partner_set_usb_mode(partner, usb_mode); typec_partner_link_device(partner, dev); put_device(&partner->dev); } + mutex_unlock(&port->partner_link_lock); }
static void typec_partner_deattach(struct typec_connector *con, struct device *dev) { struct typec_port *port = container_of(con, struct typec_port, con); - struct typec_partner *partner = typec_get_partner(port); + struct typec_partner *partner;
+ mutex_lock(&port->partner_link_lock); + partner = typec_get_partner(port); if (partner) { typec_partner_unlink_device(partner, dev); put_device(&partner->dev); @@ -2074,6 +2083,7 @@ static void typec_partner_deattach(struc port->usb2_dev = NULL; else if (port->usb3_dev == dev) port->usb3_dev = NULL; + mutex_unlock(&port->partner_link_lock); }
/** @@ -2614,6 +2624,7 @@ struct typec_port *typec_register_port(s
ida_init(&port->mode_ids); mutex_init(&port->port_type_lock); + mutex_init(&port->partner_link_lock);
port->id = id; port->ops = cap->ops; --- a/drivers/usb/typec/class.h +++ b/drivers/usb/typec/class.h @@ -59,6 +59,7 @@ struct typec_port { enum typec_port_type port_type; enum usb_mode usb_mode; struct mutex port_type_lock; + struct mutex partner_link_lock;
enum typec_orientation orientation; struct typec_switch *sw;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrei Kuchynski akuchynski@chromium.org
commit 66e1a887273c6b89f09bc11a40d0a71d5a081a8e upstream.
To avoid using invalid USB device pointers after a Type-C partner disconnects, this patch clears the pointers upon partner unregistration. This ensures a clean state for future connections.
Cc: stable@vger.kernel.org Fixes: 59de2a56d127 ("usb: typec: Link enumerated USB devices with Type-C partner") Signed-off-by: Andrei Kuchynski akuchynski@chromium.org Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Reviewed-by: Benson Leung bleung@chromium.org Link: https://lore.kernel.org/r/20250321143728.4092417-3-akuchynski@chromium.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/typec/class.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1086,10 +1086,14 @@ void typec_unregister_partner(struct typ port = to_typec_port(partner->dev.parent);
mutex_lock(&port->partner_link_lock); - if (port->usb2_dev) + if (port->usb2_dev) { typec_partner_unlink_device(partner, port->usb2_dev); - if (port->usb3_dev) + port->usb2_dev = NULL; + } + if (port->usb3_dev) { typec_partner_unlink_device(partner, port->usb3_dev); + port->usb3_dev = NULL; + }
device_unregister(&partner->dev); mutex_unlock(&port->partner_link_lock);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@linaro.org
commit 429a98abfc01d3d4378b7a00969437dc3e8f647c upstream.
We recently added some locking to this function but this error path was accidentally missed. Unlock before returning.
Fixes: ec27386de23a ("usb: typec: class: Fix NULL pointer access") Cc: stable stable@kernel.org Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/Z_44tOtmml89wQcM@stanley.mountain Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/typec/class.c | 1 + 1 file changed, 1 insertion(+)
--- a/drivers/usb/typec/class.c +++ b/drivers/usb/typec/class.c @@ -1056,6 +1056,7 @@ struct typec_partner *typec_register_par ret = device_register(&partner->dev); if (ret) { dev_err(&port->dev, "failed to register partner (%d)\n", ret); + mutex_unlock(&port->partner_link_lock); put_device(&partner->dev); return ERR_PTR(ret); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
commit 9697f5efcf5fdea65b8390b5eb81bebe746ceedc upstream.
In case submitting the URB fails we must undo what we've done so far.
Fixes: cac6fb015f71 ("usb: class: cdc-wdm: WWAN framework integration") Cc: stable stable@kernel.org Signed-off-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/20250401084749.175246-2-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/class/cdc-wdm.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
--- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -829,6 +829,7 @@ static struct usb_class_driver wdm_class static int wdm_wwan_port_start(struct wwan_port *port) { struct wdm_device *desc = wwan_port_get_drvdata(port); + int rv;
/* The interface is both exposed via the WWAN framework and as a * legacy usbmisc chardev. If chardev is already open, just fail @@ -848,7 +849,15 @@ static int wdm_wwan_port_start(struct ww wwan_port_txon(port);
/* Start getting events */ - return usb_submit_urb(desc->validity, GFP_KERNEL); + rv = usb_submit_urb(desc->validity, GFP_KERNEL); + if (rv < 0) { + wwan_port_txoff(port); + desc->manage_power(desc->intf, 0); + /* this must be last lest we race with chardev open */ + clear_bit(WDM_WWAN_IN_USE, &desc->flags); + } + + return rv; }
static void wdm_wwan_port_stop(struct wwan_port *port)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
commit c1846ed4eb527bdfe6b3b7dd2c78e2af4bf98f4f upstream.
Clearing WDM_WWAN_IN_USE must be the last action or we can open a chardev whose URBs are still poisoned
Fixes: cac6fb015f71 ("usb: class: cdc-wdm: WWAN framework integration") Cc: stable stable@kernel.org Signed-off-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/20250401084749.175246-3-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/class/cdc-wdm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -726,7 +726,7 @@ static int wdm_open(struct inode *inode, rv = -EBUSY; goto out; } - + smp_rmb(); /* ordered against wdm_wwan_port_stop() */ rv = usb_autopm_get_interface(desc->intf); if (rv < 0) { dev_err(&desc->intf->dev, "Error autopm - %d\n", rv); @@ -868,8 +868,10 @@ static void wdm_wwan_port_stop(struct ww poison_urbs(desc); desc->manage_power(desc->intf, 0); clear_bit(WDM_READ, &desc->flags); - clear_bit(WDM_WWAN_IN_USE, &desc->flags); unpoison_urbs(desc); + smp_wmb(); /* ordered against wdm_open() */ + /* this must be last lest we open a poisoned device */ + clear_bit(WDM_WWAN_IN_USE, &desc->flags); }
static void wdm_wwan_port_tx_complete(struct urb *urb)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
commit 1fdc4dca350c0b8ada0b8ebf212504e1ad55e511 upstream.
wdm_wwan_port_tx_complete is called from a completion handler with irqs disabled and possible in IRQ context usb_autopm_put_interface can take a mutex. Hence usb_autopm_put_interface_async must be used.
Fixes: cac6fb015f71 ("usb: class: cdc-wdm: WWAN framework integration") Cc: stable stable@kernel.org Signed-off-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/20250401084749.175246-4-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/class/cdc-wdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -879,7 +879,7 @@ static void wdm_wwan_port_tx_complete(st struct sk_buff *skb = urb->context; struct wdm_device *desc = skb_shinfo(skb)->destructor_arg;
- usb_autopm_put_interface(desc->intf); + usb_autopm_put_interface_async(desc->intf); wwan_port_txon(desc->wwanp); kfree_skb(skb); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum oneukum@suse.com
commit 73e9cc1ffd3650b12c4eb059dfdafd56e725ceda upstream.
This is not understandable without a comment on endianness
Fixes: afba937e540c9 ("USB: CDC WDM driver") Cc: stable stable@kernel.org Signed-off-by: Oliver Neukum oneukum@suse.com Link: https://lore.kernel.org/r/20250401084749.175246-5-oneukum@suse.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/class/cdc-wdm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -909,7 +909,7 @@ static int wdm_wwan_port_tx(struct wwan_ req->bRequestType = (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); req->bRequest = USB_CDC_SEND_ENCAPSULATED_COMMAND; req->wValue = 0; - req->wIndex = desc->inum; + req->wIndex = desc->inum; /* already converted */ req->wLength = cpu_to_le16(skb->len);
skb_shinfo(skb)->destructor_arg = desc;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Wunner lukas@wunner.de
[ Upstream commit b16510a530d1e6ab9683f04f8fb34f2e0f538275 ]
Herbert notes that DIV_ROUND_UP() may overflow unnecessarily if an ecdsa implementation's ->key_size() callback returns an unusually large value. Herbert instead suggests (for a division by 8):
X / 8 + !!(X & 7)
Based on this formula, introduce a generic DIV_ROUND_UP_POW2() macro and use it in lieu of DIV_ROUND_UP() for ->key_size() return values.
Additionally, use the macro in ecc_digits_from_bytes(), whose "nbytes" parameter is a ->key_size() return value in some instances, or a user-specified ASN.1 length in the case of ecdsa_get_signature_rs().
Link: https://lore.kernel.org/r/Z3iElsILmoSu6FuC@gondor.apana.org.au/ Signed-off-by: Lukas Wunner lukas@wunner.de Signed-off-by: Lukas Wunner lukas@wunner.de Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/ecc.c | 2 +- crypto/ecdsa-p1363.c | 2 +- crypto/ecdsa-x962.c | 4 ++-- include/linux/math.h | 12 ++++++++++++ 4 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/crypto/ecc.c b/crypto/ecc.c index 50ad2d4ed672c..6cf9a945fc6c2 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c @@ -71,7 +71,7 @@ EXPORT_SYMBOL(ecc_get_curve); void ecc_digits_from_bytes(const u8 *in, unsigned int nbytes, u64 *out, unsigned int ndigits) { - int diff = ndigits - DIV_ROUND_UP(nbytes, sizeof(u64)); + int diff = ndigits - DIV_ROUND_UP_POW2(nbytes, sizeof(u64)); unsigned int o = nbytes & 7; __be64 msd = 0;
diff --git a/crypto/ecdsa-p1363.c b/crypto/ecdsa-p1363.c index eaae7214d69bc..4454f1f8f33f5 100644 --- a/crypto/ecdsa-p1363.c +++ b/crypto/ecdsa-p1363.c @@ -22,7 +22,7 @@ static int ecdsa_p1363_verify(struct crypto_sig *tfm, { struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm); unsigned int keylen = crypto_sig_keysize(ctx->child); - unsigned int ndigits = DIV_ROUND_UP(keylen, sizeof(u64)); + unsigned int ndigits = DIV_ROUND_UP_POW2(keylen, sizeof(u64)); struct ecdsa_raw_sig sig;
if (slen != 2 * keylen) diff --git a/crypto/ecdsa-x962.c b/crypto/ecdsa-x962.c index 6a77c13e192b1..90a04f4b9a2f5 100644 --- a/crypto/ecdsa-x962.c +++ b/crypto/ecdsa-x962.c @@ -81,8 +81,8 @@ static int ecdsa_x962_verify(struct crypto_sig *tfm, struct ecdsa_x962_signature_ctx sig_ctx; int err;
- sig_ctx.ndigits = DIV_ROUND_UP(crypto_sig_keysize(ctx->child), - sizeof(u64)); + sig_ctx.ndigits = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child), + sizeof(u64));
err = asn1_ber_decoder(&ecdsasignature_decoder, &sig_ctx, src, slen); if (err < 0) diff --git a/include/linux/math.h b/include/linux/math.h index f5f18dc3616b0..0198c92cbe3ef 100644 --- a/include/linux/math.h +++ b/include/linux/math.h @@ -34,6 +34,18 @@ */ #define round_down(x, y) ((x) & ~__round_mask(x, y))
+/** + * DIV_ROUND_UP_POW2 - divide and round up + * @n: numerator + * @d: denominator (must be a power of 2) + * + * Divides @n by @d and rounds up to next multiple of @d (which must be a power + * of 2). Avoids integer overflows that may occur with __KERNEL_DIV_ROUND_UP(). + * Performance is roughly equivalent to __KERNEL_DIV_ROUND_UP(). + */ +#define DIV_ROUND_UP_POW2(n, d) \ + ((n) / (d) + !!((n) & ((d) - 1))) + #define DIV_ROUND_UP __KERNEL_DIV_ROUND_UP
#define DIV_ROUND_DOWN_ULL(ll, d) \
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amery Hung ameryhung@gmail.com
[ Upstream commit b99f27e90268b1a814c13f8bd72ea1db448ea257 ]
Fix a race condition between the main test_progs thread and the traffic monitoring thread. The traffic monitor thread tries to print a line using multiple printf and use flockfile() to prevent the line from being torn apart. Meanwhile, the main thread doing io redirection can reassign or close stdout when going through tests. A deadlock as shown below can happen.
main traffic_monitor_thread ==== ====================== show_transport() -> flockfile(stdout)
stdio_hijack_init() -> stdout = open_memstream(log_buf, log_cnt); ... env.subtest_state->stdout_saved = stdout;
... funlockfile(stdout) stdio_restore_cleanup() -> fclose(env.subtest_state->stdout_saved);
After the traffic monitor thread lock stdout, A new memstream can be assigned to stdout by the main thread. Therefore, the traffic monitor thread later will not be able to unlock the original stdout. As the main thread tries to access the old stdout, it will hang indefinitely as it is still locked by the traffic monitor thread.
The deadlock can be reproduced by running test_progs repeatedly with traffic monitor enabled:
for ((i=1;i<=100;i++)); do ./test_progs -a flow_dissector_skb* -m '*' done
Fix this by only calling printf once and remove flockfile()/funlockfile().
Signed-off-by: Amery Hung ameryhung@gmail.com Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Link: https://patch.msgid.link/20250213233217.553258-1-ameryhung@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/network_helpers.c | 33 ++++++++----------- 1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/tools/testing/selftests/bpf/network_helpers.c b/tools/testing/selftests/bpf/network_helpers.c index 80844a5fb1fee..95e943270f359 100644 --- a/tools/testing/selftests/bpf/network_helpers.c +++ b/tools/testing/selftests/bpf/network_helpers.c @@ -771,12 +771,13 @@ static const char *pkt_type_str(u16 pkt_type) return "Unknown"; }
+#define MAX_FLAGS_STRLEN 21 /* Show the information of the transport layer in the packet */ static void show_transport(const u_char *packet, u16 len, u32 ifindex, const char *src_addr, const char *dst_addr, u16 proto, bool ipv6, u8 pkt_type) { - char *ifname, _ifname[IF_NAMESIZE]; + char *ifname, _ifname[IF_NAMESIZE], flags[MAX_FLAGS_STRLEN] = ""; const char *transport_str; u16 src_port, dst_port; struct udphdr *udp; @@ -817,29 +818,21 @@ static void show_transport(const u_char *packet, u16 len, u32 ifindex,
/* TCP or UDP*/
- flockfile(stdout); + if (proto == IPPROTO_TCP) + snprintf(flags, MAX_FLAGS_STRLEN, "%s%s%s%s", + tcp->fin ? ", FIN" : "", + tcp->syn ? ", SYN" : "", + tcp->rst ? ", RST" : "", + tcp->ack ? ", ACK" : ""); + if (ipv6) - printf("%-7s %-3s IPv6 %s.%d > %s.%d: %s, length %d", + printf("%-7s %-3s IPv6 %s.%d > %s.%d: %s, length %d%s\n", ifname, pkt_type_str(pkt_type), src_addr, src_port, - dst_addr, dst_port, transport_str, len); + dst_addr, dst_port, transport_str, len, flags); else - printf("%-7s %-3s IPv4 %s:%d > %s:%d: %s, length %d", + printf("%-7s %-3s IPv4 %s:%d > %s:%d: %s, length %d%s\n", ifname, pkt_type_str(pkt_type), src_addr, src_port, - dst_addr, dst_port, transport_str, len); - - if (proto == IPPROTO_TCP) { - if (tcp->fin) - printf(", FIN"); - if (tcp->syn) - printf(", SYN"); - if (tcp->rst) - printf(", RST"); - if (tcp->ack) - printf(", ACK"); - } - - printf("\n"); - funlockfile(stdout); + dst_addr, dst_port, transport_str, len, flags); }
static void show_ipv6_packet(const u_char *packet, u32 ifindex, u8 pkt_type)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang chenyuan0y@gmail.com
[ Upstream commit f752ee5b5b86b5f88a5687c9eb0ef9b39859b908 ]
`chip.label` in rza2_gpio_register() could be NULL. Add the missing check.
Signed-off-by: Chenyuan Yang chenyuan0y@gmail.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Reviewed-by: Matthias Brugger matthias.bgg@gmail.com Link: https://lore.kernel.org/20250210232552.1545887-1-chenyuan0y@gmail.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/renesas/pinctrl-rza2.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/pinctrl/renesas/pinctrl-rza2.c b/drivers/pinctrl/renesas/pinctrl-rza2.c index 8b36161c7c502..3b58129638500 100644 --- a/drivers/pinctrl/renesas/pinctrl-rza2.c +++ b/drivers/pinctrl/renesas/pinctrl-rza2.c @@ -246,6 +246,9 @@ static int rza2_gpio_register(struct rza2_pinctrl_priv *priv) int ret;
chip.label = devm_kasprintf(priv->dev, GFP_KERNEL, "%pOFn", np); + if (!chip.label) + return -ENOMEM; + chip.parent = priv->dev; chip.ngpio = priv->npins;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Mastykin mastichi@gmail.com
[ Upstream commit 7b0671b97f0872d6950ccc925e210cb3f67721bf ]
irq_mask()/irq_unmask() are not called for nested interrupts. So level interrupts are never masked, chip's interrupt output is not cleared on INTCAP or GPIO read, the irq handler is uselessly called again. Nested irq handler is not called again, because interrupt reason is cleared by its first call. /proc/interrupts shows that number of chip's irqs is greater than number of nested irqs.
This patch adds masking and unmasking level interrupts inside irq handler.
Signed-off-by: Dmitry Mastykin mastichi@gmail.com Link: https://lore.kernel.org/20250122120504.1279790-1-mastichi@gmail.com Signed-off-by: Linus Walleij linus.walleij@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pinctrl/pinctrl-mcp23s08.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/drivers/pinctrl/pinctrl-mcp23s08.c b/drivers/pinctrl/pinctrl-mcp23s08.c index b96e6368a9568..4d1f41488017e 100644 --- a/drivers/pinctrl/pinctrl-mcp23s08.c +++ b/drivers/pinctrl/pinctrl-mcp23s08.c @@ -382,6 +382,7 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) { struct mcp23s08 *mcp = data; int intcap, intcon, intf, i, gpio, gpio_orig, intcap_mask, defval, gpinten; + bool need_unmask = false; unsigned long int enabled_interrupts; unsigned int child_irq; bool intf_set, intcap_changed, gpio_bit_changed, @@ -396,9 +397,6 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) goto unlock; }
- if (mcp_read(mcp, MCP_INTCAP, &intcap)) - goto unlock; - if (mcp_read(mcp, MCP_INTCON, &intcon)) goto unlock;
@@ -408,6 +406,16 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) if (mcp_read(mcp, MCP_DEFVAL, &defval)) goto unlock;
+ /* Mask level interrupts to avoid their immediate reactivation after clearing */ + if (intcon) { + need_unmask = true; + if (mcp_write(mcp, MCP_GPINTEN, gpinten & ~intcon)) + goto unlock; + } + + if (mcp_read(mcp, MCP_INTCAP, &intcap)) + goto unlock; + /* This clears the interrupt(configurable on S18) */ if (mcp_read(mcp, MCP_GPIO, &gpio)) goto unlock; @@ -470,9 +478,18 @@ static irqreturn_t mcp23s08_irq(int irq, void *data) } }
+ if (need_unmask) { + mutex_lock(&mcp->lock); + goto unlock; + } + return IRQ_HANDLED;
unlock: + if (need_unmask) + if (mcp_write(mcp, MCP_GPINTEN, gpinten)) + dev_err(mcp->chip.parent, "can't unmask GPINTEN\n"); + mutex_unlock(&mcp->lock); return IRQ_HANDLED; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gregory CLEMENT gregory.clement@bootlin.com
[ Upstream commit e27fbe16af5cfc40639de4ced67d1a866a1953e9 ]
Some information that should be retrieved at runtime for the Coherence Manager can be either absent or wrong. This patch allows checking if some of this information is available from the device tree and updates the internal variable accordingly.
For now, only the compatible string associated with the broken HCI is being retrieved.
Signed-off-by: Gregory CLEMENT gregory.clement@bootlin.com Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/mips/include/asm/mips-cm.h | 22 ++++++++++++++++++++++ arch/mips/kernel/mips-cm.c | 14 ++++++++++++++ 2 files changed, 36 insertions(+)
diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h index 23ce951f445bb..754e96dba256c 100644 --- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -59,6 +59,16 @@ extern phys_addr_t mips_cm_l2sync_phys_base(void); */ extern int mips_cm_is64;
+/* + * mips_cm_is_l2_hci_broken - determine if HCI is broken + * + * Some CM reports show that Hardware Cache Initialization is + * complete, but in reality it's not the case. They also incorrectly + * indicate that Hardware Cache Initialization is supported. This + * flags allows warning about this broken feature. + */ +extern bool mips_cm_is_l2_hci_broken; + /** * mips_cm_error_report - Report CM cache errors */ @@ -97,6 +107,18 @@ static inline bool mips_cm_present(void) #endif }
+/** + * mips_cm_update_property - update property from the device tree + * + * Retrieve the properties from the device tree if a CM node exist and + * update the internal variable based on this. + */ +#ifdef CONFIG_MIPS_CM +extern void mips_cm_update_property(void); +#else +static void mips_cm_update_property(void) {} +#endif + /** * mips_cm_has_l2sync - determine whether an L2-only sync region is present * diff --git a/arch/mips/kernel/mips-cm.c b/arch/mips/kernel/mips-cm.c index 3eb2cfb893e19..9cfabaa94d010 100644 --- a/arch/mips/kernel/mips-cm.c +++ b/arch/mips/kernel/mips-cm.c @@ -5,6 +5,7 @@ */
#include <linux/errno.h> +#include <linux/of.h> #include <linux/percpu.h> #include <linux/spinlock.h>
@@ -14,6 +15,7 @@ void __iomem *mips_gcr_base; void __iomem *mips_cm_l2sync_base; int mips_cm_is64; +bool mips_cm_is_l2_hci_broken;
static char *cm2_tr[8] = { "mem", "gcr", "gic", "mmio", @@ -237,6 +239,18 @@ static void mips_cm_probe_l2sync(void) mips_cm_l2sync_base = ioremap(addr, MIPS_CM_L2SYNC_SIZE); }
+void mips_cm_update_property(void) +{ + struct device_node *cm_node; + + cm_node = of_find_compatible_node(of_root, NULL, "mobileye,eyeq6-cm"); + if (!cm_node) + return; + pr_info("HCI (Hardware Cache Init for the L2 cache) in GCR_L2_RAM_CONFIG from the CM3 is broken"); + mips_cm_is_l2_hci_broken = true; + of_node_put(cm_node); +} + int mips_cm_probe(void) { phys_addr_t addr;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Devaraj Rangasamy Devaraj.Rangasamy@amd.com
[ Upstream commit 6cb345939b8cc4be79909875276aa9dc87d16757 ]
PCI device 0x1134 shares same register features as PCI device 0x17E0. Hence reuse same data for the new PCI device ID 0x1134.
Signed-off-by: Devaraj Rangasamy Devaraj.Rangasamy@amd.com Acked-by: Tom Lendacky thomas.lendacky@amd.com Reviewed-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/crypto/ccp/sp-pci.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c index 157f9a9ed6361..2ebc878da1609 100644 --- a/drivers/crypto/ccp/sp-pci.c +++ b/drivers/crypto/ccp/sp-pci.c @@ -532,6 +532,7 @@ static const struct pci_device_id sp_pci_table[] = { { PCI_VDEVICE(AMD, 0x14CA), (kernel_ulong_t)&dev_vdata[5] }, { PCI_VDEVICE(AMD, 0x15C7), (kernel_ulong_t)&dev_vdata[6] }, { PCI_VDEVICE(AMD, 0x1649), (kernel_ulong_t)&dev_vdata[6] }, + { PCI_VDEVICE(AMD, 0x1134), (kernel_ulong_t)&dev_vdata[7] }, { PCI_VDEVICE(AMD, 0x17E0), (kernel_ulong_t)&dev_vdata[7] }, { PCI_VDEVICE(AMD, 0x156E), (kernel_ulong_t)&dev_vdata[8] }, /* Last entry must be zero */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit 1047e21aecdf17c8a9ab9fd4bd24c6647453f93d ]
The HAVE_ARCH Kconfig options in lib/crypto try to solve the modular versus built-in problem, but it still fails when the the LIB option (e.g., CRYPTO_LIB_CURVE25519) is selected externally.
Fix this by introducing a level of indirection with ARCH_MAY_HAVE Kconfig options, these then go on to select the ARCH_HAVE options if the ARCH Kconfig options matches that of the LIB option.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202501230223.ikroNDr1-lkp@intel.com/ Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- arch/arm/crypto/Kconfig | 6 +++--- arch/powerpc/crypto/Kconfig | 4 ++-- arch/x86/crypto/Kconfig | 6 +++--- lib/crypto/Kconfig | 26 ++++++++++++++++++-------- 4 files changed, 26 insertions(+), 16 deletions(-)
diff --git a/arch/arm/crypto/Kconfig b/arch/arm/crypto/Kconfig index 32650c8431d98..47d9cc59f254c 100644 --- a/arch/arm/crypto/Kconfig +++ b/arch/arm/crypto/Kconfig @@ -6,7 +6,7 @@ config CRYPTO_CURVE25519_NEON tristate "Public key crypto: Curve25519 (NEON)" depends on KERNEL_MODE_NEON select CRYPTO_LIB_CURVE25519_GENERIC - select CRYPTO_ARCH_HAVE_LIB_CURVE25519 + select CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 help Curve25519 algorithm
@@ -47,7 +47,7 @@ config CRYPTO_NHPOLY1305_NEON config CRYPTO_POLY1305_ARM tristate "Hash functions: Poly1305 (NEON)" select CRYPTO_HASH - select CRYPTO_ARCH_HAVE_LIB_POLY1305 + select CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305 help Poly1305 authenticator algorithm (RFC7539)
@@ -214,7 +214,7 @@ config CRYPTO_AES_ARM_CE config CRYPTO_CHACHA20_NEON tristate "Ciphers: ChaCha20, XChaCha20, XChaCha12 (NEON)" select CRYPTO_SKCIPHER - select CRYPTO_ARCH_HAVE_LIB_CHACHA + select CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms diff --git a/arch/powerpc/crypto/Kconfig b/arch/powerpc/crypto/Kconfig index 5b315e9756b3f..e453cb0c82d2a 100644 --- a/arch/powerpc/crypto/Kconfig +++ b/arch/powerpc/crypto/Kconfig @@ -6,7 +6,7 @@ config CRYPTO_CURVE25519_PPC64 tristate "Public key crypto: Curve25519 (PowerPC64)" depends on PPC64 && CPU_LITTLE_ENDIAN select CRYPTO_LIB_CURVE25519_GENERIC - select CRYPTO_ARCH_HAVE_LIB_CURVE25519 + select CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 help Curve25519 algorithm
@@ -95,7 +95,7 @@ config CRYPTO_CHACHA20_P10 depends on PPC64 && CPU_LITTLE_ENDIAN && VSX select CRYPTO_SKCIPHER select CRYPTO_LIB_CHACHA_GENERIC - select CRYPTO_ARCH_HAVE_LIB_CHACHA + select CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms diff --git a/arch/x86/crypto/Kconfig b/arch/x86/crypto/Kconfig index 4757bf922075b..c189dad0969ba 100644 --- a/arch/x86/crypto/Kconfig +++ b/arch/x86/crypto/Kconfig @@ -6,7 +6,7 @@ config CRYPTO_CURVE25519_X86 tristate "Public key crypto: Curve25519 (ADX)" depends on X86 && 64BIT select CRYPTO_LIB_CURVE25519_GENERIC - select CRYPTO_ARCH_HAVE_LIB_CURVE25519 + select CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 help Curve25519 algorithm
@@ -352,7 +352,7 @@ config CRYPTO_CHACHA20_X86_64 depends on X86 && 64BIT select CRYPTO_SKCIPHER select CRYPTO_LIB_CHACHA_GENERIC - select CRYPTO_ARCH_HAVE_LIB_CHACHA + select CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms @@ -420,7 +420,7 @@ config CRYPTO_POLY1305_X86_64 tristate "Hash functions: Poly1305 (SSE2/AVX2)" depends on X86 && 64BIT select CRYPTO_LIB_POLY1305_GENERIC - select CRYPTO_ARCH_HAVE_LIB_POLY1305 + select CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305 help Poly1305 authenticator algorithm (RFC7539)
diff --git a/lib/crypto/Kconfig b/lib/crypto/Kconfig index b01253cac70a7..c542ef1d64d03 100644 --- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -42,12 +42,17 @@ config CRYPTO_LIB_BLAKE2S_GENERIC of CRYPTO_LIB_BLAKE2S.
config CRYPTO_ARCH_HAVE_LIB_CHACHA - tristate + bool help Declares whether the architecture provides an arch-specific accelerated implementation of the ChaCha library interface, either builtin or as a module.
+config CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA + tristate + select CRYPTO_ARCH_HAVE_LIB_CHACHA if CRYPTO_LIB_CHACHA=m + select CRYPTO_ARCH_HAVE_LIB_CHACHA if CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA=y + config CRYPTO_LIB_CHACHA_GENERIC tristate select CRYPTO_LIB_UTILS @@ -60,7 +65,6 @@ config CRYPTO_LIB_CHACHA_GENERIC
config CRYPTO_LIB_CHACHA tristate "ChaCha library interface" - depends on CRYPTO_ARCH_HAVE_LIB_CHACHA || !CRYPTO_ARCH_HAVE_LIB_CHACHA select CRYPTO_LIB_CHACHA_GENERIC if CRYPTO_ARCH_HAVE_LIB_CHACHA=n help Enable the ChaCha library interface. This interface may be fulfilled @@ -68,12 +72,17 @@ config CRYPTO_LIB_CHACHA is available and enabled.
config CRYPTO_ARCH_HAVE_LIB_CURVE25519 - tristate + bool help Declares whether the architecture provides an arch-specific accelerated implementation of the Curve25519 library interface, either builtin or as a module.
+config CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 + tristate + select CRYPTO_ARCH_HAVE_LIB_CURVE25519 if CRYPTO_LIB_CURVE25519=m + select CRYPTO_ARCH_HAVE_LIB_CURVE25519 if CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519=y + config CRYPTO_LIB_CURVE25519_GENERIC tristate help @@ -85,7 +94,6 @@ config CRYPTO_LIB_CURVE25519_GENERIC
config CRYPTO_LIB_CURVE25519 tristate "Curve25519 scalar multiplication library" - depends on CRYPTO_ARCH_HAVE_LIB_CURVE25519 || !CRYPTO_ARCH_HAVE_LIB_CURVE25519 select CRYPTO_LIB_CURVE25519_GENERIC if CRYPTO_ARCH_HAVE_LIB_CURVE25519=n select CRYPTO_LIB_UTILS help @@ -104,12 +112,17 @@ config CRYPTO_LIB_POLY1305_RSIZE default 1
config CRYPTO_ARCH_HAVE_LIB_POLY1305 - tristate + bool help Declares whether the architecture provides an arch-specific accelerated implementation of the Poly1305 library interface, either builtin or as a module.
+config CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305 + tristate + select CRYPTO_ARCH_HAVE_LIB_POLY1305 if CRYPTO_LIB_POLY1305=m + select CRYPTO_ARCH_HAVE_LIB_POLY1305 if CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305=y + config CRYPTO_LIB_POLY1305_GENERIC tristate help @@ -121,7 +134,6 @@ config CRYPTO_LIB_POLY1305_GENERIC
config CRYPTO_LIB_POLY1305 tristate "Poly1305 library interface" - depends on CRYPTO_ARCH_HAVE_LIB_POLY1305 || !CRYPTO_ARCH_HAVE_LIB_POLY1305 select CRYPTO_LIB_POLY1305_GENERIC if CRYPTO_ARCH_HAVE_LIB_POLY1305=n help Enable the Poly1305 library interface. This interface may be fulfilled @@ -130,8 +142,6 @@ config CRYPTO_LIB_POLY1305
config CRYPTO_LIB_CHACHA20POLY1305 tristate "ChaCha20-Poly1305 AEAD support (8-byte nonce library version)" - depends on CRYPTO_ARCH_HAVE_LIB_CHACHA || !CRYPTO_ARCH_HAVE_LIB_CHACHA - depends on CRYPTO_ARCH_HAVE_LIB_POLY1305 || !CRYPTO_ARCH_HAVE_LIB_POLY1305 depends on CRYPTO select CRYPTO_LIB_CHACHA select CRYPTO_LIB_POLY1305
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu herbert@gondor.apana.org.au
[ Upstream commit dcc47a028c24e793ce6d6efebfef1a1e92f80297 ]
As the null algorithm may be freed in softirq context through af_alg, use spin locks instead of mutexes to protect the default null algorithm.
Reported-by: syzbot+b3e02953598f447d4d2a@syzkaller.appspotmail.com Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Sasha Levin sashal@kernel.org --- crypto/crypto_null.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-)
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c index 5b84b0f7cc178..3378670286535 100644 --- a/crypto/crypto_null.c +++ b/crypto/crypto_null.c @@ -17,10 +17,10 @@ #include <crypto/internal/skcipher.h> #include <linux/init.h> #include <linux/module.h> -#include <linux/mm.h> +#include <linux/spinlock.h> #include <linux/string.h>
-static DEFINE_MUTEX(crypto_default_null_skcipher_lock); +static DEFINE_SPINLOCK(crypto_default_null_skcipher_lock); static struct crypto_sync_skcipher *crypto_default_null_skcipher; static int crypto_default_null_skcipher_refcnt;
@@ -152,23 +152,32 @@ MODULE_ALIAS_CRYPTO("cipher_null");
struct crypto_sync_skcipher *crypto_get_default_null_skcipher(void) { + struct crypto_sync_skcipher *ntfm = NULL; struct crypto_sync_skcipher *tfm;
- mutex_lock(&crypto_default_null_skcipher_lock); + spin_lock_bh(&crypto_default_null_skcipher_lock); tfm = crypto_default_null_skcipher;
if (!tfm) { - tfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0); - if (IS_ERR(tfm)) - goto unlock; - - crypto_default_null_skcipher = tfm; + spin_unlock_bh(&crypto_default_null_skcipher_lock); + + ntfm = crypto_alloc_sync_skcipher("ecb(cipher_null)", 0, 0); + if (IS_ERR(ntfm)) + return ntfm; + + spin_lock_bh(&crypto_default_null_skcipher_lock); + tfm = crypto_default_null_skcipher; + if (!tfm) { + tfm = ntfm; + ntfm = NULL; + crypto_default_null_skcipher = tfm; + } }
crypto_default_null_skcipher_refcnt++; + spin_unlock_bh(&crypto_default_null_skcipher_lock);
-unlock: - mutex_unlock(&crypto_default_null_skcipher_lock); + crypto_free_sync_skcipher(ntfm);
return tfm; } @@ -176,12 +185,16 @@ EXPORT_SYMBOL_GPL(crypto_get_default_null_skcipher);
void crypto_put_default_null_skcipher(void) { - mutex_lock(&crypto_default_null_skcipher_lock); + struct crypto_sync_skcipher *tfm = NULL; + + spin_lock_bh(&crypto_default_null_skcipher_lock); if (!--crypto_default_null_skcipher_refcnt) { - crypto_free_sync_skcipher(crypto_default_null_skcipher); + tfm = crypto_default_null_skcipher; crypto_default_null_skcipher = NULL; } - mutex_unlock(&crypto_default_null_skcipher_lock); + spin_unlock_bh(&crypto_default_null_skcipher_lock); + + crypto_free_sync_skcipher(tfm); } EXPORT_SYMBOL_GPL(crypto_put_default_null_skcipher);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yonghong Song yonghong.song@linux.dev
[ Upstream commit 11ba7ce076e5903e7bdc1fd1498979c331b3c286 ]
Vlad Poenaru reported the following kmemleak issue:
unreferenced object 0x606fd7c44ac8 (size 32): backtrace (crc 0): pcpu_alloc_noprof+0x730/0xeb0 bpf_map_alloc_percpu+0x69/0xc0 prealloc_init+0x9d/0x1b0 htab_map_alloc+0x363/0x510 map_create+0x215/0x3a0 __sys_bpf+0x16b/0x3e0 __x64_sys_bpf+0x18/0x20 do_syscall_64+0x7b/0x150 entry_SYSCALL_64_after_hwframe+0x4b/0x53
Further investigation shows the reason is due to not 8-byte aligned store of percpu pointer in htab_elem_set_ptr(): *(void __percpu **)(l->key + key_size) = pptr;
Note that the whole htab_elem alignment is 8 (for x86_64). If the key_size is 4, that means pptr is stored in a location which is 4 byte aligned but not 8 byte aligned. In mm/kmemleak.c, scan_block() scans the memory based on 8 byte stride, so it won't detect above pptr, hence reporting the memory leak.
In htab_map_alloc(), we already have
htab->elem_size = sizeof(struct htab_elem) + round_up(htab->map.key_size, 8); if (percpu) htab->elem_size += sizeof(void *); else htab->elem_size += round_up(htab->map.value_size, 8);
So storing pptr with 8-byte alignment won't cause any problem and can fix kmemleak too.
The issue can be reproduced with bpf selftest as well: 1. Enable CONFIG_DEBUG_KMEMLEAK config 2. Add a getchar() before skel destroy in test_hash_map() in prog_tests/for_each.c. The purpose is to keep map available so kmemleak can be detected. 3. run './test_progs -t for_each/hash_map &' and a kmemleak should be reported.
Reported-by: Vlad Poenaru thevlad@meta.com Signed-off-by: Yonghong Song yonghong.song@linux.dev Acked-by: Martin KaFai Lau martin.lau@kernel.org Link: https://lore.kernel.org/r/20250224175514.2207227-1-yonghong.song@linux.dev Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/hashtab.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 4a9eeb7aef855..c308300fc72f6 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c @@ -198,12 +198,12 @@ static bool htab_is_percpu(const struct bpf_htab *htab) static inline void htab_elem_set_ptr(struct htab_elem *l, u32 key_size, void __percpu *pptr) { - *(void __percpu **)(l->key + key_size) = pptr; + *(void __percpu **)(l->key + roundup(key_size, 8)) = pptr; }
static inline void __percpu *htab_elem_get_ptr(struct htab_elem *l, u32 key_size) { - return *(void __percpu **)(l->key + key_size); + return *(void __percpu **)(l->key + roundup(key_size, 8)); }
static void *fd_htab_map_get_ptr(const struct bpf_map *map, struct htab_elem *l) @@ -2354,7 +2354,7 @@ static int htab_percpu_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn *insn++ = BPF_EMIT_CALL(__htab_map_lookup_elem); *insn++ = BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 3); *insn++ = BPF_ALU64_IMM(BPF_ADD, BPF_REG_0, - offsetof(struct htab_elem, key) + map->key_size); + offsetof(struct htab_elem, key) + roundup(map->key_size, 8)); *insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0); *insn++ = BPF_MOV64_PERCPU_REG(BPF_REG_0, BPF_REG_0);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexei Starovoitov ast@kernel.org
[ Upstream commit 4580f4e0ebdf8dc8d506ae926b88510395a0c1d1 ]
Fix the following deadlock: CPU A _free_event() perf_kprobe_destroy() mutex_lock(&event_mutex) perf_trace_event_unreg() synchronize_rcu_tasks_trace()
There are several paths where _free_event() grabs event_mutex and calls sync_rcu_tasks_trace. Above is one such case.
CPU B bpf_prog_test_run_syscall() rcu_read_lock_trace() bpf_prog_run_pin_on_cpu() bpf_prog_load() bpf_tracing_func_proto() trace_set_clr_event() mutex_lock(&event_mutex)
Delegate trace_set_clr_event() to workqueue to avoid such lock dependency.
Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Andrii Nakryiko andrii@kernel.org Acked-by: Andrii Nakryiko andrii@kernel.org Link: https://lore.kernel.org/bpf/20250224221637.4780-1-alexei.starovoitov@gmail.c... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/trace/bpf_trace.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index a612f6f182e51..13bef2462e94b 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -392,7 +392,7 @@ static const struct bpf_func_proto bpf_trace_printk_proto = { .arg2_type = ARG_CONST_SIZE, };
-static void __set_printk_clr_event(void) +static void __set_printk_clr_event(struct work_struct *work) { /* * This program might be calling bpf_trace_printk, @@ -405,10 +405,11 @@ static void __set_printk_clr_event(void) if (trace_set_clr_event("bpf_trace", "bpf_trace_printk", 1)) pr_warn_ratelimited("could not enable bpf_trace_printk events"); } +static DECLARE_WORK(set_printk_work, __set_printk_clr_event);
const struct bpf_func_proto *bpf_get_trace_printk_proto(void) { - __set_printk_clr_event(); + schedule_work(&set_printk_work); return &bpf_trace_printk_proto; }
@@ -451,7 +452,7 @@ static const struct bpf_func_proto bpf_trace_vprintk_proto = {
const struct bpf_func_proto *bpf_get_trace_vprintk_proto(void) { - __set_printk_clr_event(); + schedule_work(&set_printk_work); return &bpf_trace_vprintk_proto; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Stuebner heiko@sntech.de
[ Upstream commit b20150d499b3ee5c2d632fbc5ac94f98dd33accf ]
of_clk_get_hw_from_clkspec() checks all available clock-providers by comparing their of nodes to the one from the clkspec. If no matching clock provider is found, the function returns -EPROBE_DEFER to cause a re-check at a later date. If a matching clock provider is found, an authoritative answer can be retrieved from it whether the clock exists or not.
This does not take into account that the clock-provider may never appear, because it's node is disabled. This can happen when a clock is optional, provided by a separate block which never gets enabled.
One example of this happening is the rk3588's VOP, which has optional additional display clocks coming from PLLs inside the hdmiphy blocks. These can be used for better rates, but the system will also work without them.
The problem around that is described in the followups to[1]. As we already know the of node of the presumed clock provider, add a check via of_device_is_available() whether this is a "valid" device node. This prevents eternal defer loops.
Link: https://lore.kernel.org/dri-devel/20250215-vop2-hdmi1-disp-modes-v1-3-81962a... [1] Reviewed-by: Sebastian Reichel sebastian.reichel@collabora.com Tested-by: Cristian Ciocaltea cristian.ciocaltea@collabora.com Signed-off-by: Heiko Stuebner heiko@sntech.de Link: https://lore.kernel.org/r/20250222223733.2990179-1-heiko@sntech.de [sboyd@kernel.org: Reword commit text a bit] Signed-off-by: Stephen Boyd sboyd@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/clk.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index cf7720b9172ff..50faafbf5dda5 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -5258,6 +5258,10 @@ of_clk_get_hw_from_clkspec(struct of_phandle_args *clkspec) if (!clkspec) return ERR_PTR(-EINVAL);
+ /* Check if node in clkspec is in disabled/fail state */ + if (!of_device_is_available(clkspec->np)) + return ERR_PTR(-ENOENT); + mutex_lock(&of_clk_mutex); list_for_each_entry(provider, &of_clk_providers, link) { if (provider->node == clkspec->np) {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu-Chun Lin eleanor15x@gmail.com
[ Upstream commit b899981750dcb958ceffa4462d903963ee494aa2 ]
As reported by the kernel test robot, the following error occurs:
arch/parisc/kernel/pdt.c:65:6: warning: no previous prototype for 'arch_report_meminfo' [-Wmissing-prototypes] 65 | void arch_report_meminfo(struct seq_file *m) | ^~~~~~~~~~~~~~~~~~~
arch_report_meminfo() is declared in include/linux/proc_fs.h and only defined when CONFIG_PROC_FS is enabled. Wrap its definition in #ifdef CONFIG_PROC_FS to fix the -Wmissing-prototypes warning.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202502082315.IPaHaTyM-lkp@intel.com/ Signed-off-by: Yu-Chun Lin eleanor15x@gmail.com Signed-off-by: Helge Deller deller@gmx.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/parisc/kernel/pdt.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/parisc/kernel/pdt.c b/arch/parisc/kernel/pdt.c index 0f9b3b5914cf6..b70b67adb855f 100644 --- a/arch/parisc/kernel/pdt.c +++ b/arch/parisc/kernel/pdt.c @@ -63,6 +63,7 @@ static unsigned long pdt_entry[MAX_PDT_ENTRIES] __page_aligned_bss; #define PDT_ADDR_PERM_ERR (pdt_type != PDT_PDC ? 2UL : 0UL) #define PDT_ADDR_SINGLE_ERR 1UL
+#ifdef CONFIG_PROC_FS /* report PDT entries via /proc/meminfo */ void arch_report_meminfo(struct seq_file *m) { @@ -74,6 +75,7 @@ void arch_report_meminfo(struct seq_file *m) seq_printf(m, "PDT_cur_entries: %7lu\n", pdt_status.pdt_entries); } +#endif
static int get_info_pat_new(void) {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li haoxiang_li2024@163.com
[ Upstream commit 3db42c75a921854a99db0a2775814fef97415bac ]
Add check for the return value of get_zeroed_page() in sclp_console_init() to prevent null pointer dereference. Furthermore, to solve the memory leak caused by the loop allocation, add a free helper to do the free job.
Signed-off-by: Haoxiang Li haoxiang_li2024@163.com Acked-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/20250218025216.2421548-1-haoxiang_li2024@163.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/char/sclp_con.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
diff --git a/drivers/s390/char/sclp_con.c b/drivers/s390/char/sclp_con.c index e5d947c763ea5..6a030ba38bf36 100644 --- a/drivers/s390/char/sclp_con.c +++ b/drivers/s390/char/sclp_con.c @@ -263,6 +263,19 @@ static struct console sclp_console = .index = 0 /* ttyS0 */ };
+/* + * Release allocated pages. + */ +static void __init __sclp_console_free_pages(void) +{ + struct list_head *page, *p; + + list_for_each_safe(page, p, &sclp_con_pages) { + list_del(page); + free_page((unsigned long)page); + } +} + /* * called by console_init() in drivers/char/tty_io.c at boot-time. */ @@ -282,6 +295,10 @@ sclp_console_init(void) /* Allocate pages for output buffering */ for (i = 0; i < sclp_console_pages; i++) { page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); + if (!page) { + __sclp_console_free_pages(); + return -ENOMEM; + } list_add_tail(page, &sclp_con_pages); } sclp_conbuf = NULL;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haoxiang Li haoxiang_li2024@163.com
[ Upstream commit ad9bb8f049717d64c5e62b2a44954be9f681c65b ]
The check for get_zeroed_page() leads to a direct return and overlooked the memory leak caused by loop allocation. Add a free helper to free spaces allocated by get_zeroed_page().
Signed-off-by: Haoxiang Li haoxiang_li2024@163.com Acked-by: Heiko Carstens hca@linux.ibm.com Link: https://lore.kernel.org/r/20250218034104.2436469-1-haoxiang_li2024@163.com Signed-off-by: Vasily Gorbik gor@linux.ibm.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/s390/char/sclp_tty.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
diff --git a/drivers/s390/char/sclp_tty.c b/drivers/s390/char/sclp_tty.c index 892c18d2f87e9..d3edacb6ee148 100644 --- a/drivers/s390/char/sclp_tty.c +++ b/drivers/s390/char/sclp_tty.c @@ -490,6 +490,17 @@ static const struct tty_operations sclp_ops = { .flush_buffer = sclp_tty_flush_buffer, };
+/* Release allocated pages. */ +static void __init __sclp_tty_free_pages(void) +{ + struct list_head *page, *p; + + list_for_each_safe(page, p, &sclp_tty_pages) { + list_del(page); + free_page((unsigned long)page); + } +} + static int __init sclp_tty_init(void) { @@ -516,6 +527,7 @@ sclp_tty_init(void) for (i = 0; i < MAX_KMEM_PAGES; i++) { page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA); if (page == NULL) { + __sclp_tty_free_pages(); tty_driver_kref_put(driver); return -ENOMEM; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das biju.das.jz@bp.renesas.com
[ Upstream commit 69ac2acd209a15bd7a61a15c9532a5b505252e1c ]
Avoid using the "- 1" for finding mstop_index in all functions accessing priv->mstop_count, by adjusting its pointer in rzv2h_cpg_probe().
While at it, drop the intermediate local variable index.
Reported-by: Geert Uytterhoeven geert+renesas@glider.be Closes: https://lore.kernel.org/all/CAMuHMdX1gPNCFddg_DyK7Bv0BeFLOLi=5eteT_HhMH=Ph2w... Signed-off-by: Biju Das biju.das.jz@bp.renesas.com Reviewed-by: Geert Uytterhoeven geert+renesas@glider.be Link: https://lore.kernel.org/20250222142009.41324-1-biju.das.jz@bp.renesas.com Signed-off-by: Geert Uytterhoeven geert+renesas@glider.be Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/clk/renesas/rzv2h-cpg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/clk/renesas/rzv2h-cpg.c b/drivers/clk/renesas/rzv2h-cpg.c index a4c1e92e1fd76..4e81a0bae0228 100644 --- a/drivers/clk/renesas/rzv2h-cpg.c +++ b/drivers/clk/renesas/rzv2h-cpg.c @@ -447,8 +447,7 @@ static void rzv2h_mod_clock_mstop_enable(struct rzv2h_cpg_priv *priv, { unsigned long mstop_mask = FIELD_GET(BUS_MSTOP_BITS_MASK, mstop_data); u16 mstop_index = FIELD_GET(BUS_MSTOP_IDX_MASK, mstop_data); - unsigned int index = (mstop_index - 1) * 16; - atomic_t *mstop = &priv->mstop_count[index]; + atomic_t *mstop = &priv->mstop_count[mstop_index * 16]; unsigned long flags; unsigned int i; u32 val = 0; @@ -469,8 +468,7 @@ static void rzv2h_mod_clock_mstop_disable(struct rzv2h_cpg_priv *priv, { unsigned long mstop_mask = FIELD_GET(BUS_MSTOP_BITS_MASK, mstop_data); u16 mstop_index = FIELD_GET(BUS_MSTOP_IDX_MASK, mstop_data); - unsigned int index = (mstop_index - 1) * 16; - atomic_t *mstop = &priv->mstop_count[index]; + atomic_t *mstop = &priv->mstop_count[mstop_index * 16]; unsigned long flags; unsigned int i; u32 val = 0; @@ -630,8 +628,7 @@ rzv2h_cpg_register_mod_clk(const struct rzv2h_mod_clk *mod, } else if (clock->mstop_data != BUS_MSTOP_NONE && mod->critical) { unsigned long mstop_mask = FIELD_GET(BUS_MSTOP_BITS_MASK, clock->mstop_data); u16 mstop_index = FIELD_GET(BUS_MSTOP_IDX_MASK, clock->mstop_data); - unsigned int index = (mstop_index - 1) * 16; - atomic_t *mstop = &priv->mstop_count[index]; + atomic_t *mstop = &priv->mstop_count[mstop_index * 16]; unsigned long flags; unsigned int i; u32 val = 0; @@ -926,6 +923,9 @@ static int __init rzv2h_cpg_probe(struct platform_device *pdev) if (!priv->mstop_count) return -ENOMEM;
+ /* Adjust for CPG_BUS_m_MSTOP starting from m = 1 */ + priv->mstop_count -= 16; + priv->resets = devm_kmemdup(dev, info->resets, sizeof(*info->resets) * info->num_resets, GFP_KERNEL); if (!priv->resets)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Feng Yang yangfeng@kylinos.cn
[ Upstream commit 339c1f8ea11cc042c30c315c1a8f61e4b8a90117 ]
The caller of cap_enable_effective() expects negative error code. Fix it.
Before: failed to restore CAP_SYS_ADMIN: -1, Unknown error -1
After: failed to restore CAP_SYS_ADMIN: -3, No such process failed to restore CAP_SYS_ADMIN: -22, Invalid argument
Signed-off-by: Feng Yang yangfeng@kylinos.cn Acked-by: Eduard Zingerman eddyz87@gmail.com Link: https://lore.kernel.org/r/20250305022234.44932-1-yangfeng59949@163.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/bpf/cap_helpers.c | 8 ++++---- tools/testing/selftests/bpf/cap_helpers.h | 1 + tools/testing/selftests/bpf/prog_tests/verifier.c | 4 ++-- tools/testing/selftests/bpf/test_loader.c | 6 +++--- 4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/bpf/cap_helpers.c b/tools/testing/selftests/bpf/cap_helpers.c index d5ac507401d7c..98f840c3a38f7 100644 --- a/tools/testing/selftests/bpf/cap_helpers.c +++ b/tools/testing/selftests/bpf/cap_helpers.c @@ -19,7 +19,7 @@ int cap_enable_effective(__u64 caps, __u64 *old_caps)
err = capget(&hdr, data); if (err) - return err; + return -errno;
if (old_caps) *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective; @@ -32,7 +32,7 @@ int cap_enable_effective(__u64 caps, __u64 *old_caps) data[1].effective |= cap1; err = capset(&hdr, data); if (err) - return err; + return -errno;
return 0; } @@ -49,7 +49,7 @@ int cap_disable_effective(__u64 caps, __u64 *old_caps)
err = capget(&hdr, data); if (err) - return err; + return -errno;
if (old_caps) *old_caps = (__u64)(data[1].effective) << 32 | data[0].effective; @@ -61,7 +61,7 @@ int cap_disable_effective(__u64 caps, __u64 *old_caps) data[1].effective &= ~cap1; err = capset(&hdr, data); if (err) - return err; + return -errno;
return 0; } diff --git a/tools/testing/selftests/bpf/cap_helpers.h b/tools/testing/selftests/bpf/cap_helpers.h index 6d163530cb0fd..8dcb28557f762 100644 --- a/tools/testing/selftests/bpf/cap_helpers.h +++ b/tools/testing/selftests/bpf/cap_helpers.h @@ -4,6 +4,7 @@
#include <linux/types.h> #include <linux/capability.h> +#include <errno.h>
#ifndef CAP_PERFMON #define CAP_PERFMON 38 diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c index 8a0e1ff8a2dc6..ecc320e045513 100644 --- a/tools/testing/selftests/bpf/prog_tests/verifier.c +++ b/tools/testing/selftests/bpf/prog_tests/verifier.c @@ -121,7 +121,7 @@ static void run_tests_aux(const char *skel_name, /* test_verifier tests are executed w/o CAP_SYS_ADMIN, do the same here */ err = cap_disable_effective(1ULL << CAP_SYS_ADMIN, &old_caps); if (err) { - PRINT_FAIL("failed to drop CAP_SYS_ADMIN: %i, %s\n", err, strerror(err)); + PRINT_FAIL("failed to drop CAP_SYS_ADMIN: %i, %s\n", err, strerror(-err)); return; }
@@ -131,7 +131,7 @@ static void run_tests_aux(const char *skel_name,
err = cap_enable_effective(old_caps, NULL); if (err) - PRINT_FAIL("failed to restore CAP_SYS_ADMIN: %i, %s\n", err, strerror(err)); + PRINT_FAIL("failed to restore CAP_SYS_ADMIN: %i, %s\n", err, strerror(-err)); }
#define RUN(skel) run_tests_aux(#skel, skel##__elf_bytes, NULL) diff --git a/tools/testing/selftests/bpf/test_loader.c b/tools/testing/selftests/bpf/test_loader.c index 53b06647cf57d..8a403e5aa3145 100644 --- a/tools/testing/selftests/bpf/test_loader.c +++ b/tools/testing/selftests/bpf/test_loader.c @@ -773,7 +773,7 @@ static int drop_capabilities(struct cap_state *caps)
err = cap_disable_effective(caps_to_drop, &caps->old_caps); if (err) { - PRINT_FAIL("failed to drop capabilities: %i, %s\n", err, strerror(err)); + PRINT_FAIL("failed to drop capabilities: %i, %s\n", err, strerror(-err)); return err; }
@@ -790,7 +790,7 @@ static int restore_capabilities(struct cap_state *caps)
err = cap_enable_effective(caps->old_caps, NULL); if (err) - PRINT_FAIL("failed to restore capabilities: %i, %s\n", err, strerror(err)); + PRINT_FAIL("failed to restore capabilities: %i, %s\n", err, strerror(-err)); caps->initialized = false; return err; } @@ -959,7 +959,7 @@ void run_subtest(struct test_loader *tester, if (subspec->caps) { err = cap_enable_effective(subspec->caps, NULL); if (err) { - PRINT_FAIL("failed to set capabilities: %i, %s\n", err, strerror(err)); + PRINT_FAIL("failed to set capabilities: %i, %s\n", err, strerror(-err)); goto subtest_cleanup; } }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sewon Nam swnam0729@gmail.com
[ Upstream commit 02a4694107b4c830d4bd6d194e98b3ac0bc86f29 ]
We are missing setting error code in do_loader() when bpf_object__open_file() fails. This means the command's exit status code will be successful, even though the operation failed. So make sure to return the correct error code. To maintain consistency with other locations where bpf_object__open_file() is called, return -1.
[0] Closes: https://github.com/libbpf/bpftool/issues/156
Reported-by: Dan Carpenter dan.carpenter@linaro.org Signed-off-by: Sewon Nam swnam0729@gmail.com Signed-off-by: Andrii Nakryiko andrii@kernel.org Tested-by: Quentin Monnet qmo@kernel.org Reviewed-by: Quentin Monnet qmo@kernel.org Link: https://lore.kernel.org/bpf/d3b5b4b4-19bb-4619-b4dd-86c958c4a367@stanley.mou... Link: https://lore.kernel.org/bpf/20250311031238.14865-1-swnam0729@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/bpf/bpftool/prog.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index e71be67f1d865..52ffb74ae4e89 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -1928,6 +1928,7 @@ static int do_loader(int argc, char **argv)
obj = bpf_object__open_file(file, &open_opts); if (!obj) { + err = -1; p_err("failed to open object file"); goto err_close_obj; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin KaFai Lau martin.lau@kernel.org
[ Upstream commit f4edc66e48a694b3e6d164cc71f059de542dfaec ]
The current cgrp storage has a percpu counter, bpf_cgrp_storage_busy, to detect potential deadlock at a spin_lock that the local storage acquires during new storage creation.
There are false positives. It turns out to be too noisy in production. For example, a bpf prog may be doing a bpf_cgrp_storage_get on map_a. An IRQ comes in and triggers another bpf_cgrp_storage_get on a different map_b. It will then trigger the false positive deadlock check in the percpu counter. On top of that, both are doing lookup only and no need to create new storage, so practically it does not need to acquire the spin_lock.
The bpf_task_storage_get already has a strategy to minimize this false positive by only failing if the bpf_task_storage_get needs to create a new storage and the percpu counter is busy. Creating a new storage is the only time it must acquire the spin_lock.
This patch borrows the same idea. Unlike task storage that has a separate variant for tracing (_recur) and non-tracing, this patch stays with one bpf_cgrp_storage_get helper to keep it simple for now in light of the upcoming res_spin_lock.
The variable could potentially use a better name noTbusy instead of nobusy. This patch follows the same naming in bpf_task_storage_get for now.
I have tested it by temporarily adding noinline to the cgroup_storage_lookup(), traced it by fentry, and the fentry program succeeded in calling bpf_cgrp_storage_get().
Signed-off-by: Martin KaFai Lau martin.lau@kernel.org Link: https://lore.kernel.org/r/20250318182759.3676094-1-martin.lau@linux.dev Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/bpf_cgrp_storage.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/kernel/bpf/bpf_cgrp_storage.c b/kernel/bpf/bpf_cgrp_storage.c index 54ff2a85d4c02..148da8f7ff368 100644 --- a/kernel/bpf/bpf_cgrp_storage.c +++ b/kernel/bpf/bpf_cgrp_storage.c @@ -161,6 +161,7 @@ BPF_CALL_5(bpf_cgrp_storage_get, struct bpf_map *, map, struct cgroup *, cgroup, void *, value, u64, flags, gfp_t, gfp_flags) { struct bpf_local_storage_data *sdata; + bool nobusy;
WARN_ON_ONCE(!bpf_rcu_lock_held()); if (flags & ~(BPF_LOCAL_STORAGE_GET_F_CREATE)) @@ -169,21 +170,21 @@ BPF_CALL_5(bpf_cgrp_storage_get, struct bpf_map *, map, struct cgroup *, cgroup, if (!cgroup) return (unsigned long)NULL;
- if (!bpf_cgrp_storage_trylock()) - return (unsigned long)NULL; + nobusy = bpf_cgrp_storage_trylock();
- sdata = cgroup_storage_lookup(cgroup, map, true); + sdata = cgroup_storage_lookup(cgroup, map, nobusy); if (sdata) goto unlock;
/* only allocate new storage, when the cgroup is refcounted */ if (!percpu_ref_is_dying(&cgroup->self.refcnt) && - (flags & BPF_LOCAL_STORAGE_GET_F_CREATE)) + (flags & BPF_LOCAL_STORAGE_GET_F_CREATE) && nobusy) sdata = bpf_local_storage_update(cgroup, (struct bpf_local_storage_map *)map, value, BPF_NOEXIST, false, gfp_flags);
unlock: - bpf_cgrp_storage_unlock(); + if (nobusy) + bpf_cgrp_storage_unlock(); return IS_ERR_OR_NULL(sdata) ? (unsigned long)NULL : (unsigned long)sdata->data; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yafang Shao laoar.shao@gmail.com
[ Upstream commit cfe816d469dce9c0864062cf65dd7b3c42adc6f8 ]
If we attach fexit/fmod_ret to __noreturn functions, it will cause an issue that the bpf trampoline image will be left over even if the bpf link has been destroyed. Take attaching do_exit() with fexit for example. The fexit works as follows,
bpf_trampoline + __bpf_tramp_enter + percpu_ref_get(&tr->pcref);
+ call do_exit()
+ __bpf_tramp_exit + percpu_ref_put(&tr->pcref);
Since do_exit() never returns, the refcnt of the trampoline image is never decremented, preventing it from being freed. That can be verified with as follows,
$ bpftool link show <<<< nothing output $ grep "bpf_trampoline_[0-9]" /proc/kallsyms ffffffffc04cb000 t bpf_trampoline_6442526459 [bpf] <<<< leftover
In this patch, all functions annotated with __noreturn are rejected, except for the following cases: - Functions that result in a system reboot, such as panic, machine_real_restart and rust_begin_unwind - Functions that are never executed by tasks, such as rest_init and cpu_startup_entry - Functions implemented in assembly, such as rewind_stack_and_make_dead and xen_cpu_bringup_again, lack an associated BTF ID.
With this change, attaching fexit probes to functions like do_exit() will be rejected.
$ ./fexit libbpf: prog 'fexit': BPF program load failed: -EINVAL libbpf: prog 'fexit': -- BEGIN PROG LOAD LOG -- Attaching fexit/fmod_ret to __noreturn functions is rejected.
Signed-off-by: Yafang Shao laoar.shao@gmail.com Link: https://lore.kernel.org/r/20250318114447.75484-2-laoar.shao@gmail.com Signed-off-by: Alexei Starovoitov ast@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index c6f3b5f4ff2be..db95b76f5c139 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -22863,6 +22863,33 @@ BTF_ID(func, __rcu_read_unlock) #endif BTF_SET_END(btf_id_deny)
+/* fexit and fmod_ret can't be used to attach to __noreturn functions. + * Currently, we must manually list all __noreturn functions here. Once a more + * robust solution is implemented, this workaround can be removed. + */ +BTF_SET_START(noreturn_deny) +#ifdef CONFIG_IA32_EMULATION +BTF_ID(func, __ia32_sys_exit) +BTF_ID(func, __ia32_sys_exit_group) +#endif +#ifdef CONFIG_KUNIT +BTF_ID(func, __kunit_abort) +BTF_ID(func, kunit_try_catch_throw) +#endif +#ifdef CONFIG_MODULES +BTF_ID(func, __module_put_and_kthread_exit) +#endif +#ifdef CONFIG_X86_64 +BTF_ID(func, __x64_sys_exit) +BTF_ID(func, __x64_sys_exit_group) +#endif +BTF_ID(func, do_exit) +BTF_ID(func, do_group_exit) +BTF_ID(func, kthread_complete_and_exit) +BTF_ID(func, kthread_exit) +BTF_ID(func, make_task_dead) +BTF_SET_END(noreturn_deny) + static bool can_be_sleepable(struct bpf_prog *prog) { if (prog->type == BPF_PROG_TYPE_TRACING) { @@ -22951,6 +22978,11 @@ static int check_attach_btf_id(struct bpf_verifier_env *env) } else if (prog->type == BPF_PROG_TYPE_TRACING && btf_id_set_contains(&btf_id_deny, btf_id)) { return -EINVAL; + } else if ((prog->expected_attach_type == BPF_TRACE_FEXIT || + prog->expected_attach_type == BPF_MODIFY_RETURN) && + btf_id_set_contains(&noreturn_deny, btf_id)) { + verbose(env, "Attaching fexit/fmod_ret to __noreturn functions is rejected.\n"); + return -EINVAL; }
key = bpf_trampoline_compute_key(tgt_prog, prog->aux->attach_btf, btf_id);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huisong Li lihuisong@huawei.com
[ Upstream commit 9779d45c749340ab461d595c1a4a664cb28f3007 ]
The function mbox_chan_received_data() calls the Rx callback of the mailbox client driver. The callback might set chan_in_use flag from pcc_send_data(). This flag's status determines whether the PCC channel is in use.
However, there is a potential race condition where chan_in_use is updated incorrectly due to concurrency between the interrupt handler (pcc_mbox_irq()) and the command sender(pcc_send_data()).
The 'chan_in_use' flag of a channel is set to true after sending a command. And the flag of the new command may be cleared erroneous by the interrupt handler afer mbox_chan_received_data() returns,
As a result, the interrupt being level triggered can't be cleared in pcc_mbox_irq() and it will be disabled after the number of handled times exceeds the specified value. The error log is as follows:
| kunpeng_hccs HISI04B2:00: PCC command executed timeout! | kunpeng_hccs HISI04B2:00: get port link status info failed, ret = -110 | irq 13: nobody cared (try booting with the "irqpoll" option) | Call trace: | dump_backtrace+0x0/0x210 | show_stack+0x1c/0x2c | dump_stack+0xec/0x130 | __report_bad_irq+0x50/0x190 | note_interrupt+0x1e4/0x260 | handle_irq_event+0x144/0x17c | handle_fasteoi_irq+0xd0/0x240 | __handle_domain_irq+0x80/0xf0 | gic_handle_irq+0x74/0x2d0 | el1_irq+0xbc/0x140 | mnt_clone_write+0x0/0x70 | file_update_time+0xcc/0x160 | fault_dirty_shared_page+0xe8/0x150 | do_shared_fault+0x80/0x1d0 | do_fault+0x118/0x1a4 | handle_pte_fault+0x154/0x230 | __handle_mm_fault+0x1ac/0x390 | handle_mm_fault+0xf0/0x250 | do_page_fault+0x184/0x454 | do_translation_fault+0xac/0xd4 | do_mem_abort+0x44/0xb4 | el0_da+0x40/0x74 | el0_sync_handler+0x60/0xb4 | el0_sync+0x168/0x180 | handlers: | pcc_mbox_irq | Disabling IRQ #13
To solve this issue, pcc_mbox_irq() must clear 'chan_in_use' flag before the call to mbox_chan_received_data().
Tested-by: Adam Young admiyo@os.amperecomputing.com Tested-by: Robbie King robbiek@xsightlabs.com Signed-off-by: Huisong Li lihuisong@huawei.com (sudeep.holla: Minor updates to the subject, commit message and comment) Signed-off-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Jassi Brar jassisinghbrar@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/pcc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 82102a4c5d688..8fd4d0f79b090 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -333,10 +333,16 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack)) return IRQ_NONE;
+ /* + * Clear this flag after updating interrupt ack register and just + * before mbox_chan_received_data() which might call pcc_send_data() + * where the flag is set again to start new transfer. This is + * required to avoid any possible race in updatation of this flag. + */ + pchan->chan_in_use = false; mbox_chan_received_data(chan, NULL);
check_and_ack(pchan, chan); - pchan->chan_in_use = false;
return IRQ_HANDLED; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sudeep Holla sudeep.holla@arm.com
[ Upstream commit cf1338c0e02880cd235a4590eeb15e2039c873bc ]
The PCC mailbox interrupt handler (pcc_mbox_irq()) currently checks for command completion flags and any error status before clearing the interrupt.
The below sequence highlights an issue in the handling of PCC mailbox interrupts, specifically when dealing with doorbell notifications and acknowledgment between the OSPM and the platform where type3 and type4 channels are sharing the interrupt.
------------------------------------------------------------------------- | T | Platform Firmware | OSPM/Linux PCC driver | |---|---------------------------------|---------------------------------| | 1 | | Build message in shmem | | 2 | | Ring Type3 chan doorbell | | 3 | Receives the doorbell interrupt | | | 4 | Process the message from OSPM | | | 5 | Build response for the message | | | 6 | Ring Platform ACK interrupt on | | | | Type3 chan to OSPM | Received the interrupt | | 7 | Build Notification in Type4 Chan| | | 8 | | Start processing interrupt in | | | | pcc_mbox_irq() handler | | 9 | | Enter PCC handler for Type4 chan| |10 | | Check command complete cleared | |11 | | Read the notification | |12 | | Clear Platform ACK interrupt | | | No effect from the previous step yet as the Platform ACK | | | interrupt has not yet been triggered for this channel | |13 | Ring Platform ACK interrupt on | | | | Type4 chan to OSPM | | |14 | | Enter PCC handler for Type3 chan| |15 | | Command complete is set. | |16 | | Read the response. | |17 | | Clear Platform ACK interrupt | |18 | | Leave PCC handler for Type3 | |19 | | Leave pcc_mbox_irq() handler | |20 | | Re-enter pcc_mbox_irq() handler | |21 | | Enter PCC handler for Type4 chan| |22 | | Leave PCC handler for Type4 chan| |23 | | Enter PCC handler for Type3 chan| |24 | | Leave PCC handler for Type3 chan| |25 | | Leave pcc_mbox_irq() handler | -------------------------------------------------------------------------
The key issue occurs when OSPM tries to acknowledge platform ack interrupt for a notification which is ready to be read and processed but the interrupt itself is not yet triggered by the platform.
This ineffective acknowledgment leads to an issue later in time where the interrupt remains pending as we exit the interrupt handler without clearing the platform ack interrupt as there is no pending response or notification. The interrupt acknowledgment order is incorrect.
To resolve this issue, the platform acknowledgment interrupt should always be cleared before processing the interrupt for any notifications or response.
Reported-by: Robbie King robbiek@xsightlabs.com Reviewed-by: Huisong Li lihuisong@huawei.com Tested-by: Huisong Li lihuisong@huawei.com Tested-by: Adam Young admiyo@os.amperecomputing.com Tested-by: Robbie King robbiek@xsightlabs.com Signed-off-by: Sudeep Holla sudeep.holla@arm.com Signed-off-by: Jassi Brar jassisinghbrar@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/mailbox/pcc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 8fd4d0f79b090..f8215a8f656a4 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -313,6 +313,10 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) int ret;
pchan = chan->con_priv; + + if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack)) + return IRQ_NONE; + if (pchan->type == ACPI_PCCT_TYPE_EXT_PCC_MASTER_SUBSPACE && !pchan->chan_in_use) return IRQ_NONE; @@ -330,9 +334,6 @@ static irqreturn_t pcc_mbox_irq(int irq, void *p) return IRQ_NONE; }
- if (pcc_chan_reg_read_modify_write(&pchan->plat_irq_ack)) - return IRQ_NONE; - /* * Clear this flag after updating interrupt ack register and just * before mbox_chan_received_data() which might call pcc_send_data()
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Penkler dpenkler@gmail.com
[ Upstream commit 76d54fd5471b10ee993c217928a39d7351eaff5c ]
In the accel read and write functions the transfer length was being calculated by an if statement setting it to the lesser of the remaining bytes to read/write and the fifo size.
Replace both instances with min() which is clearer and more compact.
Reported-by: kernel test robot lkp@intel.com Reported-by: Julia Lawall julia.lawall@inria.fr Closes: https://lore.kernel.org/r/202501182153.qHfL4Fbc-lkp@intel.com/ Signed-off-by: Dave Penkler dpenkler@gmail.com Link: https://lore.kernel.org/r/20250120145030.29684-1-dpenkler@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/staging/gpib/agilent_82350b/agilent_82350b.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c index c62407077d37f..cd7fe7d814cea 100644 --- a/drivers/staging/gpib/agilent_82350b/agilent_82350b.c +++ b/drivers/staging/gpib/agilent_82350b/agilent_82350b.c @@ -66,10 +66,7 @@ int agilent_82350b_accel_read(gpib_board_t *board, uint8_t *buffer, size_t lengt int j; int count;
- if (num_fifo_bytes - i < agilent_82350b_fifo_size) - block_size = num_fifo_bytes - i; - else - block_size = agilent_82350b_fifo_size; + block_size = min(num_fifo_bytes - i, agilent_82350b_fifo_size); set_transfer_counter(a_priv, block_size); writeb(ENABLE_TI_TO_SRAM | DIRECTION_GPIB_TO_HOST, a_priv->gpib_base + SRAM_ACCESS_CONTROL_REG); @@ -200,10 +197,7 @@ int agilent_82350b_accel_write(gpib_board_t *board, uint8_t *buffer, size_t leng for (i = 1; i < fifotransferlength;) { clear_bit(WRITE_READY_BN, &tms_priv->state);
- if (fifotransferlength - i < agilent_82350b_fifo_size) - block_size = fifotransferlength - i; - else - block_size = agilent_82350b_fifo_size; + block_size = min(fifotransferlength - i, agilent_82350b_fifo_size); set_transfer_counter(a_priv, block_size); for (j = 0; j < block_size; ++j, ++i) { // load data into board's sram
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Stein alexander.stein@mailbox.org
[ Upstream commit 41d5e3806cf589f658f92c75195095df0b66f66a ]
"maxim,max3421" DT compatible is missing its SPI device ID entry, not allowing module autoloading and leading to the following message: "SPI driver max3421-hcd has no spi_device_id for maxim,max3421"
Fix this by adding the spi_device_id table.
Signed-off-by: Alexander Stein alexander.stein@mailbox.org Link: https://lore.kernel.org/r/20250128195114.56321-1-alexander.stein@mailbox.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/max3421-hcd.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/drivers/usb/host/max3421-hcd.c b/drivers/usb/host/max3421-hcd.c index 0881fdd1823e0..dcf31a592f5d1 100644 --- a/drivers/usb/host/max3421-hcd.c +++ b/drivers/usb/host/max3421-hcd.c @@ -1946,6 +1946,12 @@ max3421_remove(struct spi_device *spi) usb_put_hcd(hcd); }
+static const struct spi_device_id max3421_spi_ids[] = { + { "max3421" }, + { }, +}; +MODULE_DEVICE_TABLE(spi, max3421_spi_ids); + static const struct of_device_id max3421_of_match_table[] = { { .compatible = "maxim,max3421", }, {}, @@ -1955,6 +1961,7 @@ MODULE_DEVICE_TABLE(of, max3421_of_match_table); static struct spi_driver max3421_driver = { .probe = max3421_probe, .remove = max3421_remove, + .id_table = max3421_spi_ids, .driver = { .name = "max3421-hcd", .of_match_table = max3421_of_match_table,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 667ecac55861281c1f5e107c8550ae893b3984f6 ]
Some of the drivers emulate or handle some of the commands in the platform-specific way. The code ends up being split between several callbacks, which complicates emulation.
In preparation to reworking such drivers, move read_cci() and read_message_in() calls into ucsi_sync_control_common().
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Łukasz Bartosik ukaszb@chromium.org Link: https://lore.kernel.org/r/20250120-ucsi-merge-commands-v2-1-462a1ec22ecc@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/ucsi/cros_ec_ucsi.c | 5 +++-- drivers/usb/typec/ucsi/ucsi.c | 19 +++++++++++-------- drivers/usb/typec/ucsi/ucsi.h | 6 ++++-- drivers/usb/typec/ucsi/ucsi_acpi.c | 5 +++-- drivers/usb/typec/ucsi/ucsi_ccg.c | 5 +++-- 5 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/drivers/usb/typec/ucsi/cros_ec_ucsi.c b/drivers/usb/typec/ucsi/cros_ec_ucsi.c index c605c86167268..744f0709a40ed 100644 --- a/drivers/usb/typec/ucsi/cros_ec_ucsi.c +++ b/drivers/usb/typec/ucsi/cros_ec_ucsi.c @@ -105,12 +105,13 @@ static int cros_ucsi_async_control(struct ucsi *ucsi, u64 cmd) return 0; }
-static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd) +static int cros_ucsi_sync_control(struct ucsi *ucsi, u64 cmd, u32 *cci, + void *data, size_t size) { struct cros_ucsi_data *udata = ucsi_get_drvdata(ucsi); int ret;
- ret = ucsi_sync_control_common(ucsi, cmd); + ret = ucsi_sync_control_common(ucsi, cmd, cci, data, size); switch (ret) { case -EBUSY: /* EC may return -EBUSY if CCI.busy is set. diff --git a/drivers/usb/typec/ucsi/ucsi.c b/drivers/usb/typec/ucsi/ucsi.c index 2a2915b0a645f..e8c7e9dc49309 100644 --- a/drivers/usb/typec/ucsi/ucsi.c +++ b/drivers/usb/typec/ucsi/ucsi.c @@ -55,7 +55,8 @@ void ucsi_notify_common(struct ucsi *ucsi, u32 cci) } EXPORT_SYMBOL_GPL(ucsi_notify_common);
-int ucsi_sync_control_common(struct ucsi *ucsi, u64 command) +int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci, + void *data, size_t size) { bool ack = UCSI_COMMAND(command) == UCSI_ACK_CC_CI; int ret; @@ -80,6 +81,13 @@ int ucsi_sync_control_common(struct ucsi *ucsi, u64 command) else clear_bit(COMMAND_PENDING, &ucsi->flags);
+ if (!ret && cci) + ret = ucsi->ops->read_cci(ucsi, cci); + + if (!ret && data && + (*cci & UCSI_CCI_COMMAND_COMPLETE)) + ret = ucsi->ops->read_message_in(ucsi, data, size); + return ret; } EXPORT_SYMBOL_GPL(ucsi_sync_control_common); @@ -95,7 +103,7 @@ static int ucsi_acknowledge(struct ucsi *ucsi, bool conn_ack) ctrl |= UCSI_ACK_CONNECTOR_CHANGE; }
- return ucsi->ops->sync_control(ucsi, ctrl); + return ucsi->ops->sync_control(ucsi, ctrl, NULL, NULL, 0); }
static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, @@ -108,9 +116,7 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, if (size > UCSI_MAX_DATA_LENGTH(ucsi)) return -EINVAL;
- ret = ucsi->ops->sync_control(ucsi, command); - if (ucsi->ops->read_cci(ucsi, cci)) - return -EIO; + ret = ucsi->ops->sync_control(ucsi, command, cci, data, size);
if (*cci & UCSI_CCI_BUSY) return ucsi_run_command(ucsi, UCSI_CANCEL, cci, NULL, 0, false) ?: -EBUSY; @@ -127,9 +133,6 @@ static int ucsi_run_command(struct ucsi *ucsi, u64 command, u32 *cci, else err = 0;
- if (!err && data && UCSI_CCI_LENGTH(*cci)) - err = ucsi->ops->read_message_in(ucsi, data, size); - /* * Don't ACK connection change if there was an error. */ diff --git a/drivers/usb/typec/ucsi/ucsi.h b/drivers/usb/typec/ucsi/ucsi.h index 28780acc4af2e..892bcf8dbcd50 100644 --- a/drivers/usb/typec/ucsi/ucsi.h +++ b/drivers/usb/typec/ucsi/ucsi.h @@ -79,7 +79,8 @@ struct ucsi_operations { int (*read_cci)(struct ucsi *ucsi, u32 *cci); int (*poll_cci)(struct ucsi *ucsi, u32 *cci); int (*read_message_in)(struct ucsi *ucsi, void *val, size_t val_len); - int (*sync_control)(struct ucsi *ucsi, u64 command); + int (*sync_control)(struct ucsi *ucsi, u64 command, u32 *cci, + void *data, size_t size); int (*async_control)(struct ucsi *ucsi, u64 command); bool (*update_altmodes)(struct ucsi *ucsi, struct ucsi_altmode *orig, struct ucsi_altmode *updated); @@ -531,7 +532,8 @@ void ucsi_altmode_update_active(struct ucsi_connector *con); int ucsi_resume(struct ucsi *ucsi);
void ucsi_notify_common(struct ucsi *ucsi, u32 cci); -int ucsi_sync_control_common(struct ucsi *ucsi, u64 command); +int ucsi_sync_control_common(struct ucsi *ucsi, u64 command, u32 *cci, + void *data, size_t size);
#if IS_ENABLED(CONFIG_POWER_SUPPLY) int ucsi_register_port_psy(struct ucsi_connector *con); diff --git a/drivers/usb/typec/ucsi/ucsi_acpi.c b/drivers/usb/typec/ucsi/ucsi_acpi.c index ac1ebb5d95272..0ac6e5ce4a288 100644 --- a/drivers/usb/typec/ucsi/ucsi_acpi.c +++ b/drivers/usb/typec/ucsi/ucsi_acpi.c @@ -128,12 +128,13 @@ static int ucsi_gram_read_message_in(struct ucsi *ucsi, void *val, size_t val_le return ret; }
-static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command) +static int ucsi_gram_sync_control(struct ucsi *ucsi, u64 command, u32 *cci, + void *data, size_t size) { struct ucsi_acpi *ua = ucsi_get_drvdata(ucsi); int ret;
- ret = ucsi_sync_control_common(ucsi, command); + ret = ucsi_sync_control_common(ucsi, command, cci, data, size); if (ret < 0) return ret;
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index 511dd1b224ae5..43a8a67159d84 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -628,7 +628,8 @@ static int ucsi_ccg_async_control(struct ucsi *ucsi, u64 command) return ccg_write(uc, reg, (u8 *)&command, sizeof(command)); }
-static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) +static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci, + void *data, size_t size) { struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); struct ucsi_connector *con; @@ -652,7 +653,7 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command) ucsi_ccg_update_set_new_cam_cmd(uc, con, &command); }
- ret = ucsi_sync_control_common(ucsi, command); + ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
err_put: pm_runtime_put_sync(uc->dev);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Baryshkov dmitry.baryshkov@linaro.org
[ Upstream commit 7f82635494ef3391ff6b542249793c7febf99c3f ]
It is easier to keep all command-specific quirks in a single place. Move them to ucsi_ccg_sync_control() as the code now allows us to return modified messages data.
Signed-off-by: Dmitry Baryshkov dmitry.baryshkov@linaro.org Reviewed-by: Heikki Krogerus heikki.krogerus@linux.intel.com Link: https://lore.kernel.org/r/20250120-ucsi-merge-commands-v2-2-462a1ec22ecc@lin... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/typec/ucsi/ucsi_ccg.c | 62 +++++++++++++++---------------- 1 file changed, 29 insertions(+), 33 deletions(-)
diff --git a/drivers/usb/typec/ucsi/ucsi_ccg.c b/drivers/usb/typec/ucsi/ucsi_ccg.c index 43a8a67159d84..c1d776c82fc2e 100644 --- a/drivers/usb/typec/ucsi/ucsi_ccg.c +++ b/drivers/usb/typec/ucsi/ucsi_ccg.c @@ -222,7 +222,6 @@ struct ucsi_ccg { u16 fw_build; struct work_struct pm_work;
- u64 last_cmd_sent; bool has_multiple_dp; struct ucsi_ccg_altmode orig[UCSI_MAX_ALTMODES]; struct ucsi_ccg_altmode updated[UCSI_MAX_ALTMODES]; @@ -538,9 +537,10 @@ static void ucsi_ccg_update_set_new_cam_cmd(struct ucsi_ccg *uc, * first and then vdo=0x3 */ static void ucsi_ccg_nvidia_altmode(struct ucsi_ccg *uc, - struct ucsi_altmode *alt) + struct ucsi_altmode *alt, + u64 command) { - switch (UCSI_ALTMODE_OFFSET(uc->last_cmd_sent)) { + switch (UCSI_ALTMODE_OFFSET(command)) { case NVIDIA_FTB_DP_OFFSET: if (alt[0].mid == USB_TYPEC_NVIDIA_VLINK_DBG_VDO) alt[0].mid = USB_TYPEC_NVIDIA_VLINK_DP_VDO | @@ -578,37 +578,11 @@ static int ucsi_ccg_read_cci(struct ucsi *ucsi, u32 *cci) static int ucsi_ccg_read_message_in(struct ucsi *ucsi, void *val, size_t val_len) { struct ucsi_ccg *uc = ucsi_get_drvdata(ucsi); - struct ucsi_capability *cap; - struct ucsi_altmode *alt;
spin_lock(&uc->op_lock); memcpy(val, uc->op_data.message_in, val_len); spin_unlock(&uc->op_lock);
- switch (UCSI_COMMAND(uc->last_cmd_sent)) { - case UCSI_GET_CURRENT_CAM: - if (uc->has_multiple_dp) - ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)val); - break; - case UCSI_GET_ALTERNATE_MODES: - if (UCSI_ALTMODE_RECIPIENT(uc->last_cmd_sent) == - UCSI_RECIPIENT_SOP) { - alt = val; - if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID) - ucsi_ccg_nvidia_altmode(uc, alt); - } - break; - case UCSI_GET_CAPABILITY: - if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) { - cap = val; - cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS; - } - break; - default: - break; - } - uc->last_cmd_sent = 0; - return 0; }
@@ -639,11 +613,9 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci, mutex_lock(&uc->lock); pm_runtime_get_sync(uc->dev);
- uc->last_cmd_sent = command; - - if (UCSI_COMMAND(uc->last_cmd_sent) == UCSI_SET_NEW_CAM && + if (UCSI_COMMAND(command) == UCSI_SET_NEW_CAM && uc->has_multiple_dp) { - con_index = (uc->last_cmd_sent >> 16) & + con_index = (command >> 16) & UCSI_CMD_CONNECTOR_MASK; if (con_index == 0) { ret = -EINVAL; @@ -655,6 +627,30 @@ static int ucsi_ccg_sync_control(struct ucsi *ucsi, u64 command, u32 *cci,
ret = ucsi_sync_control_common(ucsi, command, cci, data, size);
+ switch (UCSI_COMMAND(command)) { + case UCSI_GET_CURRENT_CAM: + if (uc->has_multiple_dp) + ucsi_ccg_update_get_current_cam_cmd(uc, (u8 *)data); + break; + case UCSI_GET_ALTERNATE_MODES: + if (UCSI_ALTMODE_RECIPIENT(command) == UCSI_RECIPIENT_SOP) { + struct ucsi_altmode *alt = data; + + if (alt[0].svid == USB_TYPEC_NVIDIA_VLINK_SID) + ucsi_ccg_nvidia_altmode(uc, alt, command); + } + break; + case UCSI_GET_CAPABILITY: + if (uc->fw_build == CCG_FW_BUILD_NVIDIA_TEGRA) { + struct ucsi_capability *cap = data; + + cap->features &= ~UCSI_CAP_ALT_MODE_DETAILS; + } + break; + default: + break; + } + err_put: pm_runtime_put_sync(uc->dev); mutex_unlock(&uc->lock);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Trevor Gamblin tgamblin@baylibre.com
[ Upstream commit 998d20e4e99d909f14d96fdf0bdcf860f7efe3ef ]
Ensure that conversion mode is successfully exited when the command is issued by adding an extra transfer beforehand, matching the minimum CNV high and low times from the AD4695 datasheet. The AD4695 has a quirk where the exit command only works during a conversion, so guarantee this happens by triggering a conversion in ad4695_exit_conversion_mode(). Then make this even more robust by ensuring that the exit command is run at AD4695_REG_ACCESS_SCLK_HZ rather than the bus maximum.
Signed-off-by: Trevor Gamblin tgamblin@baylibre.com Reviewed-by: David Lechner dlechner@baylibre.com Tested-by: David Lechner dlechner@baylibre.com Link: https://patch.msgid.link/20241113-tgamblin-ad4695_improvements-v2-2-b6bb7c75... Signed-off-by: Jonathan Cameron Jonathan.Cameron@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iio/adc/ad4695.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/drivers/iio/adc/ad4695.c b/drivers/iio/adc/ad4695.c index b79d135a54718..22fdc454b0cea 100644 --- a/drivers/iio/adc/ad4695.c +++ b/drivers/iio/adc/ad4695.c @@ -92,6 +92,8 @@ #define AD4695_T_REFBUF_MS 100 #define AD4695_T_REGCONFIG_NS 20 #define AD4695_T_SCK_CNV_DELAY_NS 80 +#define AD4695_T_CNVL_NS 80 +#define AD4695_T_CNVH_NS 10 #define AD4695_REG_ACCESS_SCLK_HZ (10 * MEGA)
/* Max number of voltage input channels. */ @@ -364,11 +366,31 @@ static int ad4695_enter_advanced_sequencer_mode(struct ad4695_state *st, u32 n) */ static int ad4695_exit_conversion_mode(struct ad4695_state *st) { - struct spi_transfer xfer = { - .tx_buf = &st->cnv_cmd2, - .len = 1, - .delay.value = AD4695_T_REGCONFIG_NS, - .delay.unit = SPI_DELAY_UNIT_NSECS, + /* + * An extra transfer is needed to trigger a conversion here so + * that we can be 100% sure the command will be processed by the + * ADC, rather than relying on it to be in the correct state + * when this function is called (this chip has a quirk where the + * command only works when reading a conversion, and if the + * previous conversion was already read then it won't work). The + * actual conversion command is then run at the slower + * AD4695_REG_ACCESS_SCLK_HZ speed to guarantee this works. + */ + struct spi_transfer xfers[] = { + { + .delay.value = AD4695_T_CNVL_NS, + .delay.unit = SPI_DELAY_UNIT_NSECS, + .cs_change = 1, + .cs_change_delay.value = AD4695_T_CNVH_NS, + .cs_change_delay.unit = SPI_DELAY_UNIT_NSECS, + }, + { + .speed_hz = AD4695_REG_ACCESS_SCLK_HZ, + .tx_buf = &st->cnv_cmd2, + .len = 1, + .delay.value = AD4695_T_REGCONFIG_NS, + .delay.unit = SPI_DELAY_UNIT_NSECS, + }, };
/* @@ -377,7 +399,7 @@ static int ad4695_exit_conversion_mode(struct ad4695_state *st) */ st->cnv_cmd2 = AD4695_CMD_EXIT_CNV_MODE << 3;
- return spi_sync_transfer(st->spi, &xfer, 1); + return spi_sync_transfer(st->spi, xfers, ARRAY_SIZE(xfers)); }
static int ad4695_set_ref_voltage(struct ad4695_state *st, int vref_mv)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Xu lizhi.xu@windriver.com
[ Upstream commit 285cec318bf5a7a6c8ba999b2b6ec96f9a20590f ]
syzbot reported a NULL pointer dereference in __generic_file_write_iter. [1]
Before the write operation is completed, the user executes ioctl[2] to clear the compress flag of the file, which causes the is_compressed() judgment to return 0, further causing the program to enter the wrong process and call the wrong ops ntfs_aops_cmpr, which triggers the null pointer dereference of write_begin.
Use inode lock to synchronize ioctl and write to avoid this case.
[1] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Mem abort info: ESR = 0x0000000086000006 EC = 0x21: IABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x06: level 2 translation fault user pgtable: 4k pages, 48-bit VAs, pgdp=000000011896d000 [0000000000000000] pgd=0800000118b44403, p4d=0800000118b44403, pud=0800000117517403, pmd=0000000000000000 Internal error: Oops: 0000000086000006 [#1] PREEMPT SMP Modules linked in: CPU: 0 UID: 0 PID: 6427 Comm: syz-executor347 Not tainted 6.13.0-rc3-syzkaller-g573067a5a685 #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : 0x0 lr : generic_perform_write+0x29c/0x868 mm/filemap.c:4055 sp : ffff80009d4978a0 x29: ffff80009d4979c0 x28: dfff800000000000 x27: ffff80009d497bc8 x26: 0000000000000000 x25: ffff80009d497960 x24: ffff80008ba71c68 x23: 0000000000000000 x22: ffff0000c655dac0 x21: 0000000000001000 x20: 000000000000000c x19: 1ffff00013a92f2c x18: ffff0000e183aa1c x17: 0004060000000014 x16: ffff800083275834 x15: 0000000000000001 x14: 0000000000000000 x13: 0000000000000001 x12: ffff0000c655dac0 x11: 0000000000ff0100 x10: 0000000000ff0100 x9 : 0000000000000000 x8 : 0000000000000000 x7 : 0000000000000000 x6 : 0000000000000000 x5 : ffff80009d497980 x4 : ffff80009d497960 x3 : 0000000000001000 x2 : 0000000000000000 x1 : ffff0000e183a928 x0 : ffff0000d60b0fc0 Call trace: 0x0 (P) __generic_file_write_iter+0xfc/0x204 mm/filemap.c:4156 ntfs_file_write_iter+0x54c/0x630 fs/ntfs3/file.c:1267 new_sync_write fs/read_write.c:586 [inline] vfs_write+0x920/0xcf4 fs/read_write.c:679 ksys_write+0x15c/0x26c fs/read_write.c:731 __do_sys_write fs/read_write.c:742 [inline] __se_sys_write fs/read_write.c:739 [inline] __arm64_sys_write+0x7c/0x90 fs/read_write.c:739 __invoke_syscall arch/arm64/kernel/syscall.c:35 [inline] invoke_syscall+0x98/0x2b8 arch/arm64/kernel/syscall.c:49 el0_svc_common+0x130/0x23c arch/arm64/kernel/syscall.c:132 do_el0_svc+0x48/0x58 arch/arm64/kernel/syscall.c:151 el0_svc+0x54/0x168 arch/arm64/kernel/entry-common.c:744 el0t_64_sync_handler+0x84/0x108 arch/arm64/kernel/entry-common.c:762
[2] ioctl$FS_IOC_SETFLAGS(r0, 0x40086602, &(0x7f00000000c0)=0x20)
Reported-by: syzbot+5d0bdc98770e6c55a0fd@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=5d0bdc98770e6c55a0fd Signed-off-by: Lizhi Xu lizhi.xu@windriver.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ntfs3/file.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index e9f701f884e72..d884facc53166 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -1246,21 +1246,22 @@ static ssize_t ntfs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ssize_t ret; int err;
- err = check_write_restriction(inode); - if (err) - return err; - - if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) { - ntfs_inode_warn(inode, "direct i/o + compressed not supported"); - return -EOPNOTSUPP; - } - if (!inode_trylock(inode)) { if (iocb->ki_flags & IOCB_NOWAIT) return -EAGAIN; inode_lock(inode); }
+ ret = check_write_restriction(inode); + if (ret) + goto out; + + if (is_compressed(ni) && (iocb->ki_flags & IOCB_DIRECT)) { + ntfs_inode_warn(inode, "direct i/o + compressed not supported"); + ret = -EOPNOTSUPP; + goto out; + } + ret = generic_write_checks(iocb, from); if (ret <= 0) goto out;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis eadavis@qq.com
[ Upstream commit ff355926445897cc9fdea3b00611e514232c213c ]
Syzbot reported a WARNING in ntfs_extend_initialized_size. The data type of in->i_valid and to is u64 in ntfs_file_mmap(). If their values are greater than LLONG_MAX, overflow will occur because the data types of the parameters valid and new_valid corresponding to the function ntfs_extend_initialized_size() are loff_t.
Before calling ntfs_extend_initialized_size() in the ntfs_file_mmap(), the "ni->i_valid < to" has been determined, so the same WARN_ON determination is not required in ntfs_extend_initialized_size(). Just execute the ntfs_extend_initialized_size() in ntfs_extend() to make a WARN_ON check.
Reported-and-tested-by: syzbot+e37dd1dfc814b10caa55@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=e37dd1dfc814b10caa55 Signed-off-by: Edward Adam Davis eadavis@qq.com Signed-off-by: Konstantin Komarov almaz.alexandrovich@paragon-software.com Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ntfs3/file.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index d884facc53166..9b6a3f8d2e7c5 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -430,6 +430,7 @@ static int ntfs_extend(struct inode *inode, loff_t pos, size_t count, }
if (extend_init && !is_compressed(ni)) { + WARN_ON(ni->i_valid >= pos); err = ntfs_extend_initialized_size(file, ni, ni->i_valid, pos); if (err) goto out;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit eafba0205426091354f050381c32ad1567c35844 ]
Prepare the gadget driver to handle the reserved endpoints that will be not allocated at the initialisation time.
While at it, add a warning where the NULL endpoint should never happen.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Tested-by: Ferry Toth fntoth@gmail.com Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/20250212193116.2487289-3-andriy.shevchenko@linux.i... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/gadget.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index b75b4c5ca7fcf..c6761fe89cfae 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -547,6 +547,7 @@ static int dwc3_gadget_set_xfer_resource(struct dwc3_ep *dep) int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index) { struct dwc3_gadget_ep_cmd_params params; + struct dwc3_ep *dep; u32 cmd; int i; int ret; @@ -563,8 +564,13 @@ int dwc3_gadget_start_config(struct dwc3 *dwc, unsigned int resource_index) return ret;
/* Reset resource allocation flags */ - for (i = resource_index; i < dwc->num_eps && dwc->eps[i]; i++) - dwc->eps[i]->flags &= ~DWC3_EP_RESOURCE_ALLOCATED; + for (i = resource_index; i < dwc->num_eps; i++) { + dep = dwc->eps[i]; + if (!dep) + continue; + + dep->flags &= ~DWC3_EP_RESOURCE_ALLOCATED; + }
return 0; } @@ -751,9 +757,11 @@ void dwc3_gadget_clear_tx_fifos(struct dwc3 *dwc)
dwc->last_fifo_depth = fifo_depth; /* Clear existing TXFIFO for all IN eps except ep0 */ - for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); - num += 2) { + for (num = 3; num < min_t(int, dwc->num_eps, DWC3_ENDPOINTS_NUM); num += 2) { dep = dwc->eps[num]; + if (!dep) + continue; + /* Don't change TXFRAMNUM on usb31 version */ size = DWC3_IP_IS(DWC3) ? 0 : dwc3_readl(dwc->regs, DWC3_GTXFIFOSIZ(num >> 1)) & @@ -3703,6 +3711,8 @@ static bool dwc3_gadget_endpoint_trbs_complete(struct dwc3_ep *dep,
for (i = 0; i < DWC3_ENDPOINTS_NUM; i++) { dep = dwc->eps[i]; + if (!dep) + continue;
if (!(dep->flags & DWC3_EP_ENABLED)) continue; @@ -3852,6 +3862,10 @@ static void dwc3_endpoint_interrupt(struct dwc3 *dwc, u8 epnum = event->endpoint_number;
dep = dwc->eps[epnum]; + if (!dep) { + dev_warn(dwc->dev, "spurious event, endpoint %u is not allocated\n", epnum); + return; + }
if (!(dep->flags & DWC3_EP_ENABLED)) { if ((epnum > 1) && !(dep->flags & DWC3_EP_TRANSFER_STARTED))
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit 461f24bff86808ee5fbfe74751a825f8a7ab24e0 ]
Intel Merrifield SoC uses these endpoints for tracing and they cannot be re-allocated if being used because the side band flow control signals are hard wired to certain endpoints:
• 1 High BW Bulk IN (IN#1) (RTIT) • 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8)
In device mode, since RTIT (EP#1) and EXI/RunControl (EP#8) uses External Buffer Control (EBC) mode, these endpoints are to be mapped to EBC mode (to be done by EXI target driver). Additionally TRB for RTIT and EXI are maintained in STM (System Trace Module) unit and the EXI target driver will as well configure the TRB location for EP #1 IN and EP#8 (IN and OUT). Since STM/PTI and EXI hardware blocks manage these endpoints and interface to OTG3 controller through EBC interface, there is no need to enable any events (such as XferComplete etc) for these end points.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Tested-by: Ferry Toth fntoth@gmail.com Acked-by: Thinh Nguyen Thinh.Nguyen@synopsys.com Link: https://lore.kernel.org/r/20250212193116.2487289-5-andriy.shevchenko@linux.i... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/dwc3/dwc3-pci.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 052852f801467..54a4ee2b90b7f 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -148,11 +148,21 @@ static const struct property_entry dwc3_pci_intel_byt_properties[] = { {} };
+/* + * Intel Merrifield SoC uses these endpoints for tracing and they cannot + * be re-allocated if being used because the side band flow control signals + * are hard wired to certain endpoints: + * - 1 High BW Bulk IN (IN#1) (RTIT) + * - 1 1KB BW Bulk IN (IN#8) + 1 1KB BW Bulk OUT (Run Control) (OUT#8) + */ +static const u8 dwc3_pci_mrfld_reserved_endpoints[] = { 3, 16, 17 }; + static const struct property_entry dwc3_pci_mrfld_properties[] = { PROPERTY_ENTRY_STRING("dr_mode", "otg"), PROPERTY_ENTRY_STRING("linux,extcon-name", "mrfld_bcove_pwrsrc"), PROPERTY_ENTRY_BOOL("snps,dis_u3_susphy_quirk"), PROPERTY_ENTRY_BOOL("snps,dis_u2_susphy_quirk"), + PROPERTY_ENTRY_U8_ARRAY("snps,reserved-endpoints", dwc3_pci_mrfld_reserved_endpoints), PROPERTY_ENTRY_BOOL("snps,usb2-gadget-lpm-disable"), PROPERTY_ENTRY_BOOL("linux,sysdev_is_parent"), {}
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Stultz jstultz@google.com
[ Upstream commit 3c7df2e27346eb40a0e86230db1ccab195c97cfe ]
Betty reported hitting the following warning:
[ 8.709131][ T221] WARNING: CPU: 2 PID: 221 at kernel/workqueue.c:4182 ... [ 8.713282][ T221] Call trace: [ 8.713365][ T221] __flush_work+0x8d0/0x914 [ 8.713468][ T221] __cancel_work_sync+0xac/0xfc [ 8.713570][ T221] cancel_work_sync+0x24/0x34 [ 8.713667][ T221] virtsnd_remove+0xa8/0xf8 [virtio_snd ab15f34d0dd772f6d11327e08a81d46dc9c36276] [ 8.713868][ T221] virtsnd_probe+0x48c/0x664 [virtio_snd ab15f34d0dd772f6d11327e08a81d46dc9c36276] [ 8.714035][ T221] virtio_dev_probe+0x28c/0x390 [ 8.714139][ T221] really_probe+0x1bc/0x4c8 ...
It seems we're hitting the error path in virtsnd_probe(), which triggers a virtsnd_remove() which iterates over the substreams calling cancel_work_sync() on the elapsed_period work_struct.
Looking at the code, from earlier in: virtsnd_probe()->virtsnd_build_devs()->virtsnd_pcm_parse_cfg()
We set snd->nsubstreams, allocate the snd->substreams, and if we then hit an error on the info allocation or something in virtsnd_ctl_query_info() fails, we will exit without having initialized the elapsed_period work_struct.
When that error path unwinds we then call virtsnd_remove() which as long as the substreams array is allocated, will iterate through calling cancel_work_sync() on the uninitialized work struct hitting this warning.
Takashi Iwai suggested this fix, which initializes the substreams structure right after allocation, so that if we hit the error paths we avoid trying to cleanup uninitialized data.
Note: I have not yet managed to reproduce the issue myself, so this patch has had limited testing.
Feedback or thoughts would be appreciated!
Cc: Anton Yakovlev anton.yakovlev@opensynergy.com Cc: "Michael S. Tsirkin" mst@redhat.com Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: virtualization@lists.linux.dev Cc: linux-sound@vger.kernel.org Cc: kernel-team@android.com Reported-by: Betty Zhou bettyzhou@google.com Suggested-by: Takashi Iwai tiwai@suse.de Signed-off-by: John Stultz jstultz@google.com Message-Id: 20250116194114.3375616-1-jstultz@google.com Signed-off-by: Michael S. Tsirkin mst@redhat.com Signed-off-by: Sasha Levin sashal@kernel.org --- sound/virtio/virtio_pcm.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/sound/virtio/virtio_pcm.c b/sound/virtio/virtio_pcm.c index 967e4c45be9bb..2f7c5e709f075 100644 --- a/sound/virtio/virtio_pcm.c +++ b/sound/virtio/virtio_pcm.c @@ -339,6 +339,21 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd) if (!snd->substreams) return -ENOMEM;
+ /* + * Initialize critical substream fields early in case we hit an + * error path and end up trying to clean up uninitialized structures + * elsewhere. + */ + for (i = 0; i < snd->nsubstreams; ++i) { + struct virtio_pcm_substream *vss = &snd->substreams[i]; + + vss->snd = snd; + vss->sid = i; + INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed); + init_waitqueue_head(&vss->msg_empty); + spin_lock_init(&vss->lock); + } + info = kcalloc(snd->nsubstreams, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; @@ -352,12 +367,6 @@ int virtsnd_pcm_parse_cfg(struct virtio_snd *snd) struct virtio_pcm_substream *vss = &snd->substreams[i]; struct virtio_pcm *vpcm;
- vss->snd = snd; - vss->sid = i; - INIT_WORK(&vss->elapsed_period, virtsnd_pcm_period_elapsed); - init_waitqueue_head(&vss->msg_empty); - spin_lock_init(&vss->lock); - rc = virtsnd_pcm_build_hw(vss, &info[i]); if (rc) goto on_exit;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren wahrenst@gmx.net
[ Upstream commit 95032938c7c9b2e5ebb69f0ee10ebe340fa3af53 ]
The old SET_LATE_SYSTEM_SLEEP_PM_OPS macro cause a build warning when CONFIG_PM is disabled:
warning: 'bcm2835_dma_suspend_late' defined but not used [-Wunused-function]
Change this to the modern replacement.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202501071533.yrFb156H-lkp@intel.com/ Signed-off-by: Stefan Wahren wahrenst@gmx.net Reviewed-by: Florian Fainelli florian.fainelli@broadcom.com Link: https://lore.kernel.org/r/20250222095028.48818-1-wahrenst@gmx.net Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/bcm2835-dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma/bcm2835-dma.c b/drivers/dma/bcm2835-dma.c index 20b10c15c6967..0117bb2e8591b 100644 --- a/drivers/dma/bcm2835-dma.c +++ b/drivers/dma/bcm2835-dma.c @@ -893,7 +893,7 @@ static int bcm2835_dma_suspend_late(struct device *dev) }
static const struct dev_pm_ops bcm2835_dma_pm_ops = { - SET_LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL) + LATE_SYSTEM_SLEEP_PM_OPS(bcm2835_dma_suspend_late, NULL) };
static int bcm2835_dma_probe(struct platform_device *pdev)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio michal.pecio@gmail.com
[ Upstream commit bfa8459942822bdcc86f0e87f237c0723ae64948 ]
Missed Service Error after an error mid TD means that the failed TD has already been passed by the xHC without acknowledgment of the final TRB, a known hardware bug. So don't wait any more and give back the TD.
Reproduced on NEC uPD720200 under conditions of ludicrously bad USB link quality, confirmed to behave as expected using dynamic debug.
Signed-off-by: Michal Pecio michal.pecio@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20250306144954.3507700-5-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-ring.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index c64316638350e..7721215be79ff 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2789,7 +2789,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_dbg(xhci, "Miss service interval error for slot %u ep %u, set skip flag\n", slot_id, ep_index); - return 0; + break; case COMP_NO_PING_RESPONSE_ERROR: ep->skip = true; xhci_dbg(xhci, @@ -2837,6 +2837,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, xhci_dequeue_td(xhci, td, ep_ring, td->status); }
+ /* Missed TDs will be skipped on the next event */ + if (trb_comp_code == COMP_MISSED_SERVICE_ERROR) + return 0; + if (list_empty(&ep_ring->td_list)) { /* * Don't print wanings if ring is empty due to a stopped endpoint generating an
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio michal.pecio@gmail.com
[ Upstream commit 906dec15b9b321b546fd31a3c99ffc13724c7af4 ]
The TRB pointer of these events points at enqueue at the time of error occurrence on xHCI 1.1+ HCs or it's NULL on older ones. By the time we are handling the event, a new TD may be queued at this ring position.
I can trigger this race by rising interrupt moderation to increase IRQ handling delay. Similar delay may occur naturally due to system load.
If this ever happens after a Missed Service Error, missed TDs will be skipped and the new TD processed as if it matched the event. It could be given back prematurely, risking data loss or buffer UAF by the xHC.
Don't complete TDs on xrun events and don't warn if queued TDs don't match the event's TRB pointer, which can be NULL or a link/no-op TRB. Don't warn if there are no queued TDs at all.
Now that it's safe, also handle xrun events if the skip flag is clear. This ensures completion of any TD stuck in 'error mid TD' state right before the xrun event, which could happen if a driver submits a finite number of URBs to a buggy HC and then an error occurs on the last TD.
Signed-off-by: Michal Pecio michal.pecio@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20250306144954.3507700-6-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-ring.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 7721215be79ff..12b1c14efeb21 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2664,6 +2664,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, int status = -EINPROGRESS; struct xhci_ep_ctx *ep_ctx; u32 trb_comp_code; + bool ring_xrun_event = false;
slot_id = TRB_TO_SLOT_ID(le32_to_cpu(event->flags)); ep_index = TRB_TO_EP_ID(le32_to_cpu(event->flags)) - 1; @@ -2770,14 +2771,12 @@ static int handle_tx_event(struct xhci_hcd *xhci, * Underrun Event for OUT Isoch endpoint. */ xhci_dbg(xhci, "Underrun event on slot %u ep %u\n", slot_id, ep_index); - if (ep->skip) - break; - return 0; + ring_xrun_event = true; + break; case COMP_RING_OVERRUN: xhci_dbg(xhci, "Overrun event on slot %u ep %u\n", slot_id, ep_index); - if (ep->skip) - break; - return 0; + ring_xrun_event = true; + break; case COMP_MISSED_SERVICE_ERROR: /* * When encounter missed service error, one or more isoc tds @@ -2850,6 +2849,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ if (trb_comp_code != COMP_STOPPED && trb_comp_code != COMP_STOPPED_LENGTH_INVALID && + !ring_xrun_event && !ep_ring->last_td_was_short) { xhci_warn(xhci, "Event TRB for slot %u ep %u with no TDs queued\n", slot_id, ep_index); @@ -2884,6 +2884,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, goto check_endpoint_halted; }
+ /* TD was queued after xrun, maybe xrun was on a link, don't panic yet */ + if (ring_xrun_event) + return 0; + /* * Skip the Force Stopped Event. The 'ep_trb' of FSE is not in the current * TD pointed by 'ep_ring->dequeue' because that the hardware dequeue @@ -2930,6 +2934,10 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ } while (ep->skip);
+ /* Get out if a TD was queued at enqueue after the xrun occurred */ + if (ring_xrun_event) + return 0; + if (trb_comp_code == COMP_SHORT_PACKET) ep_ring->last_td_was_short = true; else
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mathias Nyman mathias.nyman@linux.intel.com
[ Upstream commit b331a3d8097fad4e541d212684192f21fedbd6e5 ]
Unplugging a USB3.0 webcam from Etron hosts while streaming results in errors like this:
[ 2.646387] xhci_hcd 0000:03:00.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 18 comp_code 13 [ 2.646446] xhci_hcd 0000:03:00.0: Looking for event-dma 000000002fdf8630 trb-start 000000002fdf8640 trb-end 000000002fdf8650 [ 2.646560] xhci_hcd 0000:03:00.0: ERROR Transfer event TRB DMA ptr not part of current TD ep_index 18 comp_code 13 [ 2.646568] xhci_hcd 0000:03:00.0: Looking for event-dma 000000002fdf8660 trb-start 000000002fdf8670 trb-end 000000002fdf8670
Etron xHC generates two transfer events for the TRB if an error is detected while processing the last TRB of an isoc TD.
The first event can be any sort of error (like USB Transaction or Babble Detected, etc), and the final event is Success.
The xHCI driver will handle the TD after the first event and remove it from its internal list, and then print an "Transfer event TRB DMA ptr not part of current TD" error message after the final event.
Commit 5372c65e1311 ("xhci: process isoc TD properly when there was a transaction error mid TD.") is designed to address isoc transaction errors, but unfortunately it doesn't account for this scenario.
This issue is similar to the XHCI_SPURIOUS_SUCCESS case where a success event follows a 'short transfer' event, but the TD the event points to is already given back.
Expand the spurious success 'short transfer' event handling to cover the spurious success after error on Etron hosts.
Kuangyi Chiang reported this issue and submitted a different solution based on using error_mid_td. This commit message is mostly taken from that patch.
Reported-by: Kuangyi Chiang ki.chiang65@gmail.com Closes: https://lore.kernel.org/linux-usb/20241028025337.6372-6-ki.chiang65@gmail.co... Tested-by: Kuangyi Chiang ki.chiang65@gmail.com Tested-by: Michal Pecio michal.pecio@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20250306144954.3507700-16-mathias.nyman@linux.inte... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-ring.c | 38 ++++++++++++++++++++++++------------ drivers/usb/host/xhci.h | 2 +- 2 files changed, 27 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 12b1c14efeb21..6b20072424f0c 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2644,6 +2644,22 @@ static int handle_transferless_tx_event(struct xhci_hcd *xhci, struct xhci_virt_ return 0; }
+static bool xhci_spurious_success_tx_event(struct xhci_hcd *xhci, + struct xhci_ring *ring) +{ + switch (ring->old_trb_comp_code) { + case COMP_SHORT_PACKET: + return xhci->quirks & XHCI_SPURIOUS_SUCCESS; + case COMP_USB_TRANSACTION_ERROR: + case COMP_BABBLE_DETECTED_ERROR: + case COMP_ISOCH_BUFFER_OVERRUN: + return xhci->quirks & XHCI_ETRON_HOST && + ring->type == TYPE_ISOC; + default: + return false; + } +} + /* * If this function returns an error condition, it means it got a Transfer * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. @@ -2698,8 +2714,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, case COMP_SUCCESS: if (EVENT_TRB_LEN(le32_to_cpu(event->transfer_len)) != 0) { trb_comp_code = COMP_SHORT_PACKET; - xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td short %d\n", - slot_id, ep_index, ep_ring->last_td_was_short); + xhci_dbg(xhci, "Successful completion on short TX for slot %u ep %u with last td comp code %d\n", + slot_id, ep_index, ep_ring->old_trb_comp_code); } break; case COMP_SHORT_PACKET: @@ -2850,7 +2866,7 @@ static int handle_tx_event(struct xhci_hcd *xhci, if (trb_comp_code != COMP_STOPPED && trb_comp_code != COMP_STOPPED_LENGTH_INVALID && !ring_xrun_event && - !ep_ring->last_td_was_short) { + !xhci_spurious_success_tx_event(xhci, ep_ring)) { xhci_warn(xhci, "Event TRB for slot %u ep %u with no TDs queued\n", slot_id, ep_index); } @@ -2902,11 +2918,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
/* * Some hosts give a spurious success event after a short - * transfer. Ignore it. + * transfer or error on last TRB. Ignore it. */ - if ((xhci->quirks & XHCI_SPURIOUS_SUCCESS) && - ep_ring->last_td_was_short) { - ep_ring->last_td_was_short = false; + if (xhci_spurious_success_tx_event(xhci, ep_ring)) { + xhci_dbg(xhci, "Spurious event dma %pad, comp_code %u after %u\n", + &ep_trb_dma, trb_comp_code, ep_ring->old_trb_comp_code); + ep_ring->old_trb_comp_code = trb_comp_code; return 0; }
@@ -2934,15 +2951,12 @@ static int handle_tx_event(struct xhci_hcd *xhci, */ } while (ep->skip);
+ ep_ring->old_trb_comp_code = trb_comp_code; + /* Get out if a TD was queued at enqueue after the xrun occurred */ if (ring_xrun_event) return 0;
- if (trb_comp_code == COMP_SHORT_PACKET) - ep_ring->last_td_was_short = true; - else - ep_ring->last_td_was_short = false; - ep_trb = &ep_seg->trbs[(ep_trb_dma - ep_seg->dma) / sizeof(*ep_trb)]; trace_xhci_handle_transfer(ep_ring, (struct xhci_generic_trb *) ep_trb, ep_trb_dma);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 696b2b9c8f8e6..2c394cba120f1 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1371,7 +1371,7 @@ struct xhci_ring { unsigned int num_trbs_free; /* used only by xhci DbC */ unsigned int bounce_buf_len; enum xhci_ring_type type; - bool last_td_was_short; + u32 old_trb_comp_code; struct radix_tree_root *trb_address_map; };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stanley Chu yschu@nuvoton.com
[ Upstream commit 98d87600a04e42282797631aa6b98dd43999e274 ]
Nuvoton npcm845 SoC uses an older IP version, which has specific hardware issues that need to be addressed with a different compatible string.
Add driver data for different compatible strings to define platform specific quirks. Add compatible string for npcm845 to define its own driver data.
Signed-off-by: Stanley Chu yschu@nuvoton.com Reviewed-by: Frank Li Frank.Li@nxp.com Link: https://lore.kernel.org/r/20250306075429.2265183-3-yschu@nuvoton.com Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/i3c/master/svc-i3c-master.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/i3c/master/svc-i3c-master.c b/drivers/i3c/master/svc-i3c-master.c index ed7b9d7f688cc..0fc03bb5d0a6e 100644 --- a/drivers/i3c/master/svc-i3c-master.c +++ b/drivers/i3c/master/svc-i3c-master.c @@ -158,6 +158,10 @@ struct svc_i3c_regs_save { u32 mdynaddr; };
+struct svc_i3c_drvdata { + u32 quirks; +}; + /** * struct svc_i3c_master - Silvaco I3C Master structure * @base: I3C master controller @@ -183,6 +187,7 @@ struct svc_i3c_regs_save { * @ibi.tbq_slot: To be queued IBI slot * @ibi.lock: IBI lock * @lock: Transfer lock, protect between IBI work thread and callbacks from master + * @drvdata: Driver data * @enabled_events: Bit masks for enable events (IBI, HotJoin). * @mctrl_config: Configuration value in SVC_I3C_MCTRL for setting speed back. */ @@ -214,6 +219,7 @@ struct svc_i3c_master { spinlock_t lock; } ibi; struct mutex lock; + const struct svc_i3c_drvdata *drvdata; u32 enabled_events; u32 mctrl_config; }; @@ -1817,6 +1823,10 @@ static int svc_i3c_master_probe(struct platform_device *pdev) if (!master) return -ENOMEM;
+ master->drvdata = of_device_get_match_data(dev); + if (!master->drvdata) + return -EINVAL; + master->regs = devm_platform_ioremap_resource(pdev, 0); if (IS_ERR(master->regs)) return PTR_ERR(master->regs); @@ -1958,8 +1968,13 @@ static const struct dev_pm_ops svc_i3c_pm_ops = { svc_i3c_runtime_resume, NULL) };
+static const struct svc_i3c_drvdata npcm845_drvdata = {}; + +static const struct svc_i3c_drvdata svc_default_drvdata = {}; + static const struct of_device_id svc_i3c_master_of_match_tbl[] = { - { .compatible = "silvaco,i3c-master-v1"}, + { .compatible = "nuvoton,npcm845-i3c", .data = &npcm845_drvdata }, + { .compatible = "silvaco,i3c-master-v1", .data = &svc_default_drvdata }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, svc_i3c_master_of_match_tbl);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vinicius Costa Gomes vinicius.gomes@intel.com
[ Upstream commit e87ca16e99118ab4e130a41bdf12abbf6a87656c ]
Change the "wait for operation finish" logic to take interrupts into account.
When using dmatest with idxd DMA engine, it's possible that during longer tests, the interrupt notifying the finish of an operation happens during wait_event_freezable_timeout(), which causes dmatest to cleanup all the resources, some of which might still be in use.
This fix ensures that the wait logic correctly handles interrupts, preventing premature cleanup of resources.
Reported-by: kernel test robot oliver.sang@intel.com Closes: https://lore.kernel.org/oe-lkp/202502171134.8c403348-lkp@intel.com Signed-off-by: Vinicius Costa Gomes vinicius.gomes@intel.com Reviewed-by: Dave Jiang dave.jiang@intel.com Link: https://lore.kernel.org/r/20250305230007.590178-1-vinicius.gomes@intel.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma/dmatest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/dma/dmatest.c b/drivers/dma/dmatest.c index 91b2fbc0b8647..d891dfca358e2 100644 --- a/drivers/dma/dmatest.c +++ b/drivers/dma/dmatest.c @@ -841,9 +841,9 @@ static int dmatest_func(void *data) } else { dma_async_issue_pending(chan);
- wait_event_freezable_timeout(thread->done_wait, - done->done, - msecs_to_jiffies(params->timeout)); + wait_event_timeout(thread->done_wait, + done->done, + msecs_to_jiffies(params->timeout));
status = dma_async_is_tx_complete(chan, cookie, NULL, NULL);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio michal.pecio@gmail.com
[ Upstream commit 28a76fcc4c85dd39633fb96edb643c91820133e3 ]
Nothing prevents a broken HC from claiming that an endpoint is Running and repeatedly rejecting Stop Endpoint with Context State Error.
Avoid infinite retries and give back cancelled TDs.
No such cases known so far, but HCs have bugs.
Signed-off-by: Michal Pecio michal.pecio@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20250311154551.4035726-4-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-ring.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 6b20072424f0c..3a284c68e37a0 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -1198,16 +1198,19 @@ static void xhci_handle_cmd_stop_ep(struct xhci_hcd *xhci, int slot_id, * Stopped state, but it will soon change to Running. * * Assume this bug on unexpected Stop Endpoint failures. - * Keep retrying until the EP starts and stops again, on - * chips where this is known to help. Wait for 100ms. + * Keep retrying until the EP starts and stops again. */ - if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) - break; fallthrough; case EP_STATE_RUNNING: /* Race, HW handled stop ep cmd before ep was running */ xhci_dbg(xhci, "Stop ep completion ctx error, ctx_state %d\n", GET_EP_CTX_STATE(ep_ctx)); + /* + * Don't retry forever if we guessed wrong or a defective HC never starts + * the EP or says 'Running' but fails the command. We must give back TDs. + */ + if (time_is_before_jiffies(ep->stop_time + msecs_to_jiffies(100))) + break;
command = xhci_alloc_command(xhci, false, GFP_ATOMIC); if (!command) {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Yan andy.yan@rock-chips.com
[ Upstream commit 28dc672a1a877c77b000c896abd8f15afcdc1b0c ]
Function rk_udphy_dp_hpd_event_trigger will set vogrf let it trigger HPD interrupt to DP by Type-C. This configuration is only required when the DP work in Alternate Mode, and called by typec_mux_set. In standard DP mode, such settings will prevent the DP from receiving HPD interrupts.
Signed-off-by: Andy Yan andy.yan@rock-chips.com Link: https://lore.kernel.org/r/20250302115257.188774-1-andyshrk@163.com Signed-off-by: Vinod Koul vkoul@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/phy/rockchip/phy-rockchip-usbdp.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/drivers/phy/rockchip/phy-rockchip-usbdp.c b/drivers/phy/rockchip/phy-rockchip-usbdp.c index 5b1e8a3806ed4..c04cf64f8a35d 100644 --- a/drivers/phy/rockchip/phy-rockchip-usbdp.c +++ b/drivers/phy/rockchip/phy-rockchip-usbdp.c @@ -1045,7 +1045,6 @@ static int rk_udphy_dp_phy_init(struct phy *phy) mutex_lock(&udphy->mutex);
udphy->dp_in_use = true; - rk_udphy_dp_hpd_event_trigger(udphy, udphy->dp_sink_hpd_cfg);
mutex_unlock(&udphy->mutex);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang chenyuan0y@gmail.com
[ Upstream commit 8c75f3e6a433d92084ad4e78b029ae680865420f ]
The variable d->name, returned by 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/20250311012705.1233829-1-chenyuan0y@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/gadget/udc/aspeed-vhub/dev.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/udc/aspeed-vhub/dev.c index 573109ca5b799..a09f72772e6e9 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c @@ -548,6 +548,9 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned int idx) d->vhub = vhub; d->index = idx; d->name = devm_kasprintf(parent, GFP_KERNEL, "port%d", idx+1); + if (!d->name) + return -ENOMEM; + d->regs = vhub->regs + 0x100 + 0x10 * idx;
ast_vhub_init_ep0(vhub, &d->ep0, d);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Théo Lebrun theo.lebrun@bootlin.com
[ Upstream commit 64eb182d5f7a5ec30227bce4f6922ff663432f44 ]
Compatible "marvell,armada3700-xhci" match data uses the struct xhci_plat_priv::init_quirk() function pointer to add XHCI_RESET_ON_RESUME as quirk on XHCI.
Instead, use the struct xhci_plat_priv::quirks field.
Signed-off-by: Théo Lebrun theo.lebrun@bootlin.com Link: https://lore.kernel.org/r/20250205-s2r-cdns-v7-1-13658a271c3c@bootlin.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/usb/host/xhci-mvebu.c | 10 ---------- drivers/usb/host/xhci-mvebu.h | 6 ------ drivers/usb/host/xhci-plat.c | 2 +- 3 files changed, 1 insertion(+), 17 deletions(-)
diff --git a/drivers/usb/host/xhci-mvebu.c b/drivers/usb/host/xhci-mvebu.c index 87f1597a0e5ab..257e4d79971fd 100644 --- a/drivers/usb/host/xhci-mvebu.c +++ b/drivers/usb/host/xhci-mvebu.c @@ -73,13 +73,3 @@ int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd)
return 0; } - -int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) -{ - struct xhci_hcd *xhci = hcd_to_xhci(hcd); - - /* Without reset on resume, the HC won't work at all */ - xhci->quirks |= XHCI_RESET_ON_RESUME; - - return 0; -} diff --git a/drivers/usb/host/xhci-mvebu.h b/drivers/usb/host/xhci-mvebu.h index 3be021793cc8b..9d26e22c48422 100644 --- a/drivers/usb/host/xhci-mvebu.h +++ b/drivers/usb/host/xhci-mvebu.h @@ -12,16 +12,10 @@ struct usb_hcd;
#if IS_ENABLED(CONFIG_USB_XHCI_MVEBU) int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd); -int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd); #else static inline int xhci_mvebu_mbus_init_quirk(struct usb_hcd *hcd) { return 0; } - -static inline int xhci_mvebu_a3700_init_quirk(struct usb_hcd *hcd) -{ - return 0; -} #endif #endif /* __LINUX_XHCI_MVEBU_H */ diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c index d85ffa9ffaa70..ff813dca2d1d3 100644 --- a/drivers/usb/host/xhci-plat.c +++ b/drivers/usb/host/xhci-plat.c @@ -106,7 +106,7 @@ static const struct xhci_plat_priv xhci_plat_marvell_armada = { };
static const struct xhci_plat_priv xhci_plat_marvell_armada3700 = { - .init_quirk = xhci_mvebu_a3700_init_quirk, + .quirks = XHCI_RESET_ON_RESUME, };
static const struct xhci_plat_priv xhci_plat_brcm = {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mika Westerberg mika.westerberg@linux.intel.com
[ Upstream commit 75749d2c1d8cef439f8b69fa1f4f36d0fc3193e6 ]
Thomas reported connection issues on AMD system with Pluggable UD-4VPD dock. After some experiments it looks like the device has some sort of internal timeout that triggers reconnect. This is completely against the USB4 spec, as there is no requirement for the host to enumerate the device right away or even at all.
In Linux case the delay is caused by scanning of retimers on the link so we can work this around by doing the scanning after the device router has been enumerated.
Reported-by: Thomas Lynema lyz27@yahoo.com Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219748 Reviewed-by: Mario Limonciello mario.limonciello@amd.com Signed-off-by: Mika Westerberg mika.westerberg@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/thunderbolt/tb.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/thunderbolt/tb.c b/drivers/thunderbolt/tb.c index 390abcfe71882..8c527af989271 100644 --- a/drivers/thunderbolt/tb.c +++ b/drivers/thunderbolt/tb.c @@ -1305,11 +1305,15 @@ static void tb_scan_port(struct tb_port *port) goto out_rpm_put; }
- tb_retimer_scan(port, true); - sw = tb_switch_alloc(port->sw->tb, &port->sw->dev, tb_downstream_route(port)); if (IS_ERR(sw)) { + /* + * Make the downstream retimers available even if there + * is no router connected. + */ + tb_retimer_scan(port, true); + /* * If there is an error accessing the connected switch * it may be connected to another domain. Also we allow @@ -1359,6 +1363,14 @@ static void tb_scan_port(struct tb_port *port) upstream_port = tb_upstream_port(sw); tb_configure_link(port, upstream_port, sw);
+ /* + * Scan for downstream retimers. We only scan them after the + * router has been enumerated to avoid issues with certain + * Pluggable devices that expect the host to enumerate them + * within certain timeout. + */ + tb_retimer_scan(port, true); + /* * CL0s and CL1 are enabled and supported together. * Silently ignore CLx enabling in case CLx is not supported.
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Berg benjamin.berg@intel.com
[ Upstream commit 887c5c12e80c8424bd471122d2e8b6b462e12874 ]
sched_yield by a userspace may not actually cause scheduling in time-travel mode as no time has passed. In the case seen it appears to be a badly implemented userspace spinlock in ASAN. Unfortunately, with time-travel it causes an extreme slowdown or even deadlock depending on the kernel configuration (CONFIG_UML_MAX_USERSPACE_ITERATIONS).
Work around it by accounting time to the process whenever it executes a sched_yield syscall.
Signed-off-by: Benjamin Berg benjamin.berg@intel.com Link: https://patch.msgid.link/20250314130815.226872-1-benjamin@sipsolutions.net Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/um/include/linux/time-internal.h | 2 ++ arch/um/kernel/skas/syscall.c | 11 +++++++++++ 2 files changed, 13 insertions(+)
diff --git a/arch/um/include/linux/time-internal.h b/arch/um/include/linux/time-internal.h index b22226634ff60..138908b999d76 100644 --- a/arch/um/include/linux/time-internal.h +++ b/arch/um/include/linux/time-internal.h @@ -83,6 +83,8 @@ extern void time_travel_not_configured(void); #define time_travel_del_event(...) time_travel_not_configured() #endif /* CONFIG_UML_TIME_TRAVEL_SUPPORT */
+extern unsigned long tt_extra_sched_jiffies; + /* * Without CONFIG_UML_TIME_TRAVEL_SUPPORT this is a linker error if used, * which is intentional since we really shouldn't link it in that case. diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index b09e85279d2b8..a5beaea2967ec 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c @@ -31,6 +31,17 @@ void handle_syscall(struct uml_pt_regs *r) goto out;
syscall = UPT_SYSCALL_NR(r); + + /* + * If no time passes, then sched_yield may not actually yield, causing + * broken spinlock implementations in userspace (ASAN) to hang for long + * periods of time. + */ + if ((time_travel_mode == TT_MODE_INFCPU || + time_travel_mode == TT_MODE_EXTERNAL) && + syscall == __NR_sched_yield) + tt_extra_sched_jiffies += 1; + if (syscall >= 0 && syscall < __NR_syscalls) { unsigned long ret = EXECUTE_SYSCALL(syscall, regs);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolin Chen nicolinc@nvidia.com
[ Upstream commit da0c56520e880441d0503d0cf0d6853dcfb5f1a4 ]
There is a DoS concern on the shared hardware event queue among devices passed through to VMs, that too many translation failures that belong to VMs could overflow the shared hardware event queue if those VMs or their VMMs don't handle/recover the devices properly.
The MEV bit in the STE allows to configure the SMMU HW to merge similar event records, though there is no guarantee. Set it in a nested STE for DoS mitigations.
In the future, we might want to enable the MEV for non-nested cases too such as domain->type == IOMMU_DOMAIN_UNMANAGED or even IOMMU_DOMAIN_DMA.
Link: https://patch.msgid.link/r/8ed12feef67fc65273d0f5925f401a81f56acebe.17417197... Reviewed-by: Jason Gunthorpe jgg@nvidia.com Reviewed-by: Pranjal Shrivastava praan@google.com Acked-by: Will Deacon will@kernel.org Signed-off-by: Nicolin Chen nicolinc@nvidia.com Signed-off-by: Jason Gunthorpe jgg@nvidia.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c | 2 ++ drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 ++-- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 1 + 3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c index 5aa2e7af58b47..34a0be59cd919 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-iommufd.c @@ -43,6 +43,8 @@ static void arm_smmu_make_nested_cd_table_ste( target->data[0] |= nested_domain->ste[0] & ~cpu_to_le64(STRTAB_STE_0_CFG); target->data[1] |= nested_domain->ste[1]; + /* Merge events for DoS mitigations on eventq */ + target->data[1] |= cpu_to_le64(STRTAB_STE_1_MEV); }
/* diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c index 358072b4e293e..59749e8180afc 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c @@ -1052,7 +1052,7 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits) cpu_to_le64(STRTAB_STE_1_S1DSS | STRTAB_STE_1_S1CIR | STRTAB_STE_1_S1COR | STRTAB_STE_1_S1CSH | STRTAB_STE_1_S1STALLD | STRTAB_STE_1_STRW | - STRTAB_STE_1_EATS); + STRTAB_STE_1_EATS | STRTAB_STE_1_MEV); used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID);
/* @@ -1068,7 +1068,7 @@ void arm_smmu_get_ste_used(const __le64 *ent, __le64 *used_bits) if (cfg & BIT(1)) { used_bits[1] |= cpu_to_le64(STRTAB_STE_1_S2FWB | STRTAB_STE_1_EATS | - STRTAB_STE_1_SHCFG); + STRTAB_STE_1_SHCFG | STRTAB_STE_1_MEV); used_bits[2] |= cpu_to_le64(STRTAB_STE_2_S2VMID | STRTAB_STE_2_VTCR | STRTAB_STE_2_S2AA64 | STRTAB_STE_2_S2ENDI | diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h index bd9d7c85576a2..7290bd4c2bb0a 100644 --- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h +++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h @@ -266,6 +266,7 @@ static inline u32 arm_smmu_strtab_l2_idx(u32 sid) #define STRTAB_STE_1_S1COR GENMASK_ULL(5, 4) #define STRTAB_STE_1_S1CSH GENMASK_ULL(7, 6)
+#define STRTAB_STE_1_MEV (1UL << 19) #define STRTAB_STE_1_S2FWB (1UL << 25) #define STRTAB_STE_1_S1STALLD (1UL << 27)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 6b023c7842048c4bbeede802f3cf36b96c7a8b25 ]
In the past there were issues with KCOV triggering unreachable instruction warnings, which is why unreachable warnings are now disabled with CONFIG_KCOV.
Now some new KCOV warnings are showing up with GCC 14:
vmlinux.o: warning: objtool: cpuset_write_resmask() falls through to next function cpuset_update_active_cpus.cold() drivers/usb/core/driver.o: error: objtool: usb_deregister() falls through to next function usb_match_device() sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section
All are caused by GCC KCOV not finishing an optimization, leaving behind a never-taken conditional branch to a basic block which falls through to the next function (or end of section).
At a high level this is similar to the unreachable warnings mentioned above, in that KCOV isn't fully removing dead code. Treat it the same way by adding these to the list of warnings to ignore with CONFIG_KCOV.
Reported-by: Ingo Molnar mingo@kernel.org Reported-by: kernel test robot lkp@intel.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/66a61a0b65d74e072d3dc02384e395edb2adc3c5.174285284... Closes: https://lore.kernel.org/Z9iTsI09AEBlxlHC@gmail.com Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/ Signed-off-by: Sasha Levin sashal@kernel.org --- tools/objtool/check.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 7b535e119cafa..0ca83c74c1f38 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3490,6 +3490,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, !strncmp(func->name, "__pfx_", 6)) return 0;
+ if (file->ignore_unreachables) + return 0; + WARN("%s() falls through to next function %s()", func->name, insn_func(insn)->name); return 1; @@ -3709,6 +3712,9 @@ static int validate_branch(struct objtool_file *file, struct symbol *func, if (!next_insn) { if (state.cfi.cfa.base == CFI_UNDEFINED) return 0; + if (file->ignore_unreachables) + return 0; + WARN("%s: unexpected end of section", sec->name); return 1; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 72c774aa9d1e16bfd247096935e7dae194d84929 ]
__stack_chk_fail() can be called from uaccess-enabled code. Make sure uaccess gets disabled before calling panic().
Fixes the following warning:
kernel/trace/trace_branch.o: error: objtool: ftrace_likely_update+0x1ea: call to __stack_chk_fail() with UACCESS enabled
Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Kees Cook keescook@chromium.org Cc: Andrew Morton akpm@linux-foundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/a3e97e0119e1b04c725a8aa05f7bc83d98e657eb.174285284... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/panic.c | 6 ++++++ tools/objtool/check.c | 5 ++++- 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/kernel/panic.c b/kernel/panic.c index d8635d5cecb25..f9f0c5148f6aa 100644 --- a/kernel/panic.c +++ b/kernel/panic.c @@ -832,9 +832,15 @@ device_initcall(register_warn_debugfs); */ __visible noinstr void __stack_chk_fail(void) { + unsigned long flags; + instrumentation_begin(); + flags = user_access_save(); + panic("stack-protector: Kernel stack is corrupted in: %pB", __builtin_return_address(0)); + + user_access_restore(flags); instrumentation_end(); } EXPORT_SYMBOL(__stack_chk_fail); diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 0ca83c74c1f38..bbfd81f49802e 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1189,12 +1189,15 @@ static const char *uaccess_safe_builtin[] = { "__ubsan_handle_load_invalid_value", /* STACKLEAK */ "stackleak_track_stack", + /* TRACE_BRANCH_PROFILING */ + "ftrace_likely_update", + /* STACKPROTECTOR */ + "__stack_chk_fail", /* misc */ "csum_partial_copy_generic", "copy_mc_fragile", "copy_mc_fragile_handle_tail", "copy_mc_enhanced_fast_string", - "ftrace_likely_update", /* CONFIG_TRACE_BRANCH_PROFILING */ "rep_stos_alternative", "rep_movs_alternative", "__copy_user_nocache",
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 060aed9c0093b341480770457093449771cf1496 ]
If 'port_id' is negative, the shift counts in wcd934x_slim_irq_handler() also become negative, resulting in undefined behavior due to shift out of bounds.
If I'm reading the code correctly, that appears to be not possible, but with KCOV enabled, Clang's range analysis isn't always able to determine that and generates undefined behavior.
As a result the code generation isn't optimal, and undefined behavior should be avoided regardless. Improve code generation and remove the undefined behavior by converting the signed variables to unsigned.
Fixes the following warning with UBSAN:
sound/soc/codecs/snd-soc-wcd934x.o: warning: objtool: .text.wcd934x_slim_irq_handler: unexpected end of section
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Acked-by: Mark Brown broonie@kernel.org Cc: Srinivas Kandagatla srinivas.kandagatla@linaro.org Cc: Liam Girdwood lgirdwood@gmail.com Cc: Jaroslav Kysela perex@perex.cz Cc: Takashi Iwai tiwai@suse.com Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/7e863839ec7301bf9c0f429a03873d44e484c31c.174285284... Closes: https://lore.kernel.org/oe-kbuild-all/202503180044.oH9gyPeg-lkp@intel.com/ Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/wcd934x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/codecs/wcd934x.c b/sound/soc/codecs/wcd934x.c index 910852eb9698c..c7f1b28f3b230 100644 --- a/sound/soc/codecs/wcd934x.c +++ b/sound/soc/codecs/wcd934x.c @@ -2273,7 +2273,7 @@ static irqreturn_t wcd934x_slim_irq_handler(int irq, void *data) { struct wcd934x_codec *wcd = data; unsigned long status = 0; - int i, j, port_id; + unsigned int i, j, port_id; unsigned int val, int_val = 0; irqreturn_t ret = IRQ_NONE; bool tx;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 29c578c848402a34e8c8e115bf66cb6008b77062 ]
If 'ctr_bit' is negative, the shift counts become negative, causing a shift of bounds and undefined behavior.
Presumably that's not possible in normal operation, but the code generation isn't optimal. And undefined behavior should be avoided regardless.
Improve code generation and remove the undefined behavior by converting the signed variables to unsigned.
Fixes the following warning with an UBSAN kernel:
vmlinux.o: warning: objtool: rk806_set_mode_dcdc() falls through to next function rk806_get_mode_dcdc() vmlinux.o: warning: objtool: .text.rk806_set_mode_dcdc: unexpected end of section
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Acked-by: Mark Brown broonie@kernel.org Cc: Liam Girdwood lgirdwood@gmail.com Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/2023abcddf3f524ba478d64339996f25dc4097d2.174285284... Closes: https://lore.kernel.org/oe-kbuild-all/202503182350.52KeHGD4-lkp@intel.com/ Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/regulator/rk808-regulator.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-regulator.c index 7d82bd1b36dfc..1e8142479656a 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -270,8 +270,8 @@ static const unsigned int rk817_buck1_4_ramp_table[] = {
static int rk806_set_mode_dcdc(struct regulator_dev *rdev, unsigned int mode) { - int rid = rdev_get_id(rdev); - int ctr_bit, reg; + unsigned int rid = rdev_get_id(rdev); + unsigned int ctr_bit, reg;
reg = RK806_POWER_FPWM_EN0 + rid / 8; ctr_bit = rid % 8;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 05026ea01e95ffdeb0e5ac8fb7fb1b551e3a8726 ]
If execute_location()'s memcpy of do_nothing() gets inlined and unrolled by the compiler, it copies one word at a time:
mov 0x0(%rip),%rax R_X86_64_PC32 .text+0x1374 mov %rax,0x38(%rbx) mov 0x0(%rip),%rax R_X86_64_PC32 .text+0x136c mov %rax,0x30(%rbx) ...
Those .text references point to the middle of the function, causing objtool to complain about their lack of ENDBR.
Prevent that by resolving the function pointer at runtime rather than build time. This fixes the following warning:
drivers/misc/lkdtm/lkdtm.o: warning: objtool: execute_location+0x23: relocation to !ENDBR: .text+0x1378
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Kees Cook kees@kernel.org Cc: Arnd Bergmann arnd@arndb.de Cc: Greg Kroah-Hartman gregkh@linuxfoundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/30b9abffbddeb43c4f6320b1270fa9b4d74c54ed.174285284... Closes: https://lore.kernel.org/oe-kbuild-all/202503191453.uFfxQy5R-lkp@intel.com/ Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/misc/lkdtm/perms.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/lkdtm/perms.c b/drivers/misc/lkdtm/perms.c index 5b861dbff27e9..6c24426104ba6 100644 --- a/drivers/misc/lkdtm/perms.c +++ b/drivers/misc/lkdtm/perms.c @@ -28,6 +28,13 @@ static const unsigned long rodata = 0xAA55AA55; /* This is marked __ro_after_init, so it should ultimately be .rodata. */ static unsigned long ro_after_init __ro_after_init = 0x55AA5500;
+/* + * This is a pointer to do_nothing() which is initialized at runtime rather + * than build time to avoid objtool IBT validation warnings caused by an + * inlined unrolled memcpy() in execute_location(). + */ +static void __ro_after_init *do_nothing_ptr; + /* * This just returns to the caller. It is designed to be copied into * non-executable memory regions. @@ -65,13 +72,12 @@ static noinline __nocfi void execute_location(void *dst, bool write) { void (*func)(void); func_desc_t fdesc; - void *do_nothing_text = dereference_function_descriptor(do_nothing);
- pr_info("attempting ok execution at %px\n", do_nothing_text); + pr_info("attempting ok execution at %px\n", do_nothing_ptr); do_nothing();
if (write == CODE_WRITE) { - memcpy(dst, do_nothing_text, EXEC_SIZE); + memcpy(dst, do_nothing_ptr, EXEC_SIZE); flush_icache_range((unsigned long)dst, (unsigned long)dst + EXEC_SIZE); } @@ -267,6 +273,8 @@ static void lkdtm_ACCESS_NULL(void)
void __init lkdtm_perms_init(void) { + do_nothing_ptr = dereference_function_descriptor(do_nothing); + /* Make sure we can write to __ro_after_init values during __init */ ro_after_init |= 0xAA; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro viro@zeniv.linux.org.uk
[ Upstream commit bdb43af4fdb39f844ede401bdb1258f67a580a27 ]
failure to allocate inode => leaked dentry...
this one had been there since the initial merge; to be fair, if we are that far OOM, the odds of failing at that particular allocation are low...
Signed-off-by: Al Viro viro@zeniv.linux.org.uk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/infiniband/hw/qib/qib_fs.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index b27791029fa93..b9f4a2937c3ac 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -55,6 +55,7 @@ static int qibfs_mknod(struct inode *dir, struct dentry *dentry, struct inode *inode = new_inode(dir->i_sb);
if (!inode) { + dput(dentry); error = -EPERM; goto bail; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Charlie Jenkins charlie@rivosinc.com
[ Upstream commit bba547810c66434475d8800b3411c59ef71eafe9 ]
The size of ®s->a0 is unknown, causing the error:
../include/linux/fortify-string.h:571:25: warning: call to '__write_overflow_field' declared with attribute warning: detected write beyond size of field (1st parameter); maybe use struct_group()? [-Wattribute-warning]
Fix this by wrapping the required registers in pt_regs with struct_group() and reference the group when doing the offending memcpy().
Signed-off-by: Charlie Jenkins charlie@rivosinc.com Reviewed-by: Alexandre Ghiti alexghiti@rivosinc.com Tested-by: Alexandre Ghiti alexghiti@rivosinc.com Link: https://lore.kernel.org/r/20250224-fix_ftrace_partial_regs-v1-1-54b906417e86... Signed-off-by: Alexandre Ghiti alexghiti@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/include/asm/ftrace.h | 2 +- arch/riscv/include/asm/ptrace.h | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/arch/riscv/include/asm/ftrace.h b/arch/riscv/include/asm/ftrace.h index 2636ee00ccf0f..9704a73e515a5 100644 --- a/arch/riscv/include/asm/ftrace.h +++ b/arch/riscv/include/asm/ftrace.h @@ -207,7 +207,7 @@ ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs) { struct __arch_ftrace_regs *afregs = arch_ftrace_regs(fregs);
- memcpy(®s->a0, afregs->args, sizeof(afregs->args)); + memcpy(®s->a_regs, afregs->args, sizeof(afregs->args)); regs->epc = afregs->epc; regs->ra = afregs->ra; regs->sp = afregs->sp; diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h index b5b0adcc85c18..2910231977cb7 100644 --- a/arch/riscv/include/asm/ptrace.h +++ b/arch/riscv/include/asm/ptrace.h @@ -23,14 +23,16 @@ struct pt_regs { unsigned long t2; unsigned long s0; unsigned long s1; - unsigned long a0; - unsigned long a1; - unsigned long a2; - unsigned long a3; - unsigned long a4; - unsigned long a5; - unsigned long a6; - unsigned long a7; + struct_group(a_regs, + unsigned long a0; + unsigned long a1; + unsigned long a2; + unsigned long a3; + unsigned long a4; + unsigned long a5; + unsigned long a6; + unsigned long a7; + ); unsigned long s2; unsigned long s3; unsigned long s4;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann arnd@arndb.de
[ Upstream commit aff12700b8dd7422bfe2277696e192af4df9de8f ]
idt_scan_mws() puts a large fixed-size array on the stack and copies it into a smaller dynamically allocated array at the end. On 32-bit targets, the fixed size can easily exceed the warning limit for possible stack overflow:
drivers/ntb/hw/idt/ntb_hw_idt.c:1041:27: error: stack frame size (1032) exceeds limit (1024) in 'idt_scan_mws' [-Werror,-Wframe-larger-than]
Change it to instead just always use dynamic allocation for the array from the start. It's too big for the stack, but not actually all that much for a permanent allocation.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/all/202205111109.PiKTruEj-lkp@intel.com/ Signed-off-by: Arnd Bergmann arnd@arndb.de Reviewed-by: Dave Jiang dave.jiang@intel.com Reviewed-by: Damien Le Moal dlemoal@kernel.org Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/hw/idt/ntb_hw_idt.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/drivers/ntb/hw/idt/ntb_hw_idt.c b/drivers/ntb/hw/idt/ntb_hw_idt.c index 544d8a4d2af59..f27df8d7f3b97 100644 --- a/drivers/ntb/hw/idt/ntb_hw_idt.c +++ b/drivers/ntb/hw/idt/ntb_hw_idt.c @@ -1041,7 +1041,7 @@ static inline char *idt_get_mw_name(enum idt_mw_type mw_type) static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port, unsigned char *mw_cnt) { - struct idt_mw_cfg mws[IDT_MAX_NR_MWS], *ret_mws; + struct idt_mw_cfg *mws; const struct idt_ntb_bar *bars; enum idt_mw_type mw_type; unsigned char widx, bidx, en_cnt; @@ -1049,6 +1049,11 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port, int aprt_size; u32 data;
+ mws = devm_kcalloc(&ndev->ntb.pdev->dev, IDT_MAX_NR_MWS, + sizeof(*mws), GFP_KERNEL); + if (!mws) + return ERR_PTR(-ENOMEM); + /* Retrieve the array of the BARs registers */ bars = portdata_tbl[port].bars;
@@ -1103,16 +1108,7 @@ static struct idt_mw_cfg *idt_scan_mws(struct idt_ntb_dev *ndev, int port, } }
- /* Allocate memory for memory window descriptors */ - ret_mws = devm_kcalloc(&ndev->ntb.pdev->dev, *mw_cnt, sizeof(*ret_mws), - GFP_KERNEL); - if (!ret_mws) - return ERR_PTR(-ENOMEM); - - /* Copy the info of detected memory windows */ - memcpy(ret_mws, mws, (*mw_cnt)*sizeof(*ret_mws)); - - return ret_mws; + return mws; }
/*
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Basavaraj Natikar Basavaraj.Natikar@amd.com
[ Upstream commit bf8a7ce7e4c7267a6f5f2b2023cfc459b330b25e ]
Add NTB support for new generation of processor.
Signed-off-by: Basavaraj Natikar Basavaraj.Natikar@amd.com Signed-off-by: Jon Mason jdmason@kudzu.us Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/ntb/hw/amd/ntb_hw_amd.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/ntb/hw/amd/ntb_hw_amd.c b/drivers/ntb/hw/amd/ntb_hw_amd.c index d687e8c2cc78d..63ceed89b62ef 100644 --- a/drivers/ntb/hw/amd/ntb_hw_amd.c +++ b/drivers/ntb/hw/amd/ntb_hw_amd.c @@ -1318,6 +1318,7 @@ static const struct pci_device_id amd_ntb_pci_tbl[] = { { PCI_VDEVICE(AMD, 0x148b), (kernel_ulong_t)&dev_data[1] }, { PCI_VDEVICE(AMD, 0x14c0), (kernel_ulong_t)&dev_data[1] }, { PCI_VDEVICE(AMD, 0x14c3), (kernel_ulong_t)&dev_data[1] }, + { PCI_VDEVICE(AMD, 0x155a), (kernel_ulong_t)&dev_data[1] }, { PCI_VDEVICE(HYGON, 0x145b), (kernel_ulong_t)&dev_data[0] }, { 0, } };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dominique Martinet asmadeus@codewreck.org
[ Upstream commit d0259a856afca31d699b706ed5e2adf11086c73b ]
In p9_client_write() and p9_client_read_once(), if the server incorrectly replies with success but a negative write/read count then we would consider written (negative) <= rsize (positive) because both variables were signed.
Make variables unsigned to avoid this problem.
The reproducer linked below now fails with the following error instead of a null pointer deref: 9pnet: bogus RWRITE count (4294967295 > 3)
Reported-by: Robert Morris rtm@mit.edu Closes: https://lore.kernel.org/16271.1734448631@26-5-164.dynamic.csail.mit.edu Message-ID: 20250319-9p_unsigned_rw-v3-1-71327f1503d0@codewreck.org Reviewed-by: Christian Schoenebeck linux_oss@crudebyte.com Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/9p/client.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-)
diff --git a/net/9p/client.c b/net/9p/client.c index 09f8ced9f8bb7..52a5497cfca79 100644 --- a/net/9p/client.c +++ b/net/9p/client.c @@ -1548,7 +1548,8 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, struct p9_client *clnt = fid->clnt; struct p9_req_t *req; int count = iov_iter_count(to); - int rsize, received, non_zc = 0; + u32 rsize, received; + bool non_zc = false; char *dataptr;
*err = 0; @@ -1571,7 +1572,7 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, 0, 11, "dqd", fid->fid, offset, rsize); } else { - non_zc = 1; + non_zc = true; req = p9_client_rpc(clnt, P9_TREAD, "dqd", fid->fid, offset, rsize); } @@ -1592,11 +1593,11 @@ p9_client_read_once(struct p9_fid *fid, u64 offset, struct iov_iter *to, return 0; } if (rsize < received) { - pr_err("bogus RREAD count (%d > %d)\n", received, rsize); + pr_err("bogus RREAD count (%u > %u)\n", received, rsize); received = rsize; }
- p9_debug(P9_DEBUG_9P, "<<< RREAD count %d\n", received); + p9_debug(P9_DEBUG_9P, "<<< RREAD count %u\n", received);
if (non_zc) { int n = copy_to_iter(dataptr, received, to); @@ -1623,9 +1624,9 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) *err = 0;
while (iov_iter_count(from)) { - int count = iov_iter_count(from); - int rsize = fid->iounit; - int written; + size_t count = iov_iter_count(from); + u32 rsize = fid->iounit; + u32 written;
if (!rsize || rsize > clnt->msize - P9_IOHDRSZ) rsize = clnt->msize - P9_IOHDRSZ; @@ -1633,7 +1634,7 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) if (count < rsize) rsize = count;
- p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %d (/%d)\n", + p9_debug(P9_DEBUG_9P, ">>> TWRITE fid %d offset %llu count %u (/%zu)\n", fid->fid, offset, rsize, count);
/* Don't bother zerocopy for small IO (< 1024) */ @@ -1659,11 +1660,11 @@ p9_client_write(struct p9_fid *fid, u64 offset, struct iov_iter *from, int *err) break; } if (rsize < written) { - pr_err("bogus RWRITE count (%d > %d)\n", written, rsize); + pr_err("bogus RWRITE count (%u > %u)\n", written, rsize); written = rsize; }
- p9_debug(P9_DEBUG_9P, "<<< RWRITE count %d\n", written); + p9_debug(P9_DEBUG_9P, "<<< RWRITE count %u\n", written);
p9_req_put(clnt, req); iov_iter_revert(from, count - written - iov_iter_count(from)); @@ -2098,7 +2099,8 @@ EXPORT_SYMBOL_GPL(p9_client_xattrcreate);
int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) { - int err, rsize, non_zc = 0; + int err, non_zc = 0; + u32 rsize; struct p9_client *clnt; struct p9_req_t *req; char *dataptr; @@ -2107,7 +2109,7 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset)
iov_iter_kvec(&to, ITER_DEST, &kv, 1, count);
- p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %d\n", + p9_debug(P9_DEBUG_9P, ">>> TREADDIR fid %d offset %llu count %u\n", fid->fid, offset, count);
clnt = fid->clnt; @@ -2142,11 +2144,11 @@ int p9_client_readdir(struct p9_fid *fid, char *data, u32 count, u64 offset) goto free_and_error; } if (rsize < count) { - pr_err("bogus RREADDIR count (%d > %d)\n", count, rsize); + pr_err("bogus RREADDIR count (%u > %u)\n", count, rsize); count = rsize; }
- p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %d\n", count); + p9_debug(P9_DEBUG_9P, "<<< RREADDIR count %u\n", count);
if (non_zc) memmove(data, dataptr, count);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ignacio Encinas ignacio@iencinas.com
[ Upstream commit fbc0283fbeae27b88448c90305e738991457fee2 ]
Writes for the error value of a connection are spinlock-protected inside p9_conn_cancel, but lockless reads are present elsewhere to avoid performing unnecessary work after an error has been met.
Mark the write and lockless reads to make KCSAN happy. Mark the write as exclusive following the recommendation in "Lock-Protected Writes with Lockless Reads" in tools/memory-model/Documentation/access-marking.txt while we are at it.
Mark p9_fd_request and p9_conn_cancel m->err reads despite the fact that they do not race with concurrent writes for stylistic reasons.
Reported-by: syzbot+d69a7cc8c683c2cb7506@syzkaller.appspotmail.com Reported-by: syzbot+483d6c9b9231ea7e1851@syzkaller.appspotmail.com Signed-off-by: Ignacio Encinas ignacio@iencinas.com Message-ID: 20250318-p9_conn_err_benign_data_race-v3-1-290bb18335cc@iencinas.com Signed-off-by: Dominique Martinet asmadeus@codewreck.org Signed-off-by: Sasha Levin sashal@kernel.org --- net/9p/trans_fd.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c index 196060dc6138a..791e4868f2d4e 100644 --- a/net/9p/trans_fd.c +++ b/net/9p/trans_fd.c @@ -191,12 +191,13 @@ static void p9_conn_cancel(struct p9_conn *m, int err)
spin_lock(&m->req_lock);
- if (m->err) { + if (READ_ONCE(m->err)) { spin_unlock(&m->req_lock); return; }
- m->err = err; + WRITE_ONCE(m->err, err); + ASSERT_EXCLUSIVE_WRITER(m->err);
list_for_each_entry_safe(req, rtmp, &m->req_list, req_list) { list_move(&req->req_list, &cancel_list); @@ -283,7 +284,7 @@ static void p9_read_work(struct work_struct *work)
m = container_of(work, struct p9_conn, rq);
- if (m->err < 0) + if (READ_ONCE(m->err) < 0) return;
p9_debug(P9_DEBUG_TRANS, "start mux %p pos %zd\n", m, m->rc.offset); @@ -450,7 +451,7 @@ static void p9_write_work(struct work_struct *work)
m = container_of(work, struct p9_conn, wq);
- if (m->err < 0) { + if (READ_ONCE(m->err) < 0) { clear_bit(Wworksched, &m->wsched); return; } @@ -622,7 +623,7 @@ static void p9_poll_mux(struct p9_conn *m) __poll_t n; int err = -ECONNRESET;
- if (m->err < 0) + if (READ_ONCE(m->err) < 0) return;
n = p9_fd_poll(m->client, NULL, &err); @@ -665,6 +666,7 @@ static void p9_poll_mux(struct p9_conn *m) static int p9_fd_request(struct p9_client *client, struct p9_req_t *req) { __poll_t n; + int err; struct p9_trans_fd *ts = client->trans; struct p9_conn *m = &ts->conn;
@@ -673,9 +675,10 @@ static int p9_fd_request(struct p9_client *client, struct p9_req_t *req)
spin_lock(&m->req_lock);
- if (m->err < 0) { + err = READ_ONCE(m->err); + if (err < 0) { spin_unlock(&m->req_lock); - return m->err; + return err; }
WRITE_ONCE(req->status, REQ_STATUS_UNSENT);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukas Stockmann lukas.stockmann@siemens.com
[ Upstream commit 2b7cbd98495f6ee4cd6422fe77828a19e9edf87f ]
Power-on Reset has a documented issue in PCF85063, refer to its datasheet, section "Software reset":
"There is a low probability that some devices will have corruption of the registers after the automatic power-on reset if the device is powered up with a residual VDD level. It is required that the VDD starts at zero volts at power up or upon power cycling to ensure that there is no corruption of the registers. If this is not possible, a reset must be initiated after power-up (i.e. when power is stable) with the software reset command"
Trigger SW reset if there is an indication that POR has failed.
Link: https://www.nxp.com/docs/en/data-sheet/PCF85063A.pdf Signed-off-by: Lukas Stockmann lukas.stockmann@siemens.com Signed-off-by: Alexander Sverdlin alexander.sverdlin@siemens.com Link: https://lore.kernel.org/r/20250120093451.30778-1-alexander.sverdlin@siemens.... Signed-off-by: Alexandre Belloni alexandre.belloni@bootlin.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/rtc/rtc-pcf85063.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/rtc/rtc-pcf85063.c b/drivers/rtc/rtc-pcf85063.c index 905986c616559..73848f764559b 100644 --- a/drivers/rtc/rtc-pcf85063.c +++ b/drivers/rtc/rtc-pcf85063.c @@ -35,6 +35,7 @@ #define PCF85063_REG_CTRL1_CAP_SEL BIT(0) #define PCF85063_REG_CTRL1_STOP BIT(5) #define PCF85063_REG_CTRL1_EXT_TEST BIT(7) +#define PCF85063_REG_CTRL1_SWR 0x58
#define PCF85063_REG_CTRL2 0x01 #define PCF85063_CTRL2_AF BIT(6) @@ -589,7 +590,7 @@ static int pcf85063_probe(struct i2c_client *client)
i2c_set_clientdata(client, pcf85063);
- err = regmap_read(pcf85063->regmap, PCF85063_REG_CTRL1, &tmp); + err = regmap_read(pcf85063->regmap, PCF85063_REG_SC, &tmp); if (err) { dev_err(&client->dev, "RTC chip is not present\n"); return err; @@ -599,6 +600,22 @@ static int pcf85063_probe(struct i2c_client *client) if (IS_ERR(pcf85063->rtc)) return PTR_ERR(pcf85063->rtc);
+ /* + * If a Power loss is detected, SW reset the device. + * From PCF85063A datasheet: + * There is a low probability that some devices will have corruption + * of the registers after the automatic power-on reset... + */ + if (tmp & PCF85063_REG_SC_OS) { + dev_warn(&client->dev, + "POR issue detected, sending a SW reset\n"); + err = regmap_write(pcf85063->regmap, PCF85063_REG_CTRL1, + PCF85063_REG_CTRL1_SWR); + if (err < 0) + dev_warn(&client->dev, + "SW reset failed, trying to continue\n"); + } + err = pcf85063_load_capacitance(pcf85063, client->dev.of_node, config->force_cap_7000 ? 7000 : 0); if (err < 0)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt rostedt@goodmis.org
[ Upstream commit c44a14f216f45d8bf1634b52854a699d7090f1e8 ]
Enforce that the address and the size of the memory used by the persistent ring buffer is page aligned. Also update the documentation to reflect this requirement.
Link: https://lore.kernel.org/all/CAHk-=whUOfVucfJRt7E0AH+GV41ELmS4wJqxHDnui6Giddf...
Cc: Masami Hiramatsu mhiramat@kernel.org Cc: Mark Rutland mark.rutland@arm.com Cc: Mathieu Desnoyers mathieu.desnoyers@efficios.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Vincent Donnefort vdonnefort@google.com Cc: Vlastimil Babka vbabka@suse.cz Cc: Mike Rapoport rppt@kernel.org Cc: Jann Horn jannh@google.com Link: https://lore.kernel.org/20250402144953.412882844@goodmis.org Suggested-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Sasha Levin sashal@kernel.org --- Documentation/admin-guide/kernel-parameters.txt | 2 ++ Documentation/trace/debugging.rst | 2 ++ kernel/trace/trace.c | 10 ++++++++++ 3 files changed, 14 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index aa7447f8837cb..56be1fc99bdd4 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -7243,6 +7243,8 @@ This is just one of many ways that can clear memory. Make sure your system keeps the content of memory across reboots before relying on this option.
+ NB: Both the mapped address and size must be page aligned for the architecture. + See also Documentation/trace/debugging.rst
diff --git a/Documentation/trace/debugging.rst b/Documentation/trace/debugging.rst index 54fb16239d703..d54bc500af80b 100644 --- a/Documentation/trace/debugging.rst +++ b/Documentation/trace/debugging.rst @@ -136,6 +136,8 @@ kernel, so only the same kernel is guaranteed to work if the mapping is preserved. Switching to a different kernel version may find a different layout and mark the buffer as invalid.
+NB: Both the mapped address and size must be page aligned for the architecture. + Using trace_printk() in the boot instance ----------------------------------------- By default, the content of trace_printk() goes into the top level tracing diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 0e6d517e74e0f..50aa6d5908329 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -10427,6 +10427,16 @@ __init static void enable_instances(void) }
if (start) { + /* Start and size must be page aligned */ + if (start & ~PAGE_MASK) { + pr_warn("Tracing: mapping start addr %pa is not page aligned\n", &start); + continue; + } + if (size & ~PAGE_MASK) { + pr_warn("Tracing: mapping size %pa is not page aligned\n", &size); + continue; + } + addr = map_pages(start, size); if (addr) { pr_info("Tracing: mapped boot instance %s at physical memory %pa of size 0x%lx\n",
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Begunkov asml.silence@gmail.com
[ Upstream commit 390513642ee6763c7ada07f0a1470474986e6c1c ]
io_uring always switches requests to atomic refcounting for iowq execution before there is any parallilism by setting REQ_F_REFCOUNT, and the flag is not cleared until the request completes. That should be fine as long as the compiler doesn't make up a non existing value for the flags, however KCSAN still complains when the request owner changes oter flag bits:
BUG: KCSAN: data-race in io_req_task_cancel / io_wq_free_work ... read to 0xffff888117207448 of 8 bytes by task 3871 on cpu 0: req_ref_put_and_test io_uring/refs.h:22 [inline]
Skip REQ_F_REFCOUNT checks for iowq, we know it's set.
Reported-by: syzbot+903a2ad71fb3f1e47cf5@syzkaller.appspotmail.com Signed-off-by: Pavel Begunkov asml.silence@gmail.com Link: https://lore.kernel.org/r/d880bc27fb8c3209b54641be4ff6ac02b0e5789a.174367973... Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- io_uring/io_uring.c | 2 +- io_uring/refs.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index d9c02e6b7b921..24b9e9a5105d4 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -1775,7 +1775,7 @@ struct io_wq_work *io_wq_free_work(struct io_wq_work *work) struct io_kiocb *req = container_of(work, struct io_kiocb, work); struct io_kiocb *nxt = NULL;
- if (req_ref_put_and_test(req)) { + if (req_ref_put_and_test_atomic(req)) { if (req->flags & IO_REQ_LINK_FLAGS) nxt = io_req_find_next(req); io_free_req(req); diff --git a/io_uring/refs.h b/io_uring/refs.h index 63982ead9f7da..0d928d87c4ed1 100644 --- a/io_uring/refs.h +++ b/io_uring/refs.h @@ -17,6 +17,13 @@ static inline bool req_ref_inc_not_zero(struct io_kiocb *req) return atomic_inc_not_zero(&req->refs); }
+static inline bool req_ref_put_and_test_atomic(struct io_kiocb *req) +{ + WARN_ON_ONCE(!(data_race(req->flags) & REQ_F_REFCOUNT)); + WARN_ON_ONCE(req_ref_zero_or_close_to_overflow(req)); + return atomic_dec_and_test(&req->refs); +} + static inline bool req_ref_put_and_test(struct io_kiocb *req) { if (likely(!(req->flags & REQ_F_REFCOUNT)))
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh linux@weissschuh.net
[ Upstream commit dbdffaf50ff9cee3259a7cef8a7bd9e0f0ba9f13 ]
Remap source path prefixes in all output, including compiler diagnostics, debug information, macro expansions, etc. This removes a few absolute paths from the binary and also makes it possible to use core::panic::Location properly.
Equivalent to the same configuration done for C sources in commit 1d3730f0012f ("kbuild: support -fmacro-prefix-map for external modules") and commit a73619a845d5 ("kbuild: use -fmacro-prefix-map to make __FILE__ a relative path").
Link: https://doc.rust-lang.org/rustc/command-line-arguments.html#--remap-path-pre... Acked-by: Miguel Ojeda ojeda@kernel.org Signed-off-by: Thomas Weißschuh linux@weissschuh.net Tested-by: Gary Guo gary@garyguo.net Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- Makefile | 1 + 1 file changed, 1 insertion(+)
diff --git a/Makefile b/Makefile index 0c1b99da2c1f2..65663244e2d5c 100644 --- a/Makefile +++ b/Makefile @@ -1070,6 +1070,7 @@ KBUILD_CFLAGS += -fno-builtin-wcslen # change __FILE__ to the relative path to the source directory ifdef building_out_of_srctree KBUILD_CPPFLAGS += $(call cc-option,-fmacro-prefix-map=$(srcroot)/=) +KBUILD_RUSTFLAGS += --remap-path-prefix=$(srcroot)/= endif
# include additional Makefiles when needed
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xi Ruoyao xry111@xry111.site
[ Upstream commit 82c09de2d4c472ab1b973e6e033671020691e637 ]
Without this dependency it's really puzzling when we bisect for a "bad" commit in a series of sorttable change: when "git bisect" switches to another commit, "make" just does nothing to vmlinux.
Signed-off-by: Xi Ruoyao xry111@xry111.site Acked-by: Steven Rostedt (Google) rostedt@goodmis.org Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- scripts/Makefile.vmlinux | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 873caaa553134..fb79fd6b24654 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -79,6 +79,10 @@ ifdef CONFIG_DEBUG_INFO_BTF vmlinux: $(RESOLVE_BTFIDS) endif
+ifdef CONFIG_BUILDTIME_TABLE_SORT +vmlinux: scripts/sorttable +endif + # module.builtin.ranges # --------------------------------------------------------------------------- ifdef CONFIG_BUILTIN_MODULE_RANGES
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleg Nesterov oleg@redhat.com
[ Upstream commit 975776841e689dd8ba36df9fa72ac3eca3c2957a ]
kernel/sched/isolation.c obviously makes no sense without CONFIG_SMP, but the Kconfig entry we have right now:
config CPU_ISOLATION bool "CPU isolation" depends on SMP || COMPILE_TEST
allows the creation of pointless .config's which cause build failures.
Reported-by: kernel test robot lkp@intel.com Signed-off-by: Oleg Nesterov oleg@redhat.com Signed-off-by: Ingo Molnar mingo@kernel.org Link: https://lore.kernel.org/r/20250330134955.GA7910@redhat.com
Closes: https://lore.kernel.org/oe-kbuild-all/202503260646.lrUqD3j5-lkp@intel.com/ Signed-off-by: Sasha Levin sashal@kernel.org --- init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/init/Kconfig b/init/Kconfig index 5ab47c346ef93..dc7b10a1fad2b 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -711,7 +711,7 @@ endmenu # "CPU/Task time and stats accounting"
config CPU_ISOLATION bool "CPU isolation" - depends on SMP || COMPILE_TEST + depends on SMP default y help Make sure that CPUs running critical tasks are not disturbed by
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh thomas.weissschuh@linutronix.de
[ Upstream commit 6c9567e0850be2f0f94ab64fa6512413fd1a1eb1 ]
Restricted pointers ("%pK") are not meant to be used through TP_format(). It can unintentionally expose security sensitive, raw pointer values.
Use regular pointer formatting instead.
Link: https://lore.kernel.org/lkml/20250113171731-dc10e3c1-da64-4af0-b767-7c707046... Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de Reviewed-by: Michael Mueller mimu@linux.ibm.com Link: https://lore.kernel.org/r/20250217-restricted-pointers-s390-v1-1-0e4ace75d8a... Signed-off-by: Janosch Frank frankja@linux.ibm.com Message-ID: 20250217-restricted-pointers-s390-v1-1-0e4ace75d8aa@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/trace-s390.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/s390/kvm/trace-s390.h b/arch/s390/kvm/trace-s390.h index 9ac92dbf680db..9e28f165c114c 100644 --- a/arch/s390/kvm/trace-s390.h +++ b/arch/s390/kvm/trace-s390.h @@ -56,7 +56,7 @@ TRACE_EVENT(kvm_s390_create_vcpu, __entry->sie_block = sie_block; ),
- TP_printk("create cpu %d at 0x%pK, sie block at 0x%pK", + TP_printk("create cpu %d at 0x%p, sie block at 0x%p", __entry->id, __entry->vcpu, __entry->sie_block) );
@@ -255,7 +255,7 @@ TRACE_EVENT(kvm_s390_enable_css, __entry->kvm = kvm; ),
- TP_printk("enabling channel I/O support (kvm @ %pK)\n", + TP_printk("enabling channel I/O support (kvm @ %p)\n", __entry->kvm) );
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh thomas.weissschuh@linutronix.de
[ Upstream commit 0c7fbae5bc782429c97d68dc40fb126748d7e352 ]
Restricted pointers ("%pK") are only meant to be used when directly printing to a file from task context. Otherwise it can unintentionally expose security sensitive, raw pointer values.
Use regular pointer formatting instead.
Link: https://lore.kernel.org/lkml/20250113171731-dc10e3c1-da64-4af0-b767-7c707046... Signed-off-by: Thomas Weißschuh thomas.weissschuh@linutronix.de Reviewed-by: Michael Mueller mimu@linux.ibm.com Tested-by: Michael Mueller mimu@linux.ibm.com Link: https://lore.kernel.org/r/20250217-restricted-pointers-s390-v1-2-0e4ace75d8a... Signed-off-by: Janosch Frank frankja@linux.ibm.com Message-ID: 20250217-restricted-pointers-s390-v1-2-0e4ace75d8aa@linutronix.de Signed-off-by: Sasha Levin sashal@kernel.org --- arch/s390/kvm/intercept.c | 2 +- arch/s390/kvm/interrupt.c | 8 ++++---- arch/s390/kvm/kvm-s390.c | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c index 610dd44a948b2..a06a000f196ce 100644 --- a/arch/s390/kvm/intercept.c +++ b/arch/s390/kvm/intercept.c @@ -95,7 +95,7 @@ static int handle_validity(struct kvm_vcpu *vcpu)
vcpu->stat.exit_validity++; trace_kvm_s390_intercept_validity(vcpu, viwhy); - KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%pK)", viwhy, + KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%p)", viwhy, current->pid, vcpu->kvm);
/* do not warn on invalid runtime instrumentation mode */ diff --git a/arch/s390/kvm/interrupt.c b/arch/s390/kvm/interrupt.c index 07ff0e10cb7f5..c0558f0540073 100644 --- a/arch/s390/kvm/interrupt.c +++ b/arch/s390/kvm/interrupt.c @@ -3161,7 +3161,7 @@ void kvm_s390_gisa_clear(struct kvm *kvm) if (!gi->origin) return; gisa_clear_ipm(gi->origin); - VM_EVENT(kvm, 3, "gisa 0x%pK cleared", gi->origin); + VM_EVENT(kvm, 3, "gisa 0x%p cleared", gi->origin); }
void kvm_s390_gisa_init(struct kvm *kvm) @@ -3178,7 +3178,7 @@ void kvm_s390_gisa_init(struct kvm *kvm) gi->timer.function = gisa_vcpu_kicker; memset(gi->origin, 0, sizeof(struct kvm_s390_gisa)); gi->origin->next_alert = (u32)virt_to_phys(gi->origin); - VM_EVENT(kvm, 3, "gisa 0x%pK initialized", gi->origin); + VM_EVENT(kvm, 3, "gisa 0x%p initialized", gi->origin); }
void kvm_s390_gisa_enable(struct kvm *kvm) @@ -3219,7 +3219,7 @@ void kvm_s390_gisa_destroy(struct kvm *kvm) process_gib_alert_list(); hrtimer_cancel(&gi->timer); gi->origin = NULL; - VM_EVENT(kvm, 3, "gisa 0x%pK destroyed", gisa); + VM_EVENT(kvm, 3, "gisa 0x%p destroyed", gisa); }
void kvm_s390_gisa_disable(struct kvm *kvm) @@ -3468,7 +3468,7 @@ int __init kvm_s390_gib_init(u8 nisc) } }
- KVM_EVENT(3, "gib 0x%pK (nisc=%d) initialized", gib, gib->nisc); + KVM_EVENT(3, "gib 0x%p (nisc=%d) initialized", gib, gib->nisc); goto out;
out_unreg_gal: diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c index 020502af7dc98..8b8e2173fe829 100644 --- a/arch/s390/kvm/kvm-s390.c +++ b/arch/s390/kvm/kvm-s390.c @@ -1020,7 +1020,7 @@ static int kvm_s390_set_mem_control(struct kvm *kvm, struct kvm_device_attr *att } mutex_unlock(&kvm->lock); VM_EVENT(kvm, 3, "SET: max guest address: %lu", new_limit); - VM_EVENT(kvm, 3, "New guest asce: 0x%pK", + VM_EVENT(kvm, 3, "New guest asce: 0x%p", (void *) kvm->arch.gmap->asce); break; } @@ -3464,7 +3464,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) kvm_s390_gisa_init(kvm); INIT_LIST_HEAD(&kvm->arch.pv.need_cleanup); kvm->arch.pv.set_aside = NULL; - KVM_EVENT(3, "vm 0x%pK created by pid %u", kvm, current->pid); + KVM_EVENT(3, "vm 0x%p created by pid %u", kvm, current->pid);
return 0; out_err: @@ -3527,7 +3527,7 @@ void kvm_arch_destroy_vm(struct kvm *kvm) kvm_s390_destroy_adapters(kvm); kvm_s390_clear_float_irqs(kvm); kvm_s390_vsie_destroy(kvm); - KVM_EVENT(3, "vm 0x%pK destroyed", kvm); + KVM_EVENT(3, "vm 0x%p destroyed", kvm); }
/* Section: vcpu related */ @@ -3648,7 +3648,7 @@ static int sca_switch_to_extended(struct kvm *kvm)
free_page((unsigned long)old_sca);
- VM_EVENT(kvm, 2, "Switched to ESCA (0x%pK -> 0x%pK)", + VM_EVENT(kvm, 2, "Switched to ESCA (0x%p -> 0x%p)", old_sca, kvm->arch.sca); return 0; } @@ -4025,7 +4025,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) goto out_free_sie_block; }
- VM_EVENT(vcpu->kvm, 3, "create cpu %d at 0x%pK, sie block at 0x%pK", + VM_EVENT(vcpu->kvm, 3, "create cpu %d at 0x%p, sie block at 0x%p", vcpu->vcpu_id, vcpu, vcpu->arch.sie_block); trace_kvm_s390_create_vcpu(vcpu->vcpu_id, vcpu, vcpu->arch.sie_block);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiaogang Chen xiaogang.chen@amd.com
[ Upstream commit 021ba7f1babd029e714d13a6bf2571b08af96d0f ]
by casting size_limit_mb to u64 when calculate pglimit.
Signed-off-by: Xiaogang ChenXiaogang.Chen@amd.com Link: https://patchwork.freedesktop.org/patch/msgid/20250321164126.329638-1-xiaoga... Signed-off-by: Christian König christian.koenig@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/dma-buf/udmabuf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c index cc7398cc17d67..e74e36a8ecda2 100644 --- a/drivers/dma-buf/udmabuf.c +++ b/drivers/dma-buf/udmabuf.c @@ -393,7 +393,7 @@ static long udmabuf_create(struct miscdevice *device, if (!ubuf) return -ENOMEM;
- pglimit = (size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; + pglimit = ((u64)size_limit_mb * 1024 * 1024) >> PAGE_SHIFT; for (i = 0; i < head->count; i++) { pgoff_t subpgcnt;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long longman@redhat.com
[ Upstream commit 6da580ec656a5ed135db2cdf574b47635611a4d7 ]
Currently, we don't allow the creation of a remote partition underneath another local or remote partition. However, it is currently possible to create a new local partition with an existing remote partition underneath it if top_cpuset is the parent. However, the current cpuset code does not set the effective exclusive CPUs correctly to account for those that are taken by the remote partition.
Changing the code to properly account for those remote partition CPUs under all possible circumstances can be complex. It is much easier to not allow such a configuration which is not that useful. So forbid that by making sure that exclusive_cpus mask doesn't overlap with subpartitions_cpus and invalidate the partition if that happens.
Signed-off-by: Waiman Long longman@redhat.com Signed-off-by: Tejun Heo tj@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/cgroup/cpuset-internal.h | 1 + kernel/cgroup/cpuset.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+)
diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h index 976a8bc3ff603..383963e28ac69 100644 --- a/kernel/cgroup/cpuset-internal.h +++ b/kernel/cgroup/cpuset-internal.h @@ -33,6 +33,7 @@ enum prs_errcode { PERR_CPUSEMPTY, PERR_HKEEPING, PERR_ACCESS, + PERR_REMOTE, };
/* bits in struct cpuset flags field */ diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index d72f843d9feeb..1287274ae1ce9 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -62,6 +62,7 @@ static const char * const perr_strings[] = { [PERR_CPUSEMPTY] = "cpuset.cpus and cpuset.cpus.exclusive are empty", [PERR_HKEEPING] = "partition config conflicts with housekeeping setup", [PERR_ACCESS] = "Enable partition not permitted", + [PERR_REMOTE] = "Have remote partition underneath", };
/* @@ -2840,6 +2841,19 @@ static int update_prstate(struct cpuset *cs, int new_prs) goto out; }
+ /* + * We don't support the creation of a new local partition with + * a remote partition underneath it. This unsupported + * setting can happen only if parent is the top_cpuset because + * a remote partition cannot be created underneath an existing + * local or remote partition. + */ + if ((parent == &top_cpuset) && + cpumask_intersects(cs->exclusive_cpus, subpartitions_cpus)) { + err = PERR_REMOTE; + goto out; + } + /* * If parent is valid partition, enable local partiion. * Otherwise, enable a remote partition.
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 72070e57b0a518ec8e562a2b68fdfc796ef5c040 ]
Commit 57ed58c13256 ("selftests: ublk: enable zero copy for stripe target") added test entry of test_stripe_04, but forgot to add the test script.
So fix the test by adding the script file.
Reported-by: Uday Shankar ushankar@purestorage.com Signed-off-by: Ming Lei ming.lei@redhat.com Reviewed-by: Uday Shankar ushankar@purestorage.com Link: https://lore.kernel.org/r/20250404001849.1443064-1-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- .../testing/selftests/ublk/test_stripe_04.sh | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100755 tools/testing/selftests/ublk/test_stripe_04.sh
diff --git a/tools/testing/selftests/ublk/test_stripe_04.sh b/tools/testing/selftests/ublk/test_stripe_04.sh new file mode 100755 index 0000000000000..1f2b642381d17 --- /dev/null +++ b/tools/testing/selftests/ublk/test_stripe_04.sh @@ -0,0 +1,24 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh + +TID="stripe_04" +ERR_CODE=0 + +_prep_test "stripe" "mkfs & mount & umount on zero copy" + +backfile_0=$(_create_backfile 256M) +backfile_1=$(_create_backfile 256M) +dev_id=$(_add_ublk_dev -t stripe -z -q 2 "$backfile_0" "$backfile_1") +_check_add_dev $TID $? "$backfile_0" "$backfile_1" + +_mkfs_mount_test /dev/ublkb"${dev_id}" +ERR_CODE=$? + +_cleanup_test "stripe" + +_remove_backfile "$backfile_0" +_remove_backfile "$backfile_1" + +_show_result $TID $ERR_CODE
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Shahrouzi gshahrouzi@gmail.com
[ Upstream commit 0ba3a4ab76fd3367b9cb680cad70182c896c795c ]
Move the get_ctx(child_ctx) call and the child_event->ctx assignment to occur immediately after the child event is allocated. Ensure that child_event->ctx is non-NULL before any subsequent error path within inherit_event calls free_event(), satisfying the assumptions of the cleanup code.
Details:
There's no clear Fixes tag, because this bug is a side-effect of multiple interacting commits over time (up to 15 years old), not a single regression.
The code initially incremented refcount then assigned context immediately after the child_event was created. Later, an early validity check for child_event was added before the refcount/assignment. Even later, a WARN_ON_ONCE() cleanup check was added, assuming event->ctx is valid if the pmu_ctx is valid. The problem is that the WARN_ON_ONCE() could trigger after the initial check passed but before child_event->ctx was assigned, violating its precondition. The solution is to assign child_event->ctx right after its initial validation. This ensures the context exists for any subsequent checks or cleanup routines, resolving the WARN_ON_ONCE().
To resolve it, defer the refcount update and child_event->ctx assignment directly after child_event->pmu_ctx is set but before checking if the parent event is orphaned. The cleanup routine depends on event->pmu_ctx being non-NULL before it verifies event->ctx is non-NULL. This also maintains the author's original intent of passing in child_ctx to find_get_pmu_context before its refcount/assignment.
[ mingo: Expanded the changelog from another email by Gabriel Shahrouzi. ]
Reported-by: syzbot+ff3aa851d46ab82953a3@syzkaller.appspotmail.com Signed-off-by: Gabriel Shahrouzi gshahrouzi@gmail.com Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Peter Zijlstra peterz@infradead.org Cc: Ravi Bangoria ravi.bangoria@amd.com Cc: Kan Liang kan.liang@linux.intel.com Cc: Oleg Nesterov oleg@redhat.com Cc: Alexander Shishkin alexander.shishkin@linux.intel.com Link: https://lore.kernel.org/r/20250405203036.582721-1-gshahrouzi@gmail.com Closes: https://syzkaller.appspot.com/bug?extid=ff3aa851d46ab82953a3 Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/events/core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c index ee6b7281a1994..93ce810384c92 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -13701,6 +13701,9 @@ inherit_event(struct perf_event *parent_event, if (IS_ERR(child_event)) return child_event;
+ get_ctx(child_ctx); + child_event->ctx = child_ctx; + pmu_ctx = find_get_pmu_context(child_event->pmu, child_ctx, child_event); if (IS_ERR(pmu_ctx)) { free_event(child_event); @@ -13723,8 +13726,6 @@ inherit_event(struct perf_event *parent_event, return NULL; }
- get_ctx(child_ctx); - /* * Make the child state follow the state of the parent event, * not its attr.disabled bit. We hold the parent's mutex, @@ -13745,7 +13746,6 @@ inherit_event(struct perf_event *parent_event, local64_set(&hwc->period_left, sample_period); }
- child_event->ctx = child_ctx; child_event->overflow_handler = parent_event->overflow_handler; child_event->overflow_handler_context = parent_event->overflow_handler_context;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk jason.andryuk@amd.com
[ Upstream commit 0f2946bb172632e122d4033e0b03f85230a29510 ]
xen-acpi-processor functions under a PVH dom0 with only a xen_initial_domain() runtime check. Change the Kconfig dependency from PV dom0 to generic dom0 to reflect that.
Suggested-by: Jan Beulich jbeulich@suse.com Signed-off-by: Jason Andryuk jason.andryuk@amd.com Reviewed-by: Juergen Gross jgross@suse.com Tested-by: Jan Beulich jbeulich@suse.com Signed-off-by: Juergen Gross jgross@suse.com Message-ID: 20250331172913.51240-1-jason.andryuk@amd.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/xen/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index f7d6f47971fdf..24f485827e039 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -278,7 +278,7 @@ config XEN_PRIVCMD_EVENTFD
config XEN_ACPI_PROCESSOR tristate "Xen ACPI processor" - depends on XEN && XEN_PV_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ + depends on XEN && XEN_DOM0 && X86 && ACPI_PROCESSOR && CPU_FREQ default m help This ACPI processor uploads Power Management information to the Xen
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König u.kleine-koenig@baylibre.com
[ Upstream commit 00e53d0f4baedd72196b65f00698b2a5a537dc2b ]
Waveform parameters are supposed to be rounded down to the next value possible for the hardware. However when a requested value is too small, .round_waveform_tohw() is supposed to pick the next bigger value and return 1. Let pwm_set_waveform() behave in the same way.
This creates consistency between pwm_set_waveform_might_sleep() with exact=false and pwm_round_waveform_might_sleep() + pwm_set_waveform_might_sleep() with exact=true.
The PWM_DEBUG rounding check has to be adapted to only trigger if no uprounding happend.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Tested-by: Trevor Gamblin tgamblin@baylibre.com Link: https://lore.kernel.org/r/353dc6ae31be815e41fd3df89c257127ca0d1a09.174384473... Signed-off-by: Uwe Kleine-König ukleinek@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/core.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index ccd54c089bab8..0e4df71c2cef1 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c @@ -322,7 +322,7 @@ static int __pwm_set_waveform(struct pwm_device *pwm, const struct pwm_ops *ops = chip->ops; char wfhw[WFHWSIZE]; struct pwm_waveform wf_rounded; - int err; + int err, ret_tohw;
BUG_ON(WFHWSIZE < ops->sizeof_wfhw);
@@ -332,16 +332,16 @@ static int __pwm_set_waveform(struct pwm_device *pwm, if (!pwm_wf_valid(wf)) return -EINVAL;
- err = __pwm_round_waveform_tohw(chip, pwm, wf, &wfhw); - if (err) - return err; + ret_tohw = __pwm_round_waveform_tohw(chip, pwm, wf, &wfhw); + if (ret_tohw < 0) + return ret_tohw;
if ((IS_ENABLED(CONFIG_PWM_DEBUG) || exact) && wf->period_length_ns) { err = __pwm_round_waveform_fromhw(chip, pwm, &wfhw, &wf_rounded); if (err) return err;
- if (IS_ENABLED(CONFIG_PWM_DEBUG) && !pwm_check_rounding(wf, &wf_rounded)) + if (IS_ENABLED(CONFIG_PWM_DEBUG) && ret_tohw == 0 && !pwm_check_rounding(wf, &wf_rounded)) dev_err(&chip->dev, "Wrong rounding: requested %llu/%llu [+%llu], result %llu/%llu [+%llu]\n", wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns, wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns); @@ -382,7 +382,8 @@ static int __pwm_set_waveform(struct pwm_device *pwm, wf_rounded.duty_length_ns, wf_rounded.period_length_ns, wf_rounded.duty_offset_ns, wf_set.duty_length_ns, wf_set.period_length_ns, wf_set.duty_offset_ns); } - return 0; + + return ret_tohw; }
/**
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uwe Kleine-König u.kleine-koenig@baylibre.com
[ Upstream commit a85e08a05bf77d5d03b4ac0c59768a606a1b640b ]
The .round_waveform_tohw() is supposed to return 1 if the requested waveform cannot be implemented by rounding down all parameters. Also adapt the corresponding comment to better describe why the implemented procedure is right.
Signed-off-by: Uwe Kleine-König u.kleine-koenig@baylibre.com Tested-by: Trevor Gamblin tgamblin@baylibre.com Link: https://lore.kernel.org/r/ba451573f0218d76645f068cec78bd97802cf010.174384473... Signed-off-by: Uwe Kleine-König ukleinek@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/pwm/pwm-axi-pwmgen.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/pwm/pwm-axi-pwmgen.c b/drivers/pwm/pwm-axi-pwmgen.c index 4259a0db9ff45..4337c8f5acf05 100644 --- a/drivers/pwm/pwm-axi-pwmgen.c +++ b/drivers/pwm/pwm-axi-pwmgen.c @@ -75,6 +75,7 @@ static int axi_pwmgen_round_waveform_tohw(struct pwm_chip *chip, { struct axi_pwmgen_waveform *wfhw = _wfhw; struct axi_pwmgen_ddata *ddata = axi_pwmgen_ddata_from_chip(chip); + int ret = 0;
if (wf->period_length_ns == 0) { *wfhw = (struct axi_pwmgen_waveform){ @@ -91,12 +92,15 @@ static int axi_pwmgen_round_waveform_tohw(struct pwm_chip *chip, if (wfhw->period_cnt == 0) { /* * The specified period is too short for the hardware. - * Let's round .duty_cycle down to 0 to get a (somewhat) - * valid result. + * So round up .period_cnt to 1 (i.e. the smallest + * possible period). With .duty_cycle and .duty_offset + * being less than or equal to .period, their rounded + * value must be 0. */ wfhw->period_cnt = 1; wfhw->duty_cycle_cnt = 0; wfhw->duty_offset_cnt = 0; + ret = 1; } else { wfhw->duty_cycle_cnt = min_t(u64, mul_u64_u32_div(wf->duty_length_ns, ddata->clk_rate_hz, NSEC_PER_SEC), @@ -111,7 +115,7 @@ static int axi_pwmgen_round_waveform_tohw(struct pwm_chip *chip, pwm->hwpwm, wf->duty_length_ns, wf->period_length_ns, wf->duty_offset_ns, ddata->clk_rate_hz, wfhw->period_cnt, wfhw->duty_cycle_cnt, wfhw->duty_offset_cnt);
- return 0; + return ret; }
static int axi_pwmgen_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke hare@kernel.org
[ Upstream commit 9546ad1a9bda7362492114f5866b95b0ac4a100e ]
Scanning for namespaces can take some time, so if the target is reconfigured while the scan is running we may miss a Attached Namespace Attribute Changed AEN.
Check if the NVME_AER_NOTICE_NS_CHANGED bit is set once the scan has finished, and requeue scanning to pick up any missed change.
Signed-off-by: Hannes Reinecke hare@kernel.org Reviewed-by: Keith Busch kbusch@kernel.org Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 8359d0aa0e44b..70f9c2d2b1130 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4292,6 +4292,10 @@ static void nvme_scan_work(struct work_struct *work) nvme_scan_ns_sequential(ctrl); } mutex_unlock(&ctrl->scan_lock); + + /* Requeue if we have missed AENs */ + if (test_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) + nvme_queue_scan(ctrl); }
/*
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit b988685388effd648150aab272533f833a2a70f0 ]
When AC adapter is unplugged or plugged in EC wakes from HW sleep but APU doesn't enter back into HW sleep.
The reason this happens is that, when the APU exits HW sleep, the power rails controlled by the EC will power up the TCON. The TCON has a GPIO that will be toggled at this time. The GPIO is not marked as a wakeup source, but the GPIO controller still has an unserviced interrupt. Unserviced interrupts will block entering HW sleep again. Clearing the GPIO doesn't help as the TCON continues to assert it until it's been initialized by i2c-hid.
Fixing this would require TCON F/W changes and it's already broken in the wild on production hardware.
To avoid triggering this issue add a quirk to avoid letting EC wake up system at all. The power button still works properly on this system.
Reported-by: Antheas Kapenekakis lkml@antheas.dev Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3929 Link: https://github.com/bazzite-org/patchwork/commit/95b93b2852718ee1e808c72e6b18... Co-developed-by: Antheas Kapenekakis lkml@antheas.dev Signed-off-by: Antheas Kapenekakis lkml@antheas.dev Signed-off-by: Mario Limonciello mario.limonciello@amd.com Link: https://patch.msgid.link/20250401133858.1892077-1-superm1@kernel.org [ rjw: Changelog edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/ec.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 8db09d81918fb..3c5f34892734e 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -2301,6 +2301,34 @@ static const struct dmi_system_id acpi_ec_no_wakeup[] = { DMI_MATCH(DMI_PRODUCT_FAMILY, "103C_5336AN HP ZHAN 66 Pro"), }, }, + /* + * Lenovo Legion Go S; touchscreen blocks HW sleep when woken up from EC + * https://gitlab.freedesktop.org/drm/amd/-/issues/3929 + */ + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83L3"), + } + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83N6"), + } + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83Q2"), + } + }, + { + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "83Q3"), + } + }, { }, };
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Marc Eurin jmeurin@google.com
[ Upstream commit 7ab4f0e37a0f4207e742a8de69be03984db6ebf0 ]
The end of table checks should be done with the structure size, but 2 of the 3 similar calls use the pointer size.
Signed-off-by: Jean-Marc Eurin jmeurin@google.com Link: https://patch.msgid.link/20250402001542.2600671-1-jmeurin@google.com [ rjw: Subject edits ] Signed-off-by: Rafael J. Wysocki rafael.j.wysocki@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/acpi/pptt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c index a35dd0e41c270..f73ce6e13065d 100644 --- a/drivers/acpi/pptt.c +++ b/drivers/acpi/pptt.c @@ -229,7 +229,7 @@ static int acpi_pptt_leaf_node(struct acpi_table_header *table_hdr, node_entry = ACPI_PTR_DIFF(node, table_hdr); entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, sizeof(struct acpi_table_pptt)); - proc_sz = sizeof(struct acpi_pptt_processor *); + proc_sz = sizeof(struct acpi_pptt_processor);
while ((unsigned long)entry + proc_sz < table_end) { cpu_node = (struct acpi_pptt_processor *)entry; @@ -270,7 +270,7 @@ static struct acpi_pptt_processor *acpi_find_processor_node(struct acpi_table_he table_end = (unsigned long)table_hdr + table_hdr->length; entry = ACPI_ADD_PTR(struct acpi_subtable_header, table_hdr, sizeof(struct acpi_table_pptt)); - proc_sz = sizeof(struct acpi_pptt_processor *); + proc_sz = sizeof(struct acpi_pptt_processor);
/* find the processor structure associated with this cpuid */ while ((unsigned long)entry + proc_sz < table_end) {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emily Deng Emily.Deng@amd.com
[ Upstream commit ba6d8f878d6180d4d0ed0574479fc1e232928184 ]
Disable per queue reset for sriov.
Signed-off-by: Emily Deng Emily.Deng@amd.com Reviewed-by: Jonathan Kim jonathan.kim@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_topology.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index ceb9fb475ef13..62a9a9ccf9bb6 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c @@ -2000,7 +2000,8 @@ static void kfd_topology_set_capabilities(struct kfd_topology_device *dev) dev->node_props.capability |= HSA_CAP_TRAP_DEBUG_PRECISE_MEMORY_OPERATIONS_SUPPORTED;
- dev->node_props.capability |= HSA_CAP_PER_QUEUE_RESET_SUPPORTED; + if (!amdgpu_sriov_vf(dev->gpu->adev)) + dev->node_props.capability |= HSA_CAP_PER_QUEUE_RESET_SUPPORTED; } else { dev->node_props.debug_prop |= HSA_DBG_WATCH_ADDR_MASK_LO_BIT_GFX10 | HSA_DBG_WATCH_ADDR_MASK_HI_BIT;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jay Cornwall jay.cornwall@amd.com
[ Upstream commit 3666ed821832f42baaf25f362680dda603cde732 ]
KIQ invalidate_tlbs request has been seen to marginally exceed the configured 100 ms timeout on systems under load.
All other KIQ requests in the driver use a 10 second timeout. Use a similar timeout implementation on the invalidate_tlbs path.
v2: Poll once before msleep v3: Fix return value
Signed-off-by: Jay Cornwall jay.cornwall@amd.com Cc: Kent Russell kent.russell@amd.com Reviewed-by: Harish Kasiviswanathan Harish.Kasiviswanathan@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.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c | 19 ++++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 69895fccb474a..ab04d56b4fe36 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -352,7 +352,6 @@ enum amdgpu_kiq_irq { AMDGPU_CP_KIQ_IRQ_DRIVER0 = 0, AMDGPU_CP_KIQ_IRQ_LAST }; -#define SRIOV_USEC_TIMEOUT 1200000 /* wait 12 * 100ms for SRIOV */ #define MAX_KIQ_REG_WAIT 5000 /* in usecs, 5ms */ #define MAX_KIQ_REG_BAILOUT_INTERVAL 5 /* in msecs, 5ms */ #define MAX_KIQ_REG_TRY 1000 diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c index 1c19a65e65533..ef74259c448d7 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c @@ -678,12 +678,10 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid, uint32_t flush_type, bool all_hub, uint32_t inst) { - u32 usec_timeout = amdgpu_sriov_vf(adev) ? SRIOV_USEC_TIMEOUT : - adev->usec_timeout; struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring; struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst]; unsigned int ndw; - int r; + int r, cnt = 0; uint32_t seq;
/* @@ -740,10 +738,21 @@ int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
amdgpu_ring_commit(ring); spin_unlock(&adev->gfx.kiq[inst].ring_lock); - if (amdgpu_fence_wait_polling(ring, seq, usec_timeout) < 1) { + + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); + + might_sleep(); + while (r < 1 && cnt++ < MAX_KIQ_REG_TRY && + !amdgpu_reset_pending(adev->reset_domain)) { + msleep(MAX_KIQ_REG_BAILOUT_INTERVAL); + r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT); + } + + if (cnt > MAX_KIQ_REG_TRY) { dev_err(adev->dev, "timeout waiting for kiq fence\n"); r = -ETIME; - } + } else + r = 0; }
error_unlock_reset:
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Julia Filipchuk julia.filipchuk@intel.com
[ Upstream commit 00e0ae4f1f872800413c819f8a2a909dc29cdc35 ]
Extend Wa_14022293748, Wa_22019794406 to Xe3_LPG
Signed-off-by: Julia Filipchuk julia.filipchuk@intel.com Reviewed-by: Tejas Upadhyay tejas.upadhyay@intel.com Signed-off-by: John Harrison John.C.Harrison@Intel.com Link: https://lore.kernel.org/r/20250325224310.1455499-1-julia.filipchuk@intel.com (cherry picked from commit 32af900f2c6b1846fd3ede8ad36dd180d7e4ae70) Signed-off-by: Lucas De Marchi lucas.demarchi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/xe/xe_wa_oob.rules | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_wa_oob.rules b/drivers/gpu/drm/xe/xe_wa_oob.rules index 40438c3d9b723..32d3853b08ec8 100644 --- a/drivers/gpu/drm/xe/xe_wa_oob.rules +++ b/drivers/gpu/drm/xe/xe_wa_oob.rules @@ -30,8 +30,10 @@ 13011645652 GRAPHICS_VERSION(2004) 14022293748 GRAPHICS_VERSION(2001) GRAPHICS_VERSION(2004) + GRAPHICS_VERSION_RANGE(3000, 3001) 22019794406 GRAPHICS_VERSION(2001) GRAPHICS_VERSION(2004) + GRAPHICS_VERSION_RANGE(3000, 3001) 22019338487 MEDIA_VERSION(2000) GRAPHICS_VERSION(2001) MEDIA_VERSION(3000), MEDIA_STEP(A0, B0), FUNC(xe_rtp_match_not_sriov_vf)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke hare@kernel.org
[ Upstream commit 62baf70c327444338c34703c71aa8cc8e4189bd6 ]
When scanning for new namespaces we might have missed an ANA AEN.
The NVMe base spec (NVMe Base Specification v2.1, Figure 151 'Asynchonous Event Information - Notice': Asymmetric Namespace Access Change) states:
A controller shall not send this even if an Attached Namespace Attribute Changed asynchronous event [...] is sent for the same event.
so we need to re-read the ANA log page after we rescanned the namespace list to update the ANA states of the new namespaces.
Signed-off-by: Hannes Reinecke hare@kernel.org Reviewed-by: Keith Busch kbusch@kernel.org Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/core.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 70f9c2d2b1130..edee1ec3d4780 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4296,6 +4296,11 @@ static void nvme_scan_work(struct work_struct *work) /* Requeue if we have missed AENs */ if (test_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) nvme_queue_scan(ctrl); +#ifdef CONFIG_NVME_MULTIPATH + else + /* Re-read the ANA log page to not miss updates */ + queue_work(nvme_wq, &ctrl->ana_work); +#endif }
/*
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Uday Shankar ushankar@purestorage.com
[ Upstream commit e3105f54a51554fb1bbf19dcaf93c4411d2d6c8a ]
The function returns bool so we should return false, not NULL. No functional changes are expected.
Signed-off-by: Uday Shankar ushankar@purestorage.com Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/host/multipath.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/multipath.c b/drivers/nvme/host/multipath.c index 2a76355650830..f39823cde62c7 100644 --- a/drivers/nvme/host/multipath.c +++ b/drivers/nvme/host/multipath.c @@ -427,7 +427,7 @@ static bool nvme_available_path(struct nvme_ns_head *head) struct nvme_ns *ns;
if (!test_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) - return NULL; + return false;
list_for_each_entry_srcu(ns, &head->list, siblings, srcu_read_lock_held(&head->srcu)) {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 9f9cc012c2cbac4833746a0182e06a8eec940d19 ]
In preparation for simplifying INSN_SYSCALL, make validate_unret() terminate control flow on UD2 just like validate_branch() already does.
Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/ce841269e7e28c8b7f32064464a9821034d724ff.174409521... Signed-off-by: Sasha Levin sashal@kernel.org --- tools/objtool/check.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/tools/objtool/check.c b/tools/objtool/check.c index bbfd81f49802e..eb9109b4aaf35 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3870,6 +3870,9 @@ static int validate_unret(struct objtool_file *file, struct instruction *insn) break; }
+ if (insn->dead_end) + return 0; + if (!next) { WARN_INSN(insn, "teh end!"); return -1;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko andriy.shevchenko@linux.intel.com
[ Upstream commit b8c7a1ac884cc267d1031f8de07f1a689a69fbab ]
The regulator comment in of_gpio_set_polarity_by_property() made on top of a couple of the cases, while Atmel HSMCI quirk is not related to that. Make it clear by moving Atmel HSMCI quirk up out of the scope of the regulator comment.
Signed-off-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Link: https://lore.kernel.org/r/20250402122058.1517393-3-andriy.shevchenko@linux.i... Signed-off-by: Bartosz Golaszewski bartosz.golaszewski@linaro.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpio/gpiolib-of.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index 176e9142fd8f8..56f13e4fa3614 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -259,6 +259,9 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np, { "fsl,imx8qm-fec", "phy-reset-gpios", "phy-reset-active-high" }, { "fsl,s32v234-fec", "phy-reset-gpios", "phy-reset-active-high" }, #endif +#if IS_ENABLED(CONFIG_MMC_ATMELMCI) + { "atmel,hsmci", "cd-gpios", "cd-inverted" }, +#endif #if IS_ENABLED(CONFIG_PCI_IMX6) { "fsl,imx6q-pcie", "reset-gpio", "reset-gpio-active-high" }, { "fsl,imx6sx-pcie", "reset-gpio", "reset-gpio-active-high" }, @@ -284,9 +287,6 @@ static void of_gpio_set_polarity_by_property(const struct device_node *np, #if IS_ENABLED(CONFIG_REGULATOR_GPIO) { "regulator-gpio", "enable-gpio", "enable-active-high" }, { "regulator-gpio", "enable-gpios", "enable-active-high" }, -#endif -#if IS_ENABLED(CONFIG_MMC_ATMELMCI) - { "atmel,hsmci", "cd-gpios", "cd-inverted" }, #endif }; unsigned int i;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roger Pau Monne roger.pau@citrix.com
[ Upstream commit 64a66e2c3b3113dc78a6124e14825d68ddc2e188 ]
When running as a PVH dom0 the ACPI tables exposed to Linux are (mostly) the native ones, thus exposing the C and P states, that can lead to attachment of CPU idle and frequency drivers. However the entity in control of the CPU C and P states is Xen, as dom0 doesn't have a full view of the system load, neither has all CPUs assigned and identity pinned.
Like it's done for classic PV guests, prevent Linux from using idle or frequency state drivers when running as a PVH dom0.
On an AMD EPYC 7543P system without this fix a Linux PVH dom0 will keep the host CPUs spinning at 100% even when dom0 is completely idle, as it's attempting to use the acpi_idle driver.
Signed-off-by: Roger Pau Monné roger.pau@citrix.com Reviewed-by: Jason Andryuk jason.andryuk@amd.com Signed-off-by: Juergen Gross jgross@suse.com Message-ID: 20250407101842.67228-1-roger.pau@citrix.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/xen/enlighten_pvh.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/arch/x86/xen/enlighten_pvh.c b/arch/x86/xen/enlighten_pvh.c index 0e3d930bcb89e..9d25d9373945c 100644 --- a/arch/x86/xen/enlighten_pvh.c +++ b/arch/x86/xen/enlighten_pvh.c @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 #include <linux/acpi.h> +#include <linux/cpufreq.h> +#include <linux/cpuidle.h> #include <linux/export.h> #include <linux/mm.h>
@@ -123,8 +125,23 @@ static void __init pvh_arch_setup(void) { pvh_reserve_extra_memory();
- if (xen_initial_domain()) + if (xen_initial_domain()) { xen_add_preferred_consoles(); + + /* + * Disable usage of CPU idle and frequency drivers: when + * running as hardware domain the exposed native ACPI tables + * causes idle and/or frequency drivers to attach and + * malfunction. It's Xen the entity that controls the idle and + * frequency states. + * + * For unprivileged domains the exposed ACPI tables are + * fabricated and don't contain such data. + */ + disable_cpuidle(); + disable_cpufreq(); + WARN_ON(xen_set_default_idle()); + } }
void __init xen_pvh_init(struct boot_params *boot_params)
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo qiuxu.zhuo@intel.com
[ Upstream commit 197c1eaa7ba633a482ed7588eea6fd4aa57e08d4 ]
When running the mincore_selftest on a system with an XFS file system, it failed the "check_file_mmap" test case due to the read-ahead pages reaching the end of the file. The failure log is as below:
RUN global.check_file_mmap ... mincore_selftest.c:264:check_file_mmap:Expected i (1024) < vec_size (1024) mincore_selftest.c:265:check_file_mmap:Read-ahead pages reached the end of the file check_file_mmap: Test failed FAIL global.check_file_mmap
This is because the read-ahead window size of the XFS file system on this machine is 4 MB, which is larger than the size from the #PF address to the end of the file. As a result, all the pages for this file are populated.
blockdev --getra /dev/nvme0n1p5 8192 blockdev --getbsz /dev/nvme0n1p5 512
This issue can be fixed by extending the current FILE_SIZE 4MB to a larger number, but it will still fail if the read-ahead window size of the file system is larger enough. Additionally, in the real world, read-ahead pages reaching the end of the file can happen and is an expected behavior. Therefore, allowing read-ahead pages to reach the end of the file is a better choice for the "check_file_mmap" test case.
Link: https://lore.kernel.org/r/20250311080940.21413-1-qiuxu.zhuo@intel.com Reported-by: Yi Lai yi1.lai@intel.com Signed-off-by: Qiuxu Zhuo qiuxu.zhuo@intel.com Signed-off-by: Shuah Khan skhan@linuxfoundation.org Signed-off-by: Sasha Levin sashal@kernel.org --- tools/testing/selftests/mincore/mincore_selftest.c | 3 --- 1 file changed, 3 deletions(-)
diff --git a/tools/testing/selftests/mincore/mincore_selftest.c b/tools/testing/selftests/mincore/mincore_selftest.c index 0fd4b00bd345b..17ed3e9917ca1 100644 --- a/tools/testing/selftests/mincore/mincore_selftest.c +++ b/tools/testing/selftests/mincore/mincore_selftest.c @@ -261,9 +261,6 @@ TEST(check_file_mmap) TH_LOG("No read-ahead pages found in memory"); }
- EXPECT_LT(i, vec_size) { - TH_LOG("Read-ahead pages reached the end of the file"); - } /* * End of the readahead window. The rest of the pages shouldn't * be in memory.
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit fc9fd3f98423367c79e0bd85a9515df26dc1b3cc ]
write_ibpb() does IBPB, which (among other things) flushes branch type predictions on AMD. If the CPU has SRSO_NO, or if the SRSO mitigation has been disabled, branch type flushing isn't needed, in which case the lighter-weight SBPB can be used.
The 'x86_pred_cmd' variable already keeps track of whether IBPB or SBPB should be used. Use that instead of hardcoding IBPB.
Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Link: https://lore.kernel.org/r/17c5dcd14b29199b75199d67ff7758de9d9a4928.174414825... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/entry/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/entry/entry.S b/arch/x86/entry/entry.S index b7ea3e8e9eccd..58e3124ee2b42 100644 --- a/arch/x86/entry/entry.S +++ b/arch/x86/entry/entry.S @@ -18,7 +18,7 @@
SYM_FUNC_START(entry_ibpb) movl $MSR_IA32_PRED_CMD, %ecx - movl $PRED_CMD_IBPB, %eax + movl _ASM_RIP(x86_pred_cmd), %eax xorl %edx, %edx wrmsr
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 18bae0dfec15b24ec14ca17dc18603372f5f254f ]
eIBRS protects against guest->host RSB underflow/poisoning attacks. Adding retpoline to the mix doesn't change that. Retpoline has a balanced CALL/RET anyway.
So the current full RSB filling on VMEXIT with eIBRS+retpoline is overkill. Disable it or do the VMEXIT_LITE mitigation if needed.
Suggested-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Reviewed-by: Amit Shah amit.shah@amd.com Reviewed-by: Nikolay Borisov nik.borisov@suse.com Cc: Paolo Bonzini pbonzini@redhat.com Cc: Vitaly Kuznetsov vkuznets@redhat.com Cc: Sean Christopherson seanjc@google.com Cc: David Woodhouse dwmw2@infradead.org Link: https://lore.kernel.org/r/84a1226e5c9e2698eae1b5ade861f1b8bf3677dc.174414825... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/bugs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index a5d0998d76049..41b4d9018633e 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1604,20 +1604,20 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_ case SPECTRE_V2_NONE: return;
- case SPECTRE_V2_EIBRS_LFENCE: case SPECTRE_V2_EIBRS: + case SPECTRE_V2_EIBRS_LFENCE: + case SPECTRE_V2_EIBRS_RETPOLINE: if (boot_cpu_has_bug(X86_BUG_EIBRS_PBRSB)) { - setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE); pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n"); + setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE); } return;
- case SPECTRE_V2_EIBRS_RETPOLINE: case SPECTRE_V2_RETPOLINE: case SPECTRE_V2_LFENCE: case SPECTRE_V2_IBRS: - setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n"); + setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); return; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
[ Upstream commit 27ce8299bc1ec6df8306073785ff82b30b3cc5ee ]
User->user Spectre v2 attacks (including RSB) across context switches are already mitigated by IBPB in cond_mitigation(), if enabled globally or if either the prev or the next task has opted in to protection. RSB filling without IBPB serves no purpose for protecting user space, as indirect branches are still vulnerable.
User->kernel RSB attacks are mitigated by eIBRS. In which case the RSB filling on context switch isn't needed, so remove it.
Suggested-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Reviewed-by: Amit Shah amit.shah@amd.com Reviewed-by: Nikolay Borisov nik.borisov@suse.com Link: https://lore.kernel.org/r/98cdefe42180358efebf78e3b80752850c7a3e1b.174414825... Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/cpu/bugs.c | 24 ++++++++++++------------ arch/x86/mm/tlb.c | 6 +++--- 2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index 41b4d9018633e..9152285aaaf96 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c @@ -1578,7 +1578,7 @@ static void __init spec_ctrl_disable_kernel_rrsba(void) rrsba_disabled = true; }
-static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_mitigation mode) +static void __init spectre_v2_select_rsb_mitigation(enum spectre_v2_mitigation mode) { /* * Similar to context switches, there are two types of RSB attacks @@ -1602,7 +1602,7 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_ */ switch (mode) { case SPECTRE_V2_NONE: - return; + break;
case SPECTRE_V2_EIBRS: case SPECTRE_V2_EIBRS_LFENCE: @@ -1611,18 +1611,21 @@ static void __init spectre_v2_determine_rsb_fill_type_at_vmexit(enum spectre_v2_ pr_info("Spectre v2 / PBRSB-eIBRS: Retire a single CALL on VMEXIT\n"); setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT_LITE); } - return; + break;
case SPECTRE_V2_RETPOLINE: case SPECTRE_V2_LFENCE: case SPECTRE_V2_IBRS: - pr_info("Spectre v2 / SpectreRSB : Filling RSB on VMEXIT\n"); + pr_info("Spectre v2 / SpectreRSB: Filling RSB on context switch and VMEXIT\n"); + setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); setup_force_cpu_cap(X86_FEATURE_RSB_VMEXIT); - return; - } + break;
- pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation at VM exit"); - dump_stack(); + default: + pr_warn_once("Unknown Spectre v2 mode, disabling RSB mitigation\n"); + dump_stack(); + break; + } }
/* @@ -1854,10 +1857,7 @@ static void __init spectre_v2_select_mitigation(void) * * FIXME: Is this pointless for retbleed-affected AMD? */ - setup_force_cpu_cap(X86_FEATURE_RSB_CTXSW); - pr_info("Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\n"); - - spectre_v2_determine_rsb_fill_type_at_vmexit(mode); + spectre_v2_select_rsb_mitigation(mode);
/* * Retpoline protects the kernel, but doesn't protect firmware. IBRS diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 6cf881a942bbe..e491c75b2a688 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -389,9 +389,9 @@ static void cond_mitigation(struct task_struct *next) prev_mm = this_cpu_read(cpu_tlbstate.last_user_mm_spec);
/* - * Avoid user/user BTB poisoning by flushing the branch predictor - * when switching between processes. This stops one process from - * doing Spectre-v2 attacks on another. + * Avoid user->user BTB/RSB poisoning by flushing them when switching + * between processes. This stops one process from doing Spectre-v2 + * attacks on another. * * Both, the conditional and the always IBPB mode use the mm * pointer to avoid the IBPB when switching between tasks of the
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Wagner wagi@kernel.org
[ Upstream commit b0b26ad0e1943de25ce82a7e5af3574f31b1cf99 ]
The reference counting code can be simplified. Instead taking a tgtport refrerence at the beginning of nvmet_fc_alloc_hostport and put it back if not a new hostport object is allocated, only take it when a new hostport object is allocated.
Signed-off-by: Daniel Wagner wagi@kernel.org Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/fc.c | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-)
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c index 7318b736d4141..78c4a417f477e 100644 --- a/drivers/nvme/target/fc.c +++ b/drivers/nvme/target/fc.c @@ -1028,33 +1028,24 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) struct nvmet_fc_hostport *newhost, *match = NULL; unsigned long flags;
+ /* + * Caller holds a reference on tgtport. + */ + /* if LLDD not implemented, leave as NULL */ if (!hosthandle) return NULL;
- /* - * take reference for what will be the newly allocated hostport if - * we end up using a new allocation - */ - if (!nvmet_fc_tgtport_get(tgtport)) - return ERR_PTR(-EINVAL); - spin_lock_irqsave(&tgtport->lock, flags); match = nvmet_fc_match_hostport(tgtport, hosthandle); spin_unlock_irqrestore(&tgtport->lock, flags);
- if (match) { - /* no new allocation - release reference */ - nvmet_fc_tgtport_put(tgtport); + if (match) return match; - }
newhost = kzalloc(sizeof(*newhost), GFP_KERNEL); - if (!newhost) { - /* no new allocation - release reference */ - nvmet_fc_tgtport_put(tgtport); + if (!newhost) return ERR_PTR(-ENOMEM); - }
spin_lock_irqsave(&tgtport->lock, flags); match = nvmet_fc_match_hostport(tgtport, hosthandle); @@ -1063,6 +1054,7 @@ nvmet_fc_alloc_hostport(struct nvmet_fc_tgtport *tgtport, void *hosthandle) kfree(newhost); newhost = match; } else { + nvmet_fc_tgtport_get(tgtport); newhost->tgtport = tgtport; newhost->hosthandle = hosthandle; INIT_LIST_HEAD(&newhost->host_list);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Wagner wagi@kernel.org
[ Upstream commit 70289ae5cac4d3a39575405aaf63330486cea030 ]
Do not leak the tgtport reference when the work is already scheduled.
Signed-off-by: Daniel Wagner wagi@kernel.org Reviewed-by: Hannes Reinecke hare@suse.de Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/fc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/nvme/target/fc.c b/drivers/nvme/target/fc.c index 78c4a417f477e..ef8c5961e10c8 100644 --- a/drivers/nvme/target/fc.c +++ b/drivers/nvme/target/fc.c @@ -1089,7 +1089,8 @@ static void nvmet_fc_schedule_delete_assoc(struct nvmet_fc_tgt_assoc *assoc) { nvmet_fc_tgtport_get(assoc->tgtport); - queue_work(nvmet_wq, &assoc->del_work); + if (!queue_work(nvmet_wq, &assoc->del_work)) + nvmet_fc_tgtport_put(assoc->tgtport); }
static bool
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár pali@kernel.org
[ Upstream commit 16cb6b0509b65ac89187e9402e0b7a9ddf1765ef ]
Like in UNICODE mode, SMB1 Session Setup Kerberos Request contains oslm and domain strings.
Extract common code into ascii_oslm_strings() and ascii_domain_string() functions (similar to unicode variants) and use these functions in non-UNICODE code path in sess_auth_kerberos().
Decision if non-UNICODE or UNICODE mode is used is based on the SMBFLG2_UNICODE flag in Flags2 packed field, and not based on the capabilities of server. Fix this check too.
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 | 60 +++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 20 deletions(-)
diff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c index eb70ebf38464b..9d6b1a4704773 100644 --- a/fs/smb/client/sess.c +++ b/fs/smb/client/sess.c @@ -679,6 +679,22 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp) *pbcc_area = bcc_ptr; }
+static void +ascii_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp) +{ + char *bcc_ptr = *pbcc_area; + + strcpy(bcc_ptr, "Linux version "); + bcc_ptr += strlen("Linux version "); + strcpy(bcc_ptr, init_utsname()->release); + bcc_ptr += strlen(init_utsname()->release) + 1; + + strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); + bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; + + *pbcc_area = bcc_ptr; +} + static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses, const struct nls_table *nls_cp) { @@ -703,6 +719,25 @@ static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses, *pbcc_area = bcc_ptr; }
+static void ascii_domain_string(char **pbcc_area, struct cifs_ses *ses, + const struct nls_table *nls_cp) +{ + char *bcc_ptr = *pbcc_area; + int len; + + /* copy domain */ + if (ses->domainName != NULL) { + len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN); + if (WARN_ON_ONCE(len < 0)) + len = CIFS_MAX_DOMAINNAME_LEN - 1; + bcc_ptr += len; + } /* else we send a null domain name so server will default to its own domain */ + *bcc_ptr = 0; + bcc_ptr++; + + *pbcc_area = bcc_ptr; +} + static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses, const struct nls_table *nls_cp) { @@ -748,25 +783,10 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses, *bcc_ptr = 0; bcc_ptr++; /* account for null termination */
- /* copy domain */ - if (ses->domainName != NULL) { - len = strscpy(bcc_ptr, ses->domainName, CIFS_MAX_DOMAINNAME_LEN); - if (WARN_ON_ONCE(len < 0)) - len = CIFS_MAX_DOMAINNAME_LEN - 1; - bcc_ptr += len; - } /* else we send a null domain name so server will default to its own domain */ - *bcc_ptr = 0; - bcc_ptr++; - /* BB check for overflow here */
- strcpy(bcc_ptr, "Linux version "); - bcc_ptr += strlen("Linux version "); - strcpy(bcc_ptr, init_utsname()->release); - bcc_ptr += strlen(init_utsname()->release) + 1; - - strcpy(bcc_ptr, CIFS_NETWORK_OPSYS); - bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1; + ascii_domain_string(&bcc_ptr, ses, nls_cp); + ascii_oslm_strings(&bcc_ptr, nls_cp);
*pbcc_area = bcc_ptr; } @@ -1569,7 +1589,7 @@ sess_auth_kerberos(struct sess_data *sess_data) sess_data->iov[1].iov_len = msg->secblob_len; pSMB->req.SecurityBlobLength = cpu_to_le16(sess_data->iov[1].iov_len);
- if (ses->capabilities & CAP_UNICODE) { + 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; @@ -1578,8 +1598,8 @@ sess_auth_kerberos(struct sess_data *sess_data) unicode_oslm_strings(&bcc_ptr, sess_data->nls_cp); unicode_domain_string(&bcc_ptr, ses, sess_data->nls_cp); } else { - /* BB: is this right? */ - ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp); + ascii_oslm_strings(&bcc_ptr, sess_data->nls_cp); + ascii_domain_string(&bcc_ptr, ses, sess_data->nls_cp); }
sess_data->iov[2].iov_len = (long) bcc_ptr -
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior bigeasy@linutronix.de
[ Upstream commit 92e250c624ea37fde64bfd624fd2556f0d846f18 ]
tick_freeze() acquires a raw spinlock (tick_freeze_lock). Later in the callchain (timekeeping_suspend() -> mc146818_avoid_UIP()) the RTC driver acquires a spinlock which becomes a sleeping lock on PREEMPT_RT. Lockdep complains about this lock nesting.
Add a lockdep override for this special case and a comment explaining why it is okay.
Reported-by: Borislav Petkov bp@alien8.de Reported-by: Chris Bainbridge chris.bainbridge@gmail.com Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de Signed-off-by: Thomas Gleixner tglx@linutronix.de Acked-by: Peter Zijlstra (Intel) peterz@infradead.org Link: https://lore.kernel.org/all/20250404133429.pnAzf-eF@linutronix.de Closes: https://lore.kernel.org/all/20250330113202.GAZ-krsjAnurOlTcp-@fat_crate.loca... Closes: https://lore.kernel.org/all/CAP-bSRZ0CWyZZsMtx046YV8L28LhY0fson2g4EqcwRAVN1J... Signed-off-by: Sasha Levin sashal@kernel.org --- kernel/time/tick-common.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c index a47bcf71defcf..9a3859443c042 100644 --- a/kernel/time/tick-common.c +++ b/kernel/time/tick-common.c @@ -509,6 +509,7 @@ void tick_resume(void)
#ifdef CONFIG_SUSPEND static DEFINE_RAW_SPINLOCK(tick_freeze_lock); +static DEFINE_WAIT_OVERRIDE_MAP(tick_freeze_map, LD_WAIT_SLEEP); static unsigned int tick_freeze_depth;
/** @@ -528,9 +529,22 @@ void tick_freeze(void) if (tick_freeze_depth == num_online_cpus()) { trace_suspend_resume(TPS("timekeeping_freeze"), smp_processor_id(), true); + /* + * All other CPUs have their interrupts disabled and are + * suspended to idle. Other tasks have been frozen so there + * is no scheduling happening. This means that there is no + * concurrency in the system at this point. Therefore it is + * okay to acquire a sleeping lock on PREEMPT_RT, such as a + * spinlock, because the lock cannot be held by other CPUs + * or threads and acquiring it cannot block. + * + * Inform lockdep about the situation. + */ + lock_map_acquire_try(&tick_freeze_map); system_state = SYSTEM_SUSPEND; sched_clock_suspend(); timekeeping_suspend(); + lock_map_release(&tick_freeze_map); } else { tick_suspend_local(); } @@ -552,8 +566,16 @@ void tick_unfreeze(void) raw_spin_lock(&tick_freeze_lock);
if (tick_freeze_depth == num_online_cpus()) { + /* + * Similar to tick_freeze(). On resumption the first CPU may + * acquire uncontended sleeping locks while other CPUs block on + * tick_freeze_lock. + */ + lock_map_acquire_try(&tick_freeze_map); timekeeping_resume(); sched_clock_resume(); + lock_map_release(&tick_freeze_map); + system_state = SYSTEM_RUNNING; trace_suspend_resume(TPS("timekeeping_freeze"), smp_processor_id(), false);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pali Rohár pali@kernel.org
[ Upstream commit ef86ab131d9127dfbfa8f06e12441d05fdfb090b ]
When reparse point in SMB1 query_path_info() callback was detected then query also for EA $LXDEV. In this EA are stored device major and minor numbers used by WSL CHR and BLK reparse points. Without major and minor numbers, stat() syscall does not work for char and block devices.
Similar code is already in SMB2+ query_path_info() callback function.
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/smb1ops.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
diff --git a/fs/smb/client/smb1ops.c b/fs/smb/client/smb1ops.c index d6e2fb669c401..808970e4a7142 100644 --- a/fs/smb/client/smb1ops.c +++ b/fs/smb/client/smb1ops.c @@ -573,6 +573,42 @@ static int cifs_query_path_info(const unsigned int xid, data->reparse_point = le32_to_cpu(fi.Attributes) & ATTR_REPARSE; }
+#ifdef CONFIG_CIFS_XATTR + /* + * For WSL CHR and BLK reparse points it is required to fetch + * EA $LXDEV which contains major and minor device numbers. + */ + if (!rc && data->reparse_point) { + struct smb2_file_full_ea_info *ea; + + ea = (struct smb2_file_full_ea_info *)data->wsl.eas; + rc = CIFSSMBQAllEAs(xid, tcon, full_path, SMB2_WSL_XATTR_DEV, + &ea->ea_data[SMB2_WSL_XATTR_NAME_LEN + 1], + SMB2_WSL_XATTR_DEV_SIZE, cifs_sb); + if (rc == SMB2_WSL_XATTR_DEV_SIZE) { + ea->next_entry_offset = cpu_to_le32(0); + ea->flags = 0; + ea->ea_name_length = SMB2_WSL_XATTR_NAME_LEN; + ea->ea_value_length = cpu_to_le16(SMB2_WSL_XATTR_DEV_SIZE); + memcpy(&ea->ea_data[0], SMB2_WSL_XATTR_DEV, SMB2_WSL_XATTR_NAME_LEN + 1); + data->wsl.eas_len = sizeof(*ea) + SMB2_WSL_XATTR_NAME_LEN + 1 + + SMB2_WSL_XATTR_DEV_SIZE; + rc = 0; + } else if (rc >= 0) { + /* It is an error if EA $LXDEV has wrong size. */ + rc = -EINVAL; + } else { + /* + * In all other cases ignore error if fetching + * of EA $LXDEV failed. It is needed only for + * WSL CHR and BLK reparse points and wsl_to_fattr() + * handle the case when EA is missing. + */ + rc = 0; + } + } +#endif + return rc; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Murphy robin.murphy@arm.com
[ Upstream commit 280e5a30100578106a4305ce0118e0aa9b866f12 ]
If iommu_device_register() encounters an error, it can end up tearing down already-configured groups and default domains, however this currently still leaves devices hooked up to iommu-dma (and even historically the behaviour in this area was at best inconsistent across architectures/drivers...) Although in the case that an IOMMU is present whose driver has failed to probe, users cannot necessarily expect DMA to work anyway, it's still arguable that we should do our best to put things back as if the IOMMU driver was never there at all, and certainly the potential for crashing in iommu-dma itself is undesirable. Make sure we clean up the dev->dma_iommu flag along with everything else.
Reported-by: Chen-Yu Tsai wenst@chromium.org Signed-off-by: Robin Murphy robin.murphy@arm.com Closes: https://lore.kernel.org/all/CAGXv+5HJpTYmQ2h-GD7GjyeYT7bL9EBCvu0mz5LgpzJZtzf... Tested-by: Chen-Yu Tsai wenst@chromium.org Reviewed-by: Lu Baolu baolu.lu@linux.intel.com Link: https://lore.kernel.org/r/e788aa927f6d827dd4ea1ed608fada79f2bab030.174428422... Signed-off-by: Joerg Roedel jroedel@suse.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/iommu/iommu.c | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index e3df1f06afbeb..1efe7cddb4fe3 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -508,6 +508,9 @@ static void iommu_deinit_device(struct device *dev) dev->iommu_group = NULL; module_put(ops->owner); dev_iommu_free(dev); +#ifdef CONFIG_IOMMU_DMA + dev->dma_iommu = false; +#endif }
DEFINE_MUTEX(iommu_probe_device_lock);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ojaswin Mujoo ojaswin@linux.ibm.com
[ Upstream commit ccad447a3d331a239477c281533bacb585b54a98 ]
Block validity checks need to be skipped in case they are called for journal blocks since they are part of system's protected zone.
Currently, this is done by checking inode->ino against sbi->s_es->s_journal_inum, which is a direct read from the ext4 sb buffer head. If someone modifies this underneath us then the s_journal_inum field might get corrupted. To prevent against this, change the check to directly compare the inode with journal->j_inode.
**Slight change in behavior**: During journal init path, check_block_validity etc might be called for journal inode when sbi->s_journal is not set yet. In this case we now proceed with ext4_inode_block_valid() instead of returning early. Since systems zones have not been set yet, it is okay to proceed so we can perform basic checks on the blocks.
Suggested-by: Baokun Li libaokun1@huawei.com Reviewed-by: Baokun Li libaokun1@huawei.com Reviewed-by: Jan Kara jack@suse.cz Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Ojaswin Mujoo ojaswin@linux.ibm.com Link: https://patch.msgid.link/0c06bc9ebfcd6ccfed84a36e79147bf45ff5adc1.1743142920... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Sasha Levin sashal@kernel.org --- fs/ext4/block_validity.c | 5 ++--- fs/ext4/inode.c | 7 ++++--- 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/fs/ext4/block_validity.c b/fs/ext4/block_validity.c index 87ee3a17bd29c..e8c5525afc67a 100644 --- a/fs/ext4/block_validity.c +++ b/fs/ext4/block_validity.c @@ -351,10 +351,9 @@ int ext4_check_blockref(const char *function, unsigned int line, { __le32 *bref = p; unsigned int blk; + journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
- if (ext4_has_feature_journal(inode->i_sb) && - (inode->i_ino == - le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) + if (journal && inode == journal->j_inode) return 0;
while (bref < p+max) { diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 4108b7d1696ff..74c5e2a381a6b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -383,10 +383,11 @@ static int __check_block_validity(struct inode *inode, const char *func, unsigned int line, struct ext4_map_blocks *map) { - if (ext4_has_feature_journal(inode->i_sb) && - (inode->i_ino == - le32_to_cpu(EXT4_SB(inode->i_sb)->s_es->s_journal_inum))) + journal_t *journal = EXT4_SB(inode->i_sb)->s_journal; + + if (journal && inode == journal->j_inode) return 0; + if (!ext4_inode_block_valid(inode, map->m_pblk, map->m_len)) { ext4_error_inode(inode, func, line, map->m_pblk, "lblock %lu mapped to illegal pblock %llu "
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xingui Yang yangxingui@huawei.com
[ Upstream commit daff37f00c7506ca322ccfce95d342022f06ec58 ]
The hw port ID of phy may change when inserting disks in batches, causing the port ID in hisi_sas_port and itct to be inconsistent with the hardware, resulting in I/O errors. The solution is to set the device state to gone to intercept I/O sent to the device, and then execute linkreset to discard and find the disk to re-update its information.
Signed-off-by: Xingui Yang yangxingui@huawei.com Link: https://lore.kernel.org/r/20250312095135.3048379-3-yangxingui@huawei.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/hisi_sas/hisi_sas_main.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 3596414d970b2..7a484ad0f9abe 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -935,8 +935,28 @@ static void hisi_sas_phyup_work_common(struct work_struct *work, container_of(work, typeof(*phy), works[event]); struct hisi_hba *hisi_hba = phy->hisi_hba; struct asd_sas_phy *sas_phy = &phy->sas_phy; + struct asd_sas_port *sas_port = sas_phy->port; + struct hisi_sas_port *port = phy->port; + struct device *dev = hisi_hba->dev; + struct domain_device *port_dev; int phy_no = sas_phy->id;
+ if (!test_bit(HISI_SAS_RESETTING_BIT, &hisi_hba->flags) && + sas_port && port && (port->id != phy->port_id)) { + dev_info(dev, "phy%d's hw port id changed from %d to %llu\n", + phy_no, port->id, phy->port_id); + port_dev = sas_port->port_dev; + if (port_dev && !dev_is_expander(port_dev->dev_type)) { + /* + * Set the device state to gone to block + * sending IO to the device. + */ + set_bit(SAS_DEV_GONE, &port_dev->state); + hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); + return; + } + } + phy->wait_phyup_cnt = 0; if (phy->identify.target_port_protocols == SAS_PROTOCOL_SSP) hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Griffin peter.griffin@linaro.org
[ Upstream commit 3d101165e72316775947d71321d97194f03dfef3 ]
Ensure clocks are enabled before configuring unipro. Additionally move the pre_link() hook before the exynos_ufs_phy_init() calls. This means the register write sequence more closely resembles the ordering of the downstream driver.
Signed-off-by: Peter Griffin peter.griffin@linaro.org Link: https://lore.kernel.org/r/20250319-exynos-ufs-stability-fixes-v2-1-96722cc2b... 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/host/ufs-exynos.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index 5ea3f9beb1bd9..e77b3c63e6981 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -1060,9 +1060,14 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba) exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4); exynos_ufs_set_unipro_pclk_div(ufs);
+ exynos_ufs_setup_clocks(hba, true, PRE_CHANGE); + /* unipro */ exynos_ufs_config_unipro(ufs);
+ if (ufs->drv_data->pre_link) + ufs->drv_data->pre_link(ufs); + /* m-phy */ exynos_ufs_phy_init(ufs); if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONFIG_PHY_ATTR)) { @@ -1070,11 +1075,6 @@ static int exynos_ufs_pre_link(struct ufs_hba *hba) exynos_ufs_config_phy_cap_attr(ufs); }
- exynos_ufs_setup_clocks(hba, true, PRE_CHANGE); - - if (ufs->drv_data->pre_link) - ufs->drv_data->pre_link(ufs); - return 0; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Griffin peter.griffin@linaro.org
[ Upstream commit deac9ad496ec17e1ec06848964ecc635bdaca703 ]
PRDT_PREFETCH_ENABLE[31] bit should be set when desctype field of fmpsecurity0 register is type2 (double file encryption) or type3 (support for file and disk encryption). Setting this bit enables PRDT pre-fetching on both TXPRDT and RXPRDT.
Signed-off-by: Peter Griffin peter.griffin@linaro.org Link: https://lore.kernel.org/r/20250319-exynos-ufs-stability-fixes-v2-5-96722cc2b... 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/host/ufs-exynos.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index e77b3c63e6981..ac71b878d872f 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -34,7 +34,7 @@ * Exynos's Vendor specific registers for UFSHCI */ #define HCI_TXPRDT_ENTRY_SIZE 0x00 -#define PRDT_PREFECT_EN BIT(31) +#define PRDT_PREFETCH_EN BIT(31) #define HCI_RXPRDT_ENTRY_SIZE 0x04 #define HCI_1US_TO_CNT_VAL 0x0C #define CNT_VAL_1US_MASK 0x3FF @@ -1098,12 +1098,17 @@ static int exynos_ufs_post_link(struct ufs_hba *hba) struct exynos_ufs *ufs = ufshcd_get_variant(hba); struct phy *generic_phy = ufs->phy; struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr; + u32 val = ilog2(DATA_UNIT_SIZE);
exynos_ufs_establish_connt(ufs); exynos_ufs_fit_aggr_timeout(ufs);
hci_writel(ufs, 0xa, HCI_DATA_REORDER); - hci_writel(ufs, ilog2(DATA_UNIT_SIZE), HCI_TXPRDT_ENTRY_SIZE); + + if (hba->caps & UFSHCD_CAP_CRYPTO) + val |= PRDT_PREFETCH_EN; + hci_writel(ufs, val, HCI_TXPRDT_ENTRY_SIZE); + hci_writel(ufs, ilog2(DATA_UNIT_SIZE), HCI_RXPRDT_ENTRY_SIZE); hci_writel(ufs, (1 << hba->nutrs) - 1, HCI_UTRL_NEXUS_TYPE); hci_writel(ufs, (1 << hba->nutmrs) - 1, HCI_UTMRL_NEXUS_TYPE);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Griffin peter.griffin@linaro.org
[ Upstream commit 67e4085015c33bf2fb552af1f171c58b81ef0616 ]
ufshcd_pltfrm_remove() calls ufshcd_remove(hba) which in turn calls ufshcd_hba_exit().
By moving the phy_power_off() and phy_exit() calls to the newly created .exit callback they get called by ufshcd_variant_hba_exit() before ufshcd_hba_exit() turns off the regulators. This is also similar flow to the ufs-qcom driver.
Signed-off-by: Peter Griffin peter.griffin@linaro.org Link: https://lore.kernel.org/r/20250319-exynos-ufs-stability-fixes-v2-6-96722cc2b... 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/host/ufs-exynos.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index ac71b878d872f..b9fbc78be74ee 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -1522,6 +1522,14 @@ static int exynos_ufs_init(struct ufs_hba *hba) return ret; }
+static void exynos_ufs_exit(struct ufs_hba *hba) +{ + struct exynos_ufs *ufs = ufshcd_get_variant(hba); + + phy_power_off(ufs->phy); + phy_exit(ufs->phy); +} + static int exynos_ufs_host_reset(struct ufs_hba *hba) { struct exynos_ufs *ufs = ufshcd_get_variant(hba); @@ -1977,6 +1985,7 @@ static int gs101_ufs_pre_pwr_change(struct exynos_ufs *ufs, static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = { .name = "exynos_ufs", .init = exynos_ufs_init, + .exit = exynos_ufs_exit, .hce_enable_notify = exynos_ufs_hce_enable_notify, .link_startup_notify = exynos_ufs_link_startup_notify, .pwr_change_notify = exynos_ufs_pwr_change_notify, @@ -2015,13 +2024,7 @@ static int exynos_ufs_probe(struct platform_device *pdev)
static void exynos_ufs_remove(struct platform_device *pdev) { - struct ufs_hba *hba = platform_get_drvdata(pdev); - struct exynos_ufs *ufs = ufshcd_get_variant(hba); - ufshcd_pltfrm_remove(pdev); - - phy_power_off(ufs->phy); - phy_exit(ufs->phy); }
static struct exynos_ufs_uic_attr exynos7_uic_attr = {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Griffin peter.griffin@linaro.org
[ Upstream commit cd4c0025069f16fc666c6ffc56c49c9b1154841f ]
GPIO_OUT[0] is connected to the reset pin of embedded UFS device. Before powering off the phy assert the reset signal.
This is added as a gs101 specific suspend hook so as not to have any unintended consequences for other SoCs supported by this driver.
Signed-off-by: Peter Griffin peter.griffin@linaro.org Link: https://lore.kernel.org/r/20250319-exynos-ufs-stability-fixes-v2-7-96722cc2b... 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/host/ufs-exynos.c | 10 ++++++++++ drivers/ufs/host/ufs-exynos.h | 1 + 2 files changed, 11 insertions(+)
diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index b9fbc78be74ee..2436b9454480b 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -1700,6 +1700,12 @@ static void exynos_ufs_hibern8_notify(struct ufs_hba *hba, } }
+static int gs101_ufs_suspend(struct exynos_ufs *ufs) +{ + hci_writel(ufs, 0 << 0, HCI_GPIO_OUT); + return 0; +} + static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, enum ufs_notify_change_status status) { @@ -1708,6 +1714,9 @@ static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, if (status == PRE_CHANGE) return 0;
+ if (ufs->drv_data->suspend) + ufs->drv_data->suspend(ufs); + if (!ufshcd_is_link_active(hba)) phy_power_off(ufs->phy);
@@ -2170,6 +2179,7 @@ static const struct exynos_ufs_drv_data gs101_ufs_drvs = { .pre_link = gs101_ufs_pre_link, .post_link = gs101_ufs_post_link, .pre_pwr_change = gs101_ufs_pre_pwr_change, + .suspend = gs101_ufs_suspend, };
static const struct of_device_id exynos_ufs_of_match[] = { diff --git a/drivers/ufs/host/ufs-exynos.h b/drivers/ufs/host/ufs-exynos.h index d0b3df221503c..3c6fe5132190a 100644 --- a/drivers/ufs/host/ufs-exynos.h +++ b/drivers/ufs/host/ufs-exynos.h @@ -192,6 +192,7 @@ struct exynos_ufs_drv_data { struct ufs_pa_layer_attr *pwr); int (*pre_hce_enable)(struct exynos_ufs *ufs); int (*post_hce_enable)(struct exynos_ufs *ufs); + int (*suspend)(struct exynos_ufs *ufs); };
struct ufs_phy_time_cfg {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Pylypiv ipylypiv@google.com
[ Upstream commit f7b705c238d1483f0a766e2b20010f176e5c0fb7 ]
When a fatal error occurs, a phy down event may not be received to set phy->phy_attached to zero.
Signed-off-by: Igor Pylypiv ipylypiv@google.com Signed-off-by: Salomon Dushimirimana salomondush@google.com Link: https://lore.kernel.org/r/20250319230305.3172920-1-salomondush@google.com Signed-off-by: Martin K. Petersen martin.petersen@oracle.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/scsi/pm8001/pm8001_sas.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/drivers/scsi/pm8001/pm8001_sas.c b/drivers/scsi/pm8001/pm8001_sas.c index 183ce00aa671e..f7067878b34f3 100644 --- a/drivers/scsi/pm8001/pm8001_sas.c +++ b/drivers/scsi/pm8001/pm8001_sas.c @@ -766,6 +766,7 @@ static void pm8001_dev_gone_notify(struct domain_device *dev) spin_lock_irqsave(&pm8001_ha->lock, flags); } PM8001_CHIP_DISP->dereg_dev_req(pm8001_ha, device_id); + pm8001_ha->phy[pm8001_dev->attached_phy].phy_attached = 0; pm8001_free_dev(pm8001_dev); } else { pm8001_dbg(pm8001_ha, DISC, "Found dev has gone.\n");
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengjiu Wang shengjiu.wang@nxp.com
[ Upstream commit ef5c23ae9ab380fa756f257411024a9b4518d1b9 ]
With audio graph card, original cpu dai is changed to codec device in backend, so if cpu dai is dummy device in backend, get the codec dai device, which is the real hardware device connected.
The specific case is ASRC->SAI->AMIX->CODEC.
Signed-off-by: Shengjiu Wang shengjiu.wang@nxp.com Link: https://patch.msgid.link/20250319033504.2898605-1-shengjiu.wang@nxp.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/fsl/fsl_asrc_dma.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c index f501f47242fb0..1bba48318e2dd 100644 --- a/sound/soc/fsl/fsl_asrc_dma.c +++ b/sound/soc/fsl/fsl_asrc_dma.c @@ -156,11 +156,24 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component *component, for_each_dpcm_be(rtd, stream, dpcm) { struct snd_soc_pcm_runtime *be = dpcm->be; struct snd_pcm_substream *substream_be; - struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(be, 0); + struct snd_soc_dai *dai_cpu = snd_soc_rtd_to_cpu(be, 0); + struct snd_soc_dai *dai_codec = snd_soc_rtd_to_codec(be, 0); + struct snd_soc_dai *dai;
if (dpcm->fe != rtd) continue;
+ /* + * With audio graph card, original cpu dai is changed to codec + * device in backend, so if cpu dai is dummy device in backend, + * get the codec dai device, which is the real hardware device + * connected. + */ + if (!snd_soc_dai_is_dummy(dai_cpu)) + dai = dai_cpu; + else + dai = dai_codec; + substream_be = snd_soc_dpcm_get_substream(be, stream); dma_params_be = snd_soc_dai_get_dma_data(dai, substream_be); dev_be = dai->dev;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weidong Wang wangweidong.a@awinic.com
[ Upstream commit 6bbb2b1286f437b45ccf4828a537429153cd1096 ]
Add of_match_table for aw88081 driver to make matching between dts and driver more flexible
Signed-off-by: Weidong Wang wangweidong.a@awinic.com Link: https://patch.msgid.link/20250410024953.26565-1-wangweidong.a@awinic.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- sound/soc/codecs/aw88081.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/sound/soc/codecs/aw88081.c b/sound/soc/codecs/aw88081.c index ad16ab6812cd3..3dd8428f08cce 100644 --- a/sound/soc/codecs/aw88081.c +++ b/sound/soc/codecs/aw88081.c @@ -1295,9 +1295,19 @@ static int aw88081_i2c_probe(struct i2c_client *i2c) aw88081_dai, ARRAY_SIZE(aw88081_dai)); }
+#if defined(CONFIG_OF) +static const struct of_device_id aw88081_of_match[] = { + { .compatible = "awinic,aw88081" }, + { .compatible = "awinic,aw88083" }, + { } +}; +MODULE_DEVICE_TABLE(of, aw88081_of_match); +#endif + static struct i2c_driver aw88081_i2c_driver = { .driver = { .name = AW88081_I2C_NAME, + .of_match_table = of_match_ptr(aw88081_of_match), }, .probe = aw88081_i2c_probe, .id_table = aw88081_i2c_id,
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernando Fernandez Mancera ffmancera@riseup.net
[ Upstream commit 3940f5349b476197fb079c5aa19c9a988de64efb ]
There's a lockdep false positive warning related to i8253_lock:
WARNING: HARDIRQ-safe -> HARDIRQ-unsafe lock order detected ... systemd-sleep/3324 [HC0[0]:SC0[0]:HE0:SE1] is trying to acquire: ffffffffb2c23398 (i8253_lock){+.+.}-{2:2}, at: pcspkr_event+0x3f/0xe0 [pcspkr]
... ... which became HARDIRQ-irq-unsafe at: ... lock_acquire+0xd0/0x2f0 _raw_spin_lock+0x30/0x40 clockevent_i8253_disable+0x1c/0x60 pit_timer_init+0x25/0x50 hpet_time_init+0x46/0x50 x86_late_time_init+0x1b/0x40 start_kernel+0x962/0xa00 x86_64_start_reservations+0x24/0x30 x86_64_start_kernel+0xed/0xf0 common_startup_64+0x13e/0x141 ...
Lockdep complains due pit_timer_init() using the lock in an IRQ-unsafe fashion, but it's a false positive, because there is no deadlock possible at that point due to init ordering: at the point where pit_timer_init() is called there is no other possible usage of i8253_lock because the system is still in the very early boot stage with no interrupts.
But in any case, pit_timer_init() should disable interrupts before calling clockevent_i8253_disable() out of general principle, and to keep lockdep working even in this scenario.
Use scoped_guard() for that, as suggested by Thomas Gleixner.
[ mingo: Cleaned up the changelog. ]
Suggested-by: Thomas Gleixner tglx@linutronix.de Signed-off-by: Fernando Fernandez Mancera ffmancera@riseup.net Signed-off-by: Ingo Molnar mingo@kernel.org Reviewed-by: Thomas Gleixner tglx@linutronix.de Link: https://lore.kernel.org/r/Z-uwd4Bnn7FcCShX@gmail.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/kernel/i8253.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/i8253.c b/arch/x86/kernel/i8253.c index 80e262bb627fe..cb9852ad60989 100644 --- a/arch/x86/kernel/i8253.c +++ b/arch/x86/kernel/i8253.c @@ -46,7 +46,8 @@ bool __init pit_timer_init(void) * VMMs otherwise steal CPU time just to pointlessly waggle * the (masked) IRQ. */ - clockevent_i8253_disable(); + scoped_guard(irq) + clockevent_i8253_disable(); return false; } clockevent_i8253_init(true);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 3343b086c7035222c24956780ea4423655cad6d2 ]
The Vexia EDU ATLA 10 tablet comes in 2 different versions with significantly different mainboards. The only outward difference is that the charging barrel on one is marked 5V and the other is marked 9V.
Both need to be handled by the x86-android-tablets code. Add 9v to the symbols for the existing support for the 9V Vexia EDU ATLA 10 tablet symbols to prepare for adding support for the 5V version.
All this patch does is s/vexia_edu_atla10_info/vexia_edu_atla10_9v_info/.
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20250407092017.273124-1-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../platform/x86/x86-android-tablets/dmi.c | 2 +- .../platform/x86/x86-android-tablets/other.c | 64 +++++++++---------- .../x86-android-tablets/x86-android-tablets.h | 2 +- 3 files changed, 34 insertions(+), 34 deletions(-)
diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c index 3e5fa3b6e2fdf..e43d482b17a35 100644 --- a/drivers/platform/x86/x86-android-tablets/dmi.c +++ b/drivers/platform/x86/x86-android-tablets/dmi.c @@ -187,7 +187,7 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = { /* Above strings are too generic, also match on BIOS date */ DMI_MATCH(DMI_BIOS_DATE, "08/25/2014"), }, - .driver_data = (void *)&vexia_edu_atla10_info, + .driver_data = (void *)&vexia_edu_atla10_9v_info, }, { /* Whitelabel (sold as various brands) TM800A550L */ diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index 1d93d9edb23f4..74dcac8d19d72 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -599,62 +599,62 @@ const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { };
/* - * Vexia EDU ATLA 10 tablet, Android 4.2 / 4.4 + Guadalinex Ubuntu tablet + * Vexia EDU ATLA 10 tablet 9V, Android 4.2 + Guadalinex Ubuntu tablet * distributed to schools in the Spanish Andalucía region. */ static const char * const crystal_cove_pwrsrc_psy[] = { "crystal_cove_pwrsrc" };
-static const struct property_entry vexia_edu_atla10_ulpmc_props[] = { +static const struct property_entry vexia_edu_atla10_9v_ulpmc_props[] = { PROPERTY_ENTRY_STRING_ARRAY("supplied-from", crystal_cove_pwrsrc_psy), { } };
-static const struct software_node vexia_edu_atla10_ulpmc_node = { - .properties = vexia_edu_atla10_ulpmc_props, +static const struct software_node vexia_edu_atla10_9v_ulpmc_node = { + .properties = vexia_edu_atla10_9v_ulpmc_props, };
-static const char * const vexia_edu_atla10_accel_mount_matrix[] = { +static const char * const vexia_edu_atla10_9v_accel_mount_matrix[] = { "0", "-1", "0", "1", "0", "0", "0", "0", "1" };
-static const struct property_entry vexia_edu_atla10_accel_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", vexia_edu_atla10_accel_mount_matrix), +static const struct property_entry vexia_edu_atla10_9v_accel_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", vexia_edu_atla10_9v_accel_mount_matrix), { } };
-static const struct software_node vexia_edu_atla10_accel_node = { - .properties = vexia_edu_atla10_accel_props, +static const struct software_node vexia_edu_atla10_9v_accel_node = { + .properties = vexia_edu_atla10_9v_accel_props, };
-static const struct property_entry vexia_edu_atla10_touchscreen_props[] = { +static const struct property_entry vexia_edu_atla10_9v_touchscreen_props[] = { PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000), PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120), { } };
-static const struct software_node vexia_edu_atla10_touchscreen_node = { - .properties = vexia_edu_atla10_touchscreen_props, +static const struct software_node vexia_edu_atla10_9v_touchscreen_node = { + .properties = vexia_edu_atla10_9v_touchscreen_props, };
-static const struct property_entry vexia_edu_atla10_pmic_props[] = { +static const struct property_entry vexia_edu_atla10_9v_pmic_props[] = { PROPERTY_ENTRY_BOOL("linux,register-pwrsrc-power_supply"), { } };
-static const struct software_node vexia_edu_atla10_pmic_node = { - .properties = vexia_edu_atla10_pmic_props, +static const struct software_node vexia_edu_atla10_9v_pmic_node = { + .properties = vexia_edu_atla10_9v_pmic_props, };
-static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initconst = { +static const struct x86_i2c_client_info vexia_edu_atla10_9v_i2c_clients[] __initconst = { { /* I2C attached embedded controller, used to access fuel-gauge */ .board_info = { .type = "vexia_atla10_ec", .addr = 0x76, .dev_name = "ulpmc", - .swnode = &vexia_edu_atla10_ulpmc_node, + .swnode = &vexia_edu_atla10_9v_ulpmc_node, }, .adapter_path = "0000:00:18.1", }, { @@ -679,7 +679,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon .type = "kxtj21009", .addr = 0x0f, .dev_name = "kxtj21009", - .swnode = &vexia_edu_atla10_accel_node, + .swnode = &vexia_edu_atla10_9v_accel_node, }, .adapter_path = "0000:00:18.5", }, { @@ -688,7 +688,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon .type = "hid-over-i2c", .addr = 0x38, .dev_name = "FTSC1000", - .swnode = &vexia_edu_atla10_touchscreen_node, + .swnode = &vexia_edu_atla10_9v_touchscreen_node, }, .adapter_path = "0000:00:18.6", .irq_data = { @@ -703,7 +703,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon .type = "intel_soc_pmic_crc", .addr = 0x6e, .dev_name = "intel_soc_pmic_crc", - .swnode = &vexia_edu_atla10_pmic_node, + .swnode = &vexia_edu_atla10_9v_pmic_node, }, .adapter_path = "0000:00:18.7", .irq_data = { @@ -715,7 +715,7 @@ static const struct x86_i2c_client_info vexia_edu_atla10_i2c_clients[] __initcon } };
-static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = { +static const struct x86_serdev_info vexia_edu_atla10_9v_serdevs[] __initconst = { { .ctrl.pci.devfn = PCI_DEVFN(0x1e, 3), .ctrl_devname = "serial0", @@ -723,7 +723,7 @@ static const struct x86_serdev_info vexia_edu_atla10_serdevs[] __initconst = { }, };
-static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = { +static struct gpiod_lookup_table vexia_edu_atla10_9v_ft5416_gpios = { .dev_id = "i2c-FTSC1000", .table = { GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_LOW), @@ -731,12 +731,12 @@ static struct gpiod_lookup_table vexia_edu_atla10_ft5416_gpios = { }, };
-static struct gpiod_lookup_table * const vexia_edu_atla10_gpios[] = { - &vexia_edu_atla10_ft5416_gpios, +static struct gpiod_lookup_table * const vexia_edu_atla10_9v_gpios[] = { + &vexia_edu_atla10_9v_ft5416_gpios, NULL };
-static int __init vexia_edu_atla10_init(struct device *dev) +static int __init vexia_edu_atla10_9v_init(struct device *dev) { struct pci_dev *pdev; int ret; @@ -760,13 +760,13 @@ static int __init vexia_edu_atla10_init(struct device *dev) return 0; }
-const struct x86_dev_info vexia_edu_atla10_info __initconst = { - .i2c_client_info = vexia_edu_atla10_i2c_clients, - .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_i2c_clients), - .serdev_info = vexia_edu_atla10_serdevs, - .serdev_count = ARRAY_SIZE(vexia_edu_atla10_serdevs), - .gpiod_lookup_tables = vexia_edu_atla10_gpios, - .init = vexia_edu_atla10_init, +const struct x86_dev_info vexia_edu_atla10_9v_info __initconst = { + .i2c_client_info = vexia_edu_atla10_9v_i2c_clients, + .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_9v_i2c_clients), + .serdev_info = vexia_edu_atla10_9v_serdevs, + .serdev_count = ARRAY_SIZE(vexia_edu_atla10_9v_serdevs), + .gpiod_lookup_tables = vexia_edu_atla10_9v_gpios, + .init = vexia_edu_atla10_9v_init, .use_pci = true, };
diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h index 63a38a0069bae..2204bbaf2ed5a 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h @@ -127,7 +127,7 @@ extern const struct x86_dev_info nextbook_ares8_info; extern const struct x86_dev_info nextbook_ares8a_info; extern const struct x86_dev_info peaq_c1010_info; extern const struct x86_dev_info whitelabel_tm800a550l_info; -extern const struct x86_dev_info vexia_edu_atla10_info; +extern const struct x86_dev_info vexia_edu_atla10_9v_info; extern const struct x86_dev_info xiaomi_mipad2_info; extern const struct dmi_system_id x86_android_tablet_ids[];
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede hdegoede@redhat.com
[ Upstream commit 59df54c67be3e587e4217bddd793350fbe8f5feb ]
The Vexia EDU ATLA 10 tablet comes in 2 different versions with significantly different mainboards. The only outward difference is that the charging barrel on one is marked 5V and the other is marked 9V.
Both are x86 ACPI tablets which ships with Android x86 as factory OS. with a DSDT which contains a bunch of I2C devices which are not actually there, causing various resource conflicts. Enumeration of these is skipped through the acpi_quirk_skip_i2c_client_enumeration().
Extend the existing support for the 9V version by adding support for manually instantiating the I2C devices which are actually present on the 5V version by adding the necessary device info to the x86-android-tablets module.
Signed-off-by: Hans de Goede hdegoede@redhat.com Link: https://lore.kernel.org/r/20250407092017.273124-2-hdegoede@redhat.com Reviewed-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Ilpo Järvinen ilpo.jarvinen@linux.intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- .../platform/x86/x86-android-tablets/dmi.c | 12 ++++ .../platform/x86/x86-android-tablets/other.c | 60 +++++++++++++++++++ .../x86-android-tablets/x86-android-tablets.h | 1 + 3 files changed, 73 insertions(+)
diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c index e43d482b17a35..278c6d151dc49 100644 --- a/drivers/platform/x86/x86-android-tablets/dmi.c +++ b/drivers/platform/x86/x86-android-tablets/dmi.c @@ -179,6 +179,18 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = { }, .driver_data = (void *)&peaq_c1010_info, }, + { + /* Vexia Edu Atla 10 tablet 5V version */ + .matches = { + /* Having all 3 of these not set is somewhat unique */ + DMI_MATCH(DMI_SYS_VENDOR, "To be filled by O.E.M."), + DMI_MATCH(DMI_PRODUCT_NAME, "To be filled by O.E.M."), + DMI_MATCH(DMI_BOARD_NAME, "To be filled by O.E.M."), + /* Above strings are too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "05/14/2015"), + }, + .driver_data = (void *)&vexia_edu_atla10_5v_info, + }, { /* Vexia Edu Atla 10 tablet 9V version */ .matches = { diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index 74dcac8d19d72..f7bd9f863c85e 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -598,6 +598,66 @@ const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { .gpiod_lookup_tables = whitelabel_tm800a550l_gpios, };
+/* + * Vexia EDU ATLA 10 tablet 5V, Android 4.4 + Guadalinex Ubuntu tablet + * distributed to schools in the Spanish Andalucía region. + */ +static const struct property_entry vexia_edu_atla10_5v_touchscreen_props[] = { + PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000), + PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120), + { } +}; + +static const struct software_node vexia_edu_atla10_5v_touchscreen_node = { + .properties = vexia_edu_atla10_5v_touchscreen_props, +}; + +static const struct x86_i2c_client_info vexia_edu_atla10_5v_i2c_clients[] __initconst = { + { + /* kxcjk1013 accelerometer */ + .board_info = { + .type = "kxcjk1013", + .addr = 0x0f, + .dev_name = "kxcjk1013", + }, + .adapter_path = "\_SB_.I2C3", + }, { + /* touchscreen controller */ + .board_info = { + .type = "hid-over-i2c", + .addr = 0x38, + .dev_name = "FTSC1000", + .swnode = &vexia_edu_atla10_5v_touchscreen_node, + }, + .adapter_path = "\_SB_.I2C4", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_APIC, + .index = 0x44, + .trigger = ACPI_LEVEL_SENSITIVE, + .polarity = ACPI_ACTIVE_HIGH, + }, + } +}; + +static struct gpiod_lookup_table vexia_edu_atla10_5v_ft5416_gpios = { + .dev_id = "i2c-FTSC1000", + .table = { + GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW), + { } + }, +}; + +static struct gpiod_lookup_table * const vexia_edu_atla10_5v_gpios[] = { + &vexia_edu_atla10_5v_ft5416_gpios, + NULL +}; + +const struct x86_dev_info vexia_edu_atla10_5v_info __initconst = { + .i2c_client_info = vexia_edu_atla10_5v_i2c_clients, + .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_5v_i2c_clients), + .gpiod_lookup_tables = vexia_edu_atla10_5v_gpios, +}; + /* * Vexia EDU ATLA 10 tablet 9V, Android 4.2 + Guadalinex Ubuntu tablet * distributed to schools in the Spanish Andalucía region. diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h index 2204bbaf2ed5a..dcf8d49e3b5f4 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h @@ -127,6 +127,7 @@ extern const struct x86_dev_info nextbook_ares8_info; extern const struct x86_dev_info nextbook_ares8a_info; extern const struct x86_dev_info peaq_c1010_info; extern const struct x86_dev_info whitelabel_tm800a550l_info; +extern const struct x86_dev_info vexia_edu_atla10_5v_info; extern const struct x86_dev_info vexia_edu_atla10_9v_info; extern const struct x86_dev_info xiaomi_mipad2_info; extern const struct dmi_system_id x86_android_tablet_ids[];
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Song Liu song@kernel.org
[ Upstream commit 40cb48eba3b4b79e110c1a35d33a48cac54507a2 ]
When testing a special config:
CONFIG_NETFS_SUPPORTS=y CONFIG_PROC_FS=n
The system crashes with something like:
[ 3.766197] ------------[ cut here ]------------ [ 3.766484] kernel BUG at mm/mempool.c:560! [ 3.766789] Oops: invalid opcode: 0000 [#1] SMP NOPTI [ 3.767123] CPU: 0 UID: 0 PID: 1 Comm: swapper/0 Tainted: G W [ 3.767777] Tainted: [W]=WARN [ 3.767968] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), [ 3.768523] RIP: 0010:mempool_alloc_slab.cold+0x17/0x19 [ 3.768847] Code: 50 fe ff 58 5b 5d 41 5c 41 5d 41 5e 41 5f e9 93 95 13 00 [ 3.769977] RSP: 0018:ffffc90000013998 EFLAGS: 00010286 [ 3.770315] RAX: 000000000000002f RBX: ffff888100ba8640 RCX: 0000000000000000 [ 3.770749] RDX: 0000000000000000 RSI: 0000000000000003 RDI: 00000000ffffffff [ 3.771217] RBP: 0000000000092880 R08: 0000000000000000 R09: ffffc90000013828 [ 3.771664] R10: 0000000000000001 R11: 00000000ffffffea R12: 0000000000092cc0 [ 3.772117] R13: 0000000000000400 R14: ffff8881004b1620 R15: ffffea0004ef7e40 [ 3.772554] FS: 0000000000000000(0000) GS:ffff8881b5f3c000(0000) knlGS:0000000000000000 [ 3.773061] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 3.773443] CR2: ffffffff830901b4 CR3: 0000000004296001 CR4: 0000000000770ef0 [ 3.773884] PKRU: 55555554 [ 3.774058] Call Trace: [ 3.774232] <TASK> [ 3.774371] mempool_alloc_noprof+0x6a/0x190 [ 3.774649] ? _printk+0x57/0x80 [ 3.774862] netfs_alloc_request+0x85/0x2ce [ 3.775147] netfs_readahead+0x28/0x170 [ 3.775395] read_pages+0x6c/0x350 [ 3.775623] ? srso_alias_return_thunk+0x5/0xfbef5 [ 3.775928] page_cache_ra_unbounded+0x1bd/0x2a0 [ 3.776247] filemap_get_pages+0x139/0x970 [ 3.776510] ? srso_alias_return_thunk+0x5/0xfbef5 [ 3.776820] filemap_read+0xf9/0x580 [ 3.777054] ? srso_alias_return_thunk+0x5/0xfbef5 [ 3.777368] ? srso_alias_return_thunk+0x5/0xfbef5 [ 3.777674] ? find_held_lock+0x32/0x90 [ 3.777929] ? netfs_start_io_read+0x19/0x70 [ 3.778221] ? netfs_start_io_read+0x19/0x70 [ 3.778489] ? srso_alias_return_thunk+0x5/0xfbef5 [ 3.778800] ? lock_acquired+0x1e6/0x450 [ 3.779054] ? srso_alias_return_thunk+0x5/0xfbef5 [ 3.779379] netfs_buffered_read_iter+0x57/0x80 [ 3.779670] __kernel_read+0x158/0x2c0 [ 3.779927] bprm_execve+0x300/0x7a0 [ 3.780185] kernel_execve+0x10c/0x140 [ 3.780423] ? __pfx_kernel_init+0x10/0x10 [ 3.780690] kernel_init+0xd5/0x150 [ 3.780910] ret_from_fork+0x2d/0x50 [ 3.781156] ? __pfx_kernel_init+0x10/0x10 [ 3.781414] ret_from_fork_asm+0x1a/0x30 [ 3.781677] </TASK> [ 3.781823] Modules linked in: [ 3.782065] ---[ end trace 0000000000000000 ]---
This is caused by the following error path in netfs_init():
if (!proc_mkdir("fs/netfs", NULL)) goto error_proc;
Fix this by adding ifdef in netfs_main(), so that /proc/fs/netfs is only created with CONFIG_PROC_FS.
Signed-off-by: Song Liu song@kernel.org Link: https://lore.kernel.org/20250409170015.2651829-1-song@kernel.org Acked-by: David Howells dhowells@redhat.com Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/netfs/main.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/fs/netfs/main.c b/fs/netfs/main.c index 4e3e620408314..70ecc8f5f2103 100644 --- a/fs/netfs/main.c +++ b/fs/netfs/main.c @@ -127,11 +127,13 @@ static int __init netfs_init(void) if (mempool_init_slab_pool(&netfs_subrequest_pool, 100, netfs_subrequest_slab) < 0) goto error_subreqpool;
+#ifdef CONFIG_PROC_FS if (!proc_mkdir("fs/netfs", NULL)) goto error_proc; if (!proc_create_seq("fs/netfs/requests", S_IFREG | 0444, NULL, &netfs_requests_seq_ops)) goto error_procfile; +#endif #ifdef CONFIG_FSCACHE_STATS if (!proc_create_single("fs/netfs/stats", S_IFREG | 0444, NULL, netfs_stats_show)) @@ -144,9 +146,11 @@ static int __init netfs_init(void) return 0;
error_fscache: +#ifdef CONFIG_PROC_FS error_procfile: remove_proc_subtree("fs/netfs", NULL); error_proc: +#endif mempool_exit(&netfs_subrequest_pool); error_subreqpool: kmem_cache_destroy(netfs_subrequest_slab);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gou Hao gouhao@uniontech.com
[ Upstream commit 8e3c15ee0d292c413c66fe10201d1b035a0bea72 ]
In iomap_adjust_read_range, i is either the first !uptodate block, or it is past last for the second loop looking for trailing uptodate blocks. Assuming there's no overflow (there's no combination of huge folios and tiny blksize) then yeah, there is no point in retesting that the same block pointed to by i is uptodate since we hold the folio lock so nobody else could have set it uptodate.
Signed-off-by: Gou Hao gouhao@uniontech.com Link: https://lore.kernel.org/20250410071236.16017-1-gouhao@uniontech.com Reviewed-by: "Darrick J. Wong" djwong@kernel.org Reviewed-by: Christoph Hellwig hch@lst.de Suggested-by: Christoph Hellwig hch@infradead.org Signed-off-by: Christian Brauner brauner@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- fs/iomap/buffered-io.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c index d303e6c8900cd..a47e3afd724ca 100644 --- a/fs/iomap/buffered-io.c +++ b/fs/iomap/buffered-io.c @@ -263,7 +263,7 @@ static void iomap_adjust_read_range(struct inode *inode, struct folio *folio, }
/* truncate len if we find any trailing uptodate block(s) */ - for ( ; i <= last; i++) { + while (++i <= last) { if (ifs_block_is_uptodate(ifs, i)) { plen -= (last - i + 1) * block_size; last = i - 1;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Jones ajones@ventanamicro.com
[ Upstream commit fb53a9aa5f5b8bf302f3260a7f1f5a24345ce62a ]
We need to provide all six forms of the alternative macros (ALTERNATIVE, ALTERNATIVE_2, _ALTERNATIVE_CFG, _ALTERNATIVE_CFG_2, __ALTERNATIVE_CFG, __ALTERNATIVE_CFG_2) for all four cases derived from the two ifdefs (RISCV_ALTERNATIVE, __ASSEMBLY__) in order to ensure all configs can compile. Define this missing ones and ensure all are defined to consume all parameters passed.
Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202504130710.3IKz6Ibs-lkp@intel.com/ Signed-off-by: Andrew Jones ajones@ventanamicro.com Tested-by: Alexandre Ghiti alexghiti@rivosinc.com Reviewed-by: Alexandre Ghiti alexghiti@rivosinc.com Link: https://lore.kernel.org/r/20250414120947.135173-2-ajones@ventanamicro.com Signed-off-by: Alexandre Ghiti alexghiti@rivosinc.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/riscv/include/asm/alternative-macros.h | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h index 721ec275ce57e..231d777d936c2 100644 --- a/arch/riscv/include/asm/alternative-macros.h +++ b/arch/riscv/include/asm/alternative-macros.h @@ -115,24 +115,19 @@ \old_c .endm
-#define _ALTERNATIVE_CFG(old_c, ...) \ - ALTERNATIVE_CFG old_c - -#define _ALTERNATIVE_CFG_2(old_c, ...) \ - ALTERNATIVE_CFG old_c +#define __ALTERNATIVE_CFG(old_c, ...) ALTERNATIVE_CFG old_c +#define __ALTERNATIVE_CFG_2(old_c, ...) ALTERNATIVE_CFG old_c
#else /* !__ASSEMBLY__ */
-#define __ALTERNATIVE_CFG(old_c) \ - old_c "\n" +#define __ALTERNATIVE_CFG(old_c, ...) old_c "\n" +#define __ALTERNATIVE_CFG_2(old_c, ...) old_c "\n"
-#define _ALTERNATIVE_CFG(old_c, ...) \ - __ALTERNATIVE_CFG(old_c) +#endif /* __ASSEMBLY__ */
-#define _ALTERNATIVE_CFG_2(old_c, ...) \ - __ALTERNATIVE_CFG(old_c) +#define _ALTERNATIVE_CFG(old_c, ...) __ALTERNATIVE_CFG(old_c) +#define _ALTERNATIVE_CFG_2(old_c, ...) __ALTERNATIVE_CFG_2(old_c)
-#endif /* __ASSEMBLY__ */ #endif /* CONFIG_RISCV_ALTERNATIVE */
/*
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon linkinjeon@kernel.org
[ Upstream commit 1df0d4c616138784e033ad337961b6e1a6bcd999 ]
wait_event_timeout() will set the state of the current task to TASK_UNINTERRUPTIBLE, before doing the condition check. This means that ksmbd_durable_scavenger_alive() will try to acquire the mutex while already in a sleeping state. The scheduler warns us by giving the following warning:
do not call blocking ops when !TASK_RUNNING; state=2 set at [<0000000061515a6f>] prepare_to_wait_event+0x9f/0x6c0 WARNING: CPU: 2 PID: 4147 at kernel/sched/core.c:10099 __might_sleep+0x12f/0x160
mutex lock is not needed in ksmbd_durable_scavenger_alive().
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/vfs_cache.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c index 8d1f30dcba7e8..1f8fa3468173a 100644 --- a/fs/smb/server/vfs_cache.c +++ b/fs/smb/server/vfs_cache.c @@ -713,12 +713,8 @@ static bool tree_conn_fd_check(struct ksmbd_tree_connect *tcon,
static bool ksmbd_durable_scavenger_alive(void) { - mutex_lock(&durable_scavenger_lock); - if (!durable_scavenger_running) { - mutex_unlock(&durable_scavenger_lock); + if (!durable_scavenger_running) return false; - } - mutex_unlock(&durable_scavenger_lock);
if (kthread_should_stop()) return false; @@ -799,9 +795,7 @@ static int ksmbd_durable_scavenger(void *dummy) break; }
- mutex_lock(&durable_scavenger_lock); durable_scavenger_running = false; - mutex_unlock(&durable_scavenger_lock);
module_put(THIS_MODULE);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao leitao@debian.org
[ Upstream commit 41c721fc093938745d116c3a21326a0ee03bb491 ]
Some machines with tegra_qspi_combined_seq_xfer hardware issues generate excessive kernel warnings, severely polluting the logs:
dmesg | grep -i "WARNING:.*tegra_qspi_transfer_one_message" | wc -l 94451
This patch replaces WARN_ON with WARN_ON_ONCE for timeout conditions to reduce log spam. The subsequent error message still prints on each occurrence, providing sufficient information about the failure, while the stack trace is only needed once for debugging purposes.
Signed-off-by: Breno Leitao leitao@debian.org Link: https://patch.msgid.link/20250401-tegra-v2-1-126c293ec047@debian.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-tegra210-quad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 08e49a8768943..2d320fbb8875f 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -1117,7 +1117,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, (&tqspi->xfer_completion, QSPI_DMA_TIMEOUT);
- if (WARN_ON(ret == 0)) { + if (WARN_ON_ONCE(ret == 0)) { dev_err(tqspi->dev, "QSPI Transfer failed with timeout: %d\n", ret); if (tqspi->is_curr_dma_xfer &&
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao leitao@debian.org
[ Upstream commit 21f4314e66ed8d40b2ee24185d1a06a07a512eb1 ]
On malfunctioning hardware, timeout error messages can appear thousands of times, creating unnecessary system pressure and log bloat. This patch makes two improvements:
1. Replace dev_err() with dev_err_ratelimited() to prevent log flooding when hardware errors persist 2. Remove the redundant timeout value parameter from the error message, as 'ret' is always zero in this error path
These changes reduce logging overhead while maintaining necessary error reporting for debugging purposes.
Signed-off-by: Breno Leitao leitao@debian.org Link: https://patch.msgid.link/20250401-tegra-v2-2-126c293ec047@debian.org Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-tegra210-quad.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 2d320fbb8875f..64e1b2f8a0001 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -1118,8 +1118,8 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, QSPI_DMA_TIMEOUT);
if (WARN_ON_ONCE(ret == 0)) { - dev_err(tqspi->dev, "QSPI Transfer failed with timeout: %d\n", - ret); + dev_err_ratelimited(tqspi->dev, + "QSPI Transfer failed with timeout\n"); if (tqspi->is_curr_dma_xfer && (tqspi->cur_direction & DATA_DIR_TX)) dmaengine_terminate_all
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mostafa Saleh smostafa@google.com
[ Upstream commit 9b044614be12d78d3a93767708b8d02fb7dfa9b0 ]
Running lib_ubsan.ko on arm64 (without CONFIG_UBSAN_TRAP) panics the kernel:
[ 31.616546] Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: test_ubsan_out_of_bounds+0x158/0x158 [test_ubsan] [ 31.646817] CPU: 3 UID: 0 PID: 179 Comm: insmod Not tainted 6.15.0-rc2 #1 PREEMPT [ 31.648153] Hardware name: linux,dummy-virt (DT) [ 31.648970] Call trace: [ 31.649345] show_stack+0x18/0x24 (C) [ 31.650960] dump_stack_lvl+0x40/0x84 [ 31.651559] dump_stack+0x18/0x24 [ 31.652264] panic+0x138/0x3b4 [ 31.652812] __ktime_get_real_seconds+0x0/0x10 [ 31.653540] test_ubsan_load_invalid_value+0x0/0xa8 [test_ubsan] [ 31.654388] init_module+0x24/0xff4 [test_ubsan] [ 31.655077] do_one_initcall+0xd4/0x280 [ 31.655680] do_init_module+0x58/0x2b4
That happens because the test corrupts other data in the stack: 400: d5384108 mrs x8, sp_el0 404: f9426d08 ldr x8, [x8, #1240] 408: f85f83a9 ldur x9, [x29, #-8] 40c: eb09011f cmp x8, x9 410: 54000301 b.ne 470 <test_ubsan_out_of_bounds+0x154> // b.any
As there is no guarantee the compiler will order the local variables as declared in the module: volatile char above[4] = { }; /* Protect surrounding memory. */ volatile int arr[4]; volatile char below[4] = { }; /* Protect surrounding memory. */
There is another problem where the out-of-bound index is 5 which is larger than the extra surrounding memory for protection.
So, use a struct to enforce the ordering, and fix the index to be 4. Also, remove some of the volatiles and rely on OPTIMIZER_HIDE_VAR()
Signed-off-by: Mostafa Saleh smostafa@google.com Link: https://lore.kernel.org/r/20250415203354.4109415-1-smostafa@google.com Signed-off-by: Kees Cook kees@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- lib/test_ubsan.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/lib/test_ubsan.c b/lib/test_ubsan.c index 5d7b10e986107..63b7566e78639 100644 --- a/lib/test_ubsan.c +++ b/lib/test_ubsan.c @@ -68,18 +68,22 @@ static void test_ubsan_shift_out_of_bounds(void)
static void test_ubsan_out_of_bounds(void) { - volatile int i = 4, j = 5, k = -1; - volatile char above[4] = { }; /* Protect surrounding memory. */ - volatile int arr[4]; - volatile char below[4] = { }; /* Protect surrounding memory. */ + int i = 4, j = 4, k = -1; + volatile struct { + char above[4]; /* Protect surrounding memory. */ + int arr[4]; + char below[4]; /* Protect surrounding memory. */ + } data;
- above[0] = below[0]; + OPTIMIZER_HIDE_VAR(i); + OPTIMIZER_HIDE_VAR(j); + OPTIMIZER_HIDE_VAR(k);
UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "above"); - arr[j] = i; + data.arr[j] = i;
UBSAN_TEST(CONFIG_UBSAN_BOUNDS, "below"); - arr[k] = i; + data.arr[k] = i; }
enum ubsan_test_enum {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal dlemoal@kernel.org
[ Upstream commit ad91308d3bdeb9d90ef4a400f379ce461f0fb6a7 ]
Since the link_up boolean field of struct nvmet_pci_epf_ctrl is always set to true when nvmet_pci_epf_start_ctrl() is called, assign true to this field in nvmet_pci_epf_start_ctrl(). Conversely, since this field is set to false when nvmet_pci_epf_stop_ctrl() is called, set this field to false directly inside that function.
While at it, also add information messages to notify the user of the PCI link state changes to help troubleshoot any link stability issues without needing to enable debug messages.
Signed-off-by: Damien Le Moal dlemoal@kernel.org Reviewed-by: Keith Busch kbusch@kernel.org Reviewed-by: Niklas Cassel cassel@kernel.org Signed-off-by: Christoph Hellwig hch@lst.de Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/nvme/target/pci-epf.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/drivers/nvme/target/pci-epf.c b/drivers/nvme/target/pci-epf.c index 5c4c4c1f535d4..bc1daa9aede9d 100644 --- a/drivers/nvme/target/pci-epf.c +++ b/drivers/nvme/target/pci-epf.c @@ -2109,11 +2109,18 @@ static int nvmet_pci_epf_create_ctrl(struct nvmet_pci_epf *nvme_epf,
static void nvmet_pci_epf_start_ctrl(struct nvmet_pci_epf_ctrl *ctrl) { + + dev_info(ctrl->dev, "PCI link up\n"); + ctrl->link_up = true; + schedule_delayed_work(&ctrl->poll_cc, NVMET_PCI_EPF_CC_POLL_INTERVAL); }
static void nvmet_pci_epf_stop_ctrl(struct nvmet_pci_epf_ctrl *ctrl) { + dev_info(ctrl->dev, "PCI link down\n"); + ctrl->link_up = false; + cancel_delayed_work_sync(&ctrl->poll_cc);
nvmet_pci_epf_disable_ctrl(ctrl, false); @@ -2340,10 +2347,8 @@ static int nvmet_pci_epf_epc_init(struct pci_epf *epf) if (ret) goto out_clear_bar;
- if (!epc_features->linkup_notifier) { - ctrl->link_up = true; + if (!epc_features->linkup_notifier) nvmet_pci_epf_start_ctrl(&nvme_epf->ctrl); - }
return 0;
@@ -2359,7 +2364,6 @@ static void nvmet_pci_epf_epc_deinit(struct pci_epf *epf) struct nvmet_pci_epf *nvme_epf = epf_get_drvdata(epf); struct nvmet_pci_epf_ctrl *ctrl = &nvme_epf->ctrl;
- ctrl->link_up = false; nvmet_pci_epf_destroy_ctrl(ctrl);
nvmet_pci_epf_deinit_dma(nvme_epf); @@ -2371,7 +2375,6 @@ static int nvmet_pci_epf_link_up(struct pci_epf *epf) struct nvmet_pci_epf *nvme_epf = epf_get_drvdata(epf); struct nvmet_pci_epf_ctrl *ctrl = &nvme_epf->ctrl;
- ctrl->link_up = true; nvmet_pci_epf_start_ctrl(ctrl);
return 0; @@ -2382,7 +2385,6 @@ static int nvmet_pci_epf_link_down(struct pci_epf *epf) struct nvmet_pci_epf *nvme_epf = epf_get_drvdata(epf); struct nvmet_pci_epf_ctrl *ctrl = &nvme_epf->ctrl;
- ctrl->link_up = false; nvmet_pci_epf_stop_ctrl(ctrl);
return 0;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pi Xiange xiange.pi@intel.com
[ Upstream commit d466304c4322ad391797437cd84cca7ce1660de0 ]
Bartlett Lake has a P-core only product with Raptor Cove.
[ mingo: Switch around the define as pointed out by Christian Ludloff: Ratpr Cove is the core, Bartlett Lake is the product.
Signed-off-by: Pi Xiange xiange.pi@intel.com Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Christian Ludloff ludloff@gmail.com Cc: Peter Zijlstra peterz@infradead.org Cc: Tony Luck tony.luck@intel.com Cc: Andrew Cooper andrew.cooper3@citrix.com Cc: "H. Peter Anvin" hpa@zytor.com Cc: John Ogness john.ogness@linutronix.de Cc: "Ahmed S. Darwish" darwi@linutronix.de Cc: x86-cpuid@lists.linux.dev Link: https://lore.kernel.org/r/20250414032839.5368-1-xiange.pi@intel.com Signed-off-by: Sasha Levin sashal@kernel.org --- arch/x86/include/asm/intel-family.h | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h index 6d7b04ffc5fd0..ef5a06ddf0287 100644 --- a/arch/x86/include/asm/intel-family.h +++ b/arch/x86/include/asm/intel-family.h @@ -115,6 +115,8 @@ #define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) #define INTEL_GRANITERAPIDS_D IFM(6, 0xAE)
+#define INTEL_BARTLETTLAKE IFM(6, 0xD7) /* Raptor Cove */ + /* "Hybrid" Processors (P-Core/E-Core) */
#define INTEL_LAKEFIELD IFM(6, 0x8A) /* Sunny Cove / Tremont */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Meir Elisha meir.elisha@volumez.com
[ Upstream commit b7c178d9e57c8fd4238ff77263b877f6f16182ba ]
During recovery/check operations, the process_checks function loops through available disks to find a 'primary' source with successfully read data.
If no suitable source disk is found after checking all possibilities, the 'primary' index will reach conf->raid_disks * 2. Add an explicit check for this condition after the loop. If no source disk was found, print an error message and return early to prevent further processing without a valid primary source.
Link: https://lore.kernel.org/linux-raid/20250408143808.1026534-1-meir.elisha@volu... Signed-off-by: Meir Elisha meir.elisha@volumez.com Suggested-and-reviewed-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Yu Kuai yukuai3@huawei.com Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/md/raid1.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 15829ab192d2b..7373dff023d0f 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2199,14 +2199,9 @@ static int fix_sync_read_error(struct r1bio *r1_bio) if (!rdev_set_badblocks(rdev, sect, s, 0)) abort = 1; } - if (abort) { - conf->recovery_disabled = - mddev->recovery_disabled; - set_bit(MD_RECOVERY_INTR, &mddev->recovery); - md_done_sync(mddev, r1_bio->sectors, 0); - put_buf(r1_bio); + if (abort) return 0; - } + /* Try next page */ sectors -= s; sect += s; @@ -2345,10 +2340,21 @@ static void sync_request_write(struct mddev *mddev, struct r1bio *r1_bio) int disks = conf->raid_disks * 2; struct bio *wbio;
- if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) - /* ouch - failed to read all of that. */ - if (!fix_sync_read_error(r1_bio)) + if (!test_bit(R1BIO_Uptodate, &r1_bio->state)) { + /* + * ouch - failed to read all of that. + * No need to fix read error for check/repair + * because all member disks are read. + */ + if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) || + !fix_sync_read_error(r1_bio)) { + conf->recovery_disabled = mddev->recovery_disabled; + set_bit(MD_RECOVERY_INTR, &mddev->recovery); + md_done_sync(mddev, r1_bio->sectors, 0); + put_buf(r1_bio); return; + } + }
if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) process_checks(r1_bio);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian König christian.koenig@amd.com
[ Upstream commit 447fab30955cf7dba7dd563f42b67c02284860c8 ]
Otherwise triggering sysfs multiple times without other submissions in between only runs the shader once.
v2: add some comment v3: re-add missing cast v4: squash in semicolon fix
Signed-off-by: Christian König christian.koenig@amd.com Reviewed-by: Srinivasan Shanmugam srinivasan.shanmugam@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 8b2ae7d492675e8af8902f103364bef59382b935) Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c index c1f35ded684e8..506786784e32d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c @@ -1411,9 +1411,11 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring) struct amdgpu_device *adev = ring->adev; struct drm_gpu_scheduler *sched = &ring->sched; struct drm_sched_entity entity; + static atomic_t counter; struct dma_fence *f; struct amdgpu_job *job; struct amdgpu_ib *ib; + void *owner; int i, r;
/* Initialize the scheduler entity */ @@ -1424,9 +1426,15 @@ static int amdgpu_gfx_run_cleaner_shader_job(struct amdgpu_ring *ring) goto err; }
- r = amdgpu_job_alloc_with_ib(ring->adev, &entity, NULL, - 64, 0, - &job); + /* + * Use some unique dummy value as the owner to make sure we execute + * the cleaner shader on each submission. The value just need to change + * for each submission and is otherwise meaningless. + */ + owner = (void *)(unsigned long)atomic_inc_return(&counter); + + r = amdgpu_job_alloc_with_ib(ring->adev, &entity, owner, + 64, 0, &job); if (r) goto err;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello mario.limonciello@amd.com
[ Upstream commit 1657793def101dac7c9d3b2250391f6a3dd934ba ]
On systems that default to 'deep' some userspace software likes to try to suspend in 'deep' first. If there is a failure for any reason (such as -ENOMEM) the failure is ignored and then it will try to use 's2idle' as a fallback. This fails, but more importantly it leads to graphical problems.
Forbid this behavior and only allow suspending in the last state supported by the system.
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4093 Acked-by: Alex Deucher alexander.deucher@amd.com Link: https://lore.kernel.org/r/20250408180957.4027643-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 2aabd44aa8a3c08da3d43264c168370f6da5e81d) Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/amdgpu.h | 1 + drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index ab04d56b4fe36..98f0c12df12bc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -1118,6 +1118,7 @@ struct amdgpu_device { bool in_s3; bool in_s4; bool in_s0ix; + suspend_state_t last_suspend_state;
enum pp_mp1_state mp1_state; struct amdgpu_doorbell_index doorbell_index; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c index 24c255e05079e..f2d77bc04e4a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c @@ -2515,8 +2515,20 @@ static int amdgpu_pmops_suspend(struct device *dev) adev->in_s0ix = true; else if (amdgpu_acpi_is_s3_active(adev)) adev->in_s3 = true; - if (!adev->in_s0ix && !adev->in_s3) + if (!adev->in_s0ix && !adev->in_s3) { + /* don't allow going deep first time followed by s2idle the next time */ + if (adev->last_suspend_state != PM_SUSPEND_ON && + adev->last_suspend_state != pm_suspend_target_state) { + drm_err_once(drm_dev, "Unsupported suspend state %d\n", + pm_suspend_target_state); + return -EINVAL; + } return 0; + } + + /* cache the state last used for suspend */ + adev->last_suspend_state = pm_suspend_target_state; + return amdgpu_device_suspend(drm_dev, true); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar lijo.lazar@amd.com
[ Upstream commit c235a7132258ac30bd43d228222986022d21f5de ]
There are a few prechecks made before HDP flush like a flush is not required on APU bare metal. Using hdp callback directly bypasses those checks. Use amdgpu_device_flush_hdp which takes care of prechecks.
Signed-off-by: Lijo Lazar lijo.lazar@amd.com Reviewed-by: Alex Deucher alexander.deucher@amd.com Signed-off-by: Alex Deucher alexander.deucher@amd.com (cherry picked from commit 1d9bff4cf8c53d33ee2ff1b11574e5da739ce61c) Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 8 ++++---- drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c | 12 ++++++------ drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c | 6 +++--- drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c | 4 ++-- drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/psp_v13_0.c | 2 +- drivers/gpu/drm/amd/amdgpu/psp_v14_0.c | 2 +- 10 files changed, 23 insertions(+), 23 deletions(-)
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c index 5ba263fe55121..1f32c531f610e 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c @@ -6044,7 +6044,7 @@ static int gfx_v10_0_cp_gfx_load_pfp_microcode(struct amdgpu_device *adev) }
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
tmp = RREG32_SOC15(GC, 0, mmCP_PFP_IC_BASE_CNTL); tmp = REG_SET_FIELD(tmp, CP_PFP_IC_BASE_CNTL, VMID, 0); @@ -6122,7 +6122,7 @@ static int gfx_v10_0_cp_gfx_load_ce_microcode(struct amdgpu_device *adev) }
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
tmp = RREG32_SOC15(GC, 0, mmCP_CE_IC_BASE_CNTL); tmp = REG_SET_FIELD(tmp, CP_CE_IC_BASE_CNTL, VMID, 0); @@ -6199,7 +6199,7 @@ static int gfx_v10_0_cp_gfx_load_me_microcode(struct amdgpu_device *adev) }
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
tmp = RREG32_SOC15(GC, 0, mmCP_ME_IC_BASE_CNTL); tmp = REG_SET_FIELD(tmp, CP_ME_IC_BASE_CNTL, VMID, 0); @@ -6574,7 +6574,7 @@ static int gfx_v10_0_cp_compute_load_microcode(struct amdgpu_device *adev) }
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
tmp = RREG32_SOC15(GC, 0, mmCP_CPC_IC_BASE_CNTL); tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0); diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c index cfb51baa581a1..f1f53c7687410 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v11_0.c @@ -2391,7 +2391,7 @@ static int gfx_v11_0_config_me_cache(struct amdgpu_device *adev, uint64_t addr) }
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
tmp = RREG32_SOC15(GC, 0, regCP_ME_IC_BASE_CNTL); tmp = REG_SET_FIELD(tmp, CP_ME_IC_BASE_CNTL, VMID, 0); @@ -2435,7 +2435,7 @@ static int gfx_v11_0_config_pfp_cache(struct amdgpu_device *adev, uint64_t addr) }
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
tmp = RREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_CNTL); tmp = REG_SET_FIELD(tmp, CP_PFP_IC_BASE_CNTL, VMID, 0); @@ -2480,7 +2480,7 @@ static int gfx_v11_0_config_mec_cache(struct amdgpu_device *adev, uint64_t addr) }
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
tmp = RREG32_SOC15(GC, 0, regCP_CPC_IC_BASE_CNTL); tmp = REG_SET_FIELD(tmp, CP_CPC_IC_BASE_CNTL, CACHE_POLICY, 0); @@ -3115,7 +3115,7 @@ static int gfx_v11_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev) amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj);
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, lower_32_bits(adev->gfx.pfp.pfp_fw_gpu_addr)); @@ -3333,7 +3333,7 @@ static int gfx_v11_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev) amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj);
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, lower_32_bits(adev->gfx.me.me_fw_gpu_addr)); @@ -4549,7 +4549,7 @@ static int gfx_v11_0_gfxhub_enable(struct amdgpu_device *adev) if (r) return r;
- adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? false : true; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c index c21b168f75a75..0c08785099f32 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v12_0.c @@ -2306,7 +2306,7 @@ static int gfx_v12_0_cp_gfx_load_pfp_microcode_rs64(struct amdgpu_device *adev) amdgpu_bo_unreserve(adev->gfx.pfp.pfp_fw_data_obj);
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
WREG32_SOC15(GC, 0, regCP_PFP_IC_BASE_LO, lower_32_bits(adev->gfx.pfp.pfp_fw_gpu_addr)); @@ -2450,7 +2450,7 @@ static int gfx_v12_0_cp_gfx_load_me_microcode_rs64(struct amdgpu_device *adev) amdgpu_bo_unreserve(adev->gfx.me.me_fw_data_obj);
if (amdgpu_emu_mode == 1) - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
WREG32_SOC15(GC, 0, regCP_ME_IC_BASE_LO, lower_32_bits(adev->gfx.me.me_fw_gpu_addr)); @@ -3469,7 +3469,7 @@ static int gfx_v12_0_gfxhub_enable(struct amdgpu_device *adev) if (r) return r;
- adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? false : true; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 9bedca9a79c63..a88ad9951d328 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -268,7 +268,7 @@ static void gmc_v10_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
/* flush hdp cache */ - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
/* This is necessary for SRIOV as well as for GFXOFF to function * properly under bare metal @@ -969,7 +969,7 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) adev->hdp.funcs->init_registers(adev);
/* Flush HDP after it is initialized */ - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? false : true; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 72751ab4c766e..1eb97117fe7ae 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -229,7 +229,7 @@ static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, ack = hub->vm_inv_eng0_ack + hub->eng_distance * eng;
/* flush hdp cache */ - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
/* This is necessary for SRIOV as well as for GFXOFF to function * properly under bare metal @@ -896,7 +896,7 @@ static int gmc_v11_0_gart_enable(struct amdgpu_device *adev) return r;
/* Flush HDP after it is initialized */ - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? false : true; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c index c3c144a4f45eb..0f136d6bbdc9b 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v12_0.c @@ -297,7 +297,7 @@ static void gmc_v12_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid, return;
/* flush hdp cache */ - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
/* This is necessary for SRIOV as well as for GFXOFF to function * properly under bare metal @@ -881,7 +881,7 @@ static int gmc_v12_0_gart_enable(struct amdgpu_device *adev) return r;
/* Flush HDP after it is initialized */ - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
value = (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) ? false : true; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 291549765c38c..5250b470e5ef3 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -2434,7 +2434,7 @@ static int gmc_v9_0_hw_init(struct amdgpu_ip_block *ip_block) adev->hdp.funcs->init_registers(adev);
/* After HDP is initialized, flush HDP.*/ - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL);
if (amdgpu_vm_fault_stop == AMDGPU_VM_FAULT_STOP_ALWAYS) value = false; diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c index 2395f1856962a..e77a467af7ac3 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c @@ -532,7 +532,7 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops) }
memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL); vfree(buf); drm_dev_exit(idx); } else { diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c index cc621064610f1..afdf8ce3b4c59 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v13_0.c @@ -610,7 +610,7 @@ static int psp_v13_0_memory_training(struct psp_context *psp, uint32_t ops) }
memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL); vfree(buf); drm_dev_exit(idx); } else { diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v14_0.c b/drivers/gpu/drm/amd/amdgpu/psp_v14_0.c index 4d33c95a51163..89f6c06946c51 100644 --- a/drivers/gpu/drm/amd/amdgpu/psp_v14_0.c +++ b/drivers/gpu/drm/amd/amdgpu/psp_v14_0.c @@ -488,7 +488,7 @@ static int psp_v14_0_memory_training(struct psp_context *psp, uint32_t ops) }
memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); - adev->hdp.funcs->flush_hdp(adev, NULL); + amdgpu_device_flush_hdp(adev, NULL); vfree(buf); drm_dev_exit(idx); } else {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 00b3b0d7cb454d614117c93f33351cdcd20b5b93 ]
Add ublk_force_abort_dev() for handling ublk_nosrv_dev_should_queue_io() in ublk_stop_dev(). Then queue quiesce and unquiesce can be paired in single function.
Meantime not change device state to QUIESCED any more, since the disk is going to be removed soon.
Reviewed-by: Uday Shankar ushankar@purestorage.com Signed-off-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20250416035444.99569-3-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index c7761a5cfeec0..7bb7276f14c60 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1707,22 +1707,20 @@ static void __ublk_quiesce_dev(struct ublk_device *ub) ub->dev_info.state = UBLK_S_DEV_QUIESCED; }
-static void ublk_unquiesce_dev(struct ublk_device *ub) +static void ublk_force_abort_dev(struct ublk_device *ub) { int i;
- pr_devel("%s: unquiesce ub: dev_id %d state %s\n", + pr_devel("%s: force abort ub: dev_id %d state %s\n", __func__, ub->dev_info.dev_id, ub->dev_info.state == UBLK_S_DEV_LIVE ? "LIVE" : "QUIESCED"); - /* quiesce_work has run. We let requeued rqs be aborted - * before running fallback_wq. "force_abort" must be seen - * after request queue is unqiuesced. Then del_gendisk() - * can move on. - */ + blk_mq_quiesce_queue(ub->ub_disk->queue); + if (ub->dev_info.state == UBLK_S_DEV_LIVE) + ublk_wait_tagset_rqs_idle(ub); + for (i = 0; i < ub->dev_info.nr_hw_queues; i++) ublk_get_queue(ub, i)->force_abort = true; - blk_mq_unquiesce_queue(ub->ub_disk->queue); /* We may have requeued some rqs in ublk_quiesce_queue() */ blk_mq_kick_requeue_list(ub->ub_disk->queue); @@ -1750,11 +1748,8 @@ static void ublk_stop_dev(struct ublk_device *ub) mutex_lock(&ub->mutex); if (ub->dev_info.state == UBLK_S_DEV_DEAD) goto unlock; - if (ublk_nosrv_dev_should_queue_io(ub)) { - if (ub->dev_info.state == UBLK_S_DEV_LIVE) - __ublk_quiesce_dev(ub); - ublk_unquiesce_dev(ub); - } + if (ublk_nosrv_dev_should_queue_io(ub)) + ublk_force_abort_dev(ub); del_gendisk(ub->ub_disk); disk = ublk_detach_disk(ub); put_disk(disk);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
[ Upstream commit 7e26cb69c5e62152a6f05a2ae23605a983a8ef31 ]
Now ublk deals with ublk_nosrv_dev_should_queue_io() by keeping request queue as quiesced. This way is fragile because queue quiesce crosses syscalls or process contexts.
Switch to rely on ubq->canceling for dealing with ublk_nosrv_dev_should_queue_io(), because it has been used for this purpose during io_uring context exiting, and it can be reused before recovering too. In ublk_queue_rq(), the request will be added to requeue list without kicking off requeue in case of ubq->canceling, and finally requests added in requeue list will be dispatched from either ublk_stop_dev() or ublk_ctrl_end_recovery().
Meantime we have to move reset of ubq->canceling from ublk_ctrl_start_recovery() to ublk_ctrl_end_recovery(), when IO handling can be recovered completely.
Then blk_mq_quiesce_queue() and blk_mq_unquiesce_queue() are always used in same context.
Signed-off-by: Ming Lei ming.lei@redhat.com Reviewed-by: Uday Shankar ushankar@purestorage.com Link: https://lore.kernel.org/r/20250416035444.99569-4-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/block/ublk_drv.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c index 7bb7276f14c60..0efac33473c1e 100644 --- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1698,13 +1698,19 @@ static void ublk_wait_tagset_rqs_idle(struct ublk_device *ub)
static void __ublk_quiesce_dev(struct ublk_device *ub) { + int i; + pr_devel("%s: quiesce ub: dev_id %d state %s\n", __func__, ub->dev_info.dev_id, ub->dev_info.state == UBLK_S_DEV_LIVE ? "LIVE" : "QUIESCED"); blk_mq_quiesce_queue(ub->ub_disk->queue); + /* mark every queue as canceling */ + for (i = 0; i < ub->dev_info.nr_hw_queues; i++) + ublk_get_queue(ub, i)->canceling = true; ublk_wait_tagset_rqs_idle(ub); ub->dev_info.state = UBLK_S_DEV_QUIESCED; + blk_mq_unquiesce_queue(ub->ub_disk->queue); }
static void ublk_force_abort_dev(struct ublk_device *ub) @@ -2846,7 +2852,6 @@ static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq) /* We have to reset it to NULL, otherwise ub won't accept new FETCH_REQ */ ubq->ubq_daemon = NULL; ubq->timeout = false; - ubq->canceling = false;
for (i = 0; i < ubq->q_depth; i++) { struct ublk_io *io = &ubq->ios[i]; @@ -2935,20 +2940,18 @@ static int ublk_ctrl_end_recovery(struct ublk_device *ub, pr_devel("%s: new ublksrv_pid %d, dev id %d\n", __func__, ublksrv_pid, header->dev_id);
- if (ublk_nosrv_dev_should_queue_io(ub)) { - ub->dev_info.state = UBLK_S_DEV_LIVE; - blk_mq_unquiesce_queue(ub->ub_disk->queue); - pr_devel("%s: queue unquiesced, dev id %d.\n", - __func__, header->dev_id); - blk_mq_kick_requeue_list(ub->ub_disk->queue); - } else { - blk_mq_quiesce_queue(ub->ub_disk->queue); - ub->dev_info.state = UBLK_S_DEV_LIVE; - for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { - ublk_get_queue(ub, i)->fail_io = false; - } - blk_mq_unquiesce_queue(ub->ub_disk->queue); + blk_mq_quiesce_queue(ub->ub_disk->queue); + ub->dev_info.state = UBLK_S_DEV_LIVE; + for (i = 0; i < ub->dev_info.nr_hw_queues; i++) { + struct ublk_queue *ubq = ublk_get_queue(ub, i); + + ubq->canceling = false; + ubq->fail_io = false; } + blk_mq_unquiesce_queue(ub->ub_disk->queue); + pr_devel("%s: queue unquiesced, dev id %d.\n", + __func__, header->dev_id); + blk_mq_kick_requeue_list(ub->ub_disk->queue);
ret = 0; out_unlock:
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tamura Dai kirinode0@gmail.com
[ Upstream commit 951a04ab3a2db4029debfa48d380ef834b93207e ]
Add check for the return value of spi_imx_setupxfer(). spi_imx->rx and spi_imx->tx function pointer can be NULL when spi_imx_setupxfer() return error, and make NULL pointer dereference.
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 Call trace: 0x0 spi_imx_pio_transfer+0x50/0xd8 spi_imx_transfer_one+0x18c/0x858 spi_transfer_one_message+0x43c/0x790 __spi_pump_transfer_message+0x238/0x5d4 __spi_sync+0x2b0/0x454 spi_write_then_read+0x11c/0x200
Signed-off-by: Tamura Dai kirinode0@gmail.com Reviewed-by: Carlos Song carlos.song@nxp.com Link: https://patch.msgid.link/20250417011700.14436-1-kirinode0@gmail.com Signed-off-by: Mark Brown broonie@kernel.org Signed-off-by: Sasha Levin sashal@kernel.org --- drivers/spi/spi-imx.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index eeb7d082c2472..c43fb496da956 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1695,9 +1695,12 @@ static int spi_imx_transfer_one(struct spi_controller *controller, struct spi_device *spi, struct spi_transfer *transfer) { + int ret; struct spi_imx_data *spi_imx = spi_controller_get_devdata(spi->controller);
- spi_imx_setupxfer(spi, transfer); + ret = spi_imx_setupxfer(spi, transfer); + if (ret < 0) + return ret; transfer->effective_speed_hz = spi_imx->spi_bus_clk;
/* flush rxfifo before transfer */
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov dmitry.torokhov@gmail.com
commit dc1771f718548f7d4b93991b174c6e7b5e1ba410 upstream.
This reverts commit c0a40097f0bc81deafc15f9195d1fb54595cd6d0.
Probing a device can take arbitrary long time. In the field we observed that, for example, probing a bad micro-SD cards in an external USB card reader (or maybe cards were good but cables were flaky) sometimes takes longer than 2 minutes due to multiple retries at various levels of the stack. We can not block uevent_show() method for that long because udev is reading that attribute very often and that blocks udev and interferes with booting of the system.
The change that introduced locking was concerned with dev_uevent() racing with unbinding the driver. However we can handle it without locking (which will be done in subsequent patch).
There was also claim that synchronization with probe() is needed to properly load USB drivers, however this is a red herring: the change adding the lock was introduced in May of last year and USB loading and probing worked properly for many years before that.
Revert the harmful locking.
Cc: stable@vger.kernel.org Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Reviewed-by: Masami Hiramatsu (Google) mhiramat@kernel.org Link: https://lore.kernel.org/r/20250311052417.1846985-1-dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/core.c | 3 --- 1 file changed, 3 deletions(-)
--- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2726,11 +2726,8 @@ static ssize_t uevent_show(struct device if (!env) return -ENOMEM;
- /* Synchronize with really_probe() */ - device_lock(dev); /* let the kset specific function add its keys */ retval = kset->uevent_ops->uevent(&dev->kobj, env); - device_unlock(dev); if (retval) goto out;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov dmitry.torokhov@gmail.com
commit 04d3e5461c1f5cf8eec964ab64948ebed826e95e upstream.
In preparation to closing a race when reading driver pointer in dev_uevent() code, instead of setting device->driver pointer directly introduce device_set_driver() helper.
Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Reviewed-by: Masami Hiramatsu (Google) mhiramat@kernel.org Link: https://lore.kernel.org/r/20250311052417.1846985-2-dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/base.h | 6 ++++++ drivers/base/core.c | 2 +- drivers/base/dd.c | 7 +++---- 3 files changed, 10 insertions(+), 5 deletions(-)
--- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -180,6 +180,12 @@ int driver_add_groups(const struct devic void driver_remove_groups(const struct device_driver *drv, const struct attribute_group **groups); void device_driver_detach(struct device *dev);
+static inline void device_set_driver(struct device *dev, const struct device_driver *drv) +{ + // FIXME - this cast should not be needed "soon" + dev->driver = (struct device_driver *)drv; +} + int devres_release_all(struct device *dev); void device_block_probing(void); void device_unblock_probing(void); --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3697,7 +3697,7 @@ done: device_pm_remove(dev); dpm_sysfs_remove(dev); DPMError: - dev->driver = NULL; + device_set_driver(dev, NULL); bus_remove_device(dev); BusError: device_remove_attrs(dev); --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -550,7 +550,7 @@ static void device_unbind_cleanup(struct arch_teardown_dma_ops(dev); kfree(dev->dma_range_map); dev->dma_range_map = NULL; - dev->driver = NULL; + device_set_driver(dev, NULL); dev_set_drvdata(dev, NULL); if (dev->pm_domain && dev->pm_domain->dismiss) dev->pm_domain->dismiss(dev); @@ -629,8 +629,7 @@ static int really_probe(struct device *d }
re_probe: - // FIXME - this cast should not be needed "soon" - dev->driver = (struct device_driver *)drv; + device_set_driver(dev, drv);
/* If using pinctrl, bind pins now before probing */ ret = pinctrl_bind_pins(dev); @@ -1014,7 +1013,7 @@ static int __device_attach(struct device if (ret == 0) ret = 1; else { - dev->driver = NULL; + device_set_driver(dev, NULL); ret = 0; } } else {
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov dmitry.torokhov@gmail.com
commit 18daa52418e7e4629ed1703b64777294209d2622 upstream.
If userspace reads "uevent" device attribute at the same time as another threads unbinds the device from its driver, change to dev->driver from a valid pointer to NULL may result in crash. Fix this by using READ_ONCE() when fetching the pointer, and take bus' drivers klist lock to make sure driver instance will not disappear while we access it.
Use WRITE_ONCE() when setting the driver pointer to ensure there is no tearing.
Signed-off-by: Dmitry Torokhov dmitry.torokhov@gmail.com Reviewed-by: Masami Hiramatsu (Google) mhiramat@kernel.org Link: https://lore.kernel.org/r/20250311052417.1846985-3-dmitry.torokhov@gmail.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/base/base.h | 13 ++++++++++++- drivers/base/bus.c | 2 +- drivers/base/core.c | 33 +++++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 4 deletions(-)
--- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -73,6 +73,7 @@ static inline void subsys_put(struct sub kset_put(&sp->subsys); }
+struct subsys_private *bus_to_subsys(const struct bus_type *bus); struct subsys_private *class_to_subsys(const struct class *class);
struct driver_private { @@ -182,8 +183,18 @@ void device_driver_detach(struct device
static inline void device_set_driver(struct device *dev, const struct device_driver *drv) { + /* + * Majority (all?) read accesses to dev->driver happens either + * while holding device lock or in bus/driver code that is only + * invoked when the device is bound to a driver and there is no + * concern of the pointer being changed while it is being read. + * However when reading device's uevent file we read driver pointer + * without taking device lock (so we do not block there for + * arbitrary amount of time). We use WRITE_ONCE() here to prevent + * tearing so that READ_ONCE() can safely be used in uevent code. + */ // FIXME - this cast should not be needed "soon" - dev->driver = (struct device_driver *)drv; + WRITE_ONCE(dev->driver, (struct device_driver *)drv); }
int devres_release_all(struct device *dev); --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -57,7 +57,7 @@ static int __must_check bus_rescan_devic * NULL. A call to subsys_put() must be done when finished with the pointer in * order for it to be properly freed. */ -static struct subsys_private *bus_to_subsys(const struct bus_type *bus) +struct subsys_private *bus_to_subsys(const struct bus_type *bus) { struct subsys_private *sp = NULL; struct kobject *kobj; --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2624,6 +2624,35 @@ static const char *dev_uevent_name(const return NULL; }
+/* + * Try filling "DRIVER=<name>" uevent variable for a device. Because this + * function may race with binding and unbinding the device from a driver, + * we need to be careful. Binding is generally safe, at worst we miss the + * fact that the device is already bound to a driver (but the driver + * information that is delivered through uevents is best-effort, it may + * become obsolete as soon as it is generated anyways). Unbinding is more + * risky as driver pointer is transitioning to NULL, so READ_ONCE() should + * be used to make sure we are dealing with the same pointer, and to + * ensure that driver structure is not going to disappear from under us + * we take bus' drivers klist lock. The assumption that only registered + * driver can be bound to a device, and to unregister a driver bus code + * will take the same lock. + */ +static void dev_driver_uevent(const struct device *dev, struct kobj_uevent_env *env) +{ + struct subsys_private *sp = bus_to_subsys(dev->bus); + + if (sp) { + scoped_guard(spinlock, &sp->klist_drivers.k_lock) { + struct device_driver *drv = READ_ONCE(dev->driver); + if (drv) + add_uevent_var(env, "DRIVER=%s", drv->name); + } + + subsys_put(sp); + } +} + static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) { const struct device *dev = kobj_to_dev(kobj); @@ -2655,8 +2684,8 @@ static int dev_uevent(const struct kobje if (dev->type && dev->type->name) add_uevent_var(env, "DEVTYPE=%s", dev->type->name);
- if (dev->driver) - add_uevent_var(env, "DRIVER=%s", dev->driver->name); + /* Add "DRIVER=%s" variable if the device is bound to a driver */ + dev_driver_uevent(dev, env);
/* Add common DT information about the device */ of_device_uevent(dev, env);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann daniel@iogearbox.net
commit 4c2227656d9003f4d77afc76f34dd81b95e4c2c4 upstream.
vmxnet3 driver's XDP handling is buggy for packet sizes using ring0 (that is, packet sizes between 128 - 3k bytes).
We noticed MTU-related connectivity issues with Cilium's service load- balancing in case of vmxnet3 as NIC underneath. A simple curl to a HTTP backend service where the XDP LB was doing IPIP encap led to overly large packet sizes but only for *some* of the packets (e.g. HTTP GET request) while others (e.g. the prior TCP 3WHS) looked completely fine on the wire.
In fact, the pcap recording on the backend node actually revealed that the node with the XDP LB was leaking uninitialized kernel data onto the wire for the affected packets, for example, while the packets should have been 152 bytes their actual size was 1482 bytes, so the remainder after 152 bytes was padded with whatever other data was in that page at the time (e.g. we saw user/payload data from prior processed packets).
We only noticed this through an MTU issue, e.g. when the XDP LB node and the backend node both had the same MTU (e.g. 1500) then the curl request got dropped on the backend node's NIC given the packet was too large even though the IPIP-encapped packet normally would never even come close to the MTU limit. Lowering the MTU on the XDP LB (e.g. 1480) allowed to let the curl request succeed (which also indicates that the kernel ignored the padding, and thus the issue wasn't very user-visible).
Commit e127ce7699c1 ("vmxnet3: Fix missing reserved tailroom") was too eager to also switch xdp_prepare_buff() from rcd->len to rbi->len. It really needs to stick to rcd->len which is the actual packet length from the descriptor. The latter we also feed into vmxnet3_process_xdp_small(), by the way, and it indicates the correct length needed to initialize the xdp->{data,data_end} parts. For e127ce7699c1 ("vmxnet3: Fix missing reserved tailroom") the relevant part was adapting xdp_init_buff() to address the warning given the xdp_data_hard_end() depends on xdp->frame_sz. With that fixed, traffic on the wire looks good again.
Fixes: e127ce7699c1 ("vmxnet3: Fix missing reserved tailroom") Signed-off-by: Daniel Borkmann daniel@iogearbox.net Tested-by: Andrew Sauber andrew.sauber@isovalent.com Cc: Anton Protopopov aspsk@isovalent.com Cc: William Tu witu@nvidia.com Cc: Martin Zaharinov micron10@gmail.com Cc: Ronak Doshi ronak.doshi@broadcom.com Reviewed-by: Simon Horman horms@kernel.org Link: https://patch.msgid.link/20250423133600.176689-1-daniel@iogearbox.net Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/vmxnet3/vmxnet3_xdp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/vmxnet3/vmxnet3_xdp.c +++ b/drivers/net/vmxnet3/vmxnet3_xdp.c @@ -397,7 +397,7 @@ vmxnet3_process_xdp(struct vmxnet3_adapt
xdp_init_buff(&xdp, PAGE_SIZE, &rq->xdp_rxq); xdp_prepare_buff(&xdp, page_address(page), rq->page_pool->p.offset, - rbi->len, false); + rcd->len, false); xdp_buff_clear_frags_flag(&xdp);
xdp_prog = rcu_dereference(rq->adapter->xdp_bpf_prog);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott abbotti@mev.co.uk
commit 44d9b3f584c59a606b521e7274e658d5b866c699 upstream.
When `jr3_pci_detach()` is called during device removal, it calls `timer_delete_sync()` to stop the timer, but the timer expiry function always reschedules the timer, so the synchronization is ineffective.
Call `timer_shutdown_sync()` instead. It does not matter that the timer expiry function pointer is cleared, because the device is being removed.
Fixes: 07b509e6584a5 ("Staging: comedi: add jr3_pci driver") Cc: stable stable@kernel.org Signed-off-by: Ian Abbott abbotti@mev.co.uk Link: https://lore.kernel.org/r/20250415123901.13483-1-abbotti@mev.co.uk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/comedi/drivers/jr3_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/comedi/drivers/jr3_pci.c +++ b/drivers/comedi/drivers/jr3_pci.c @@ -758,7 +758,7 @@ static void jr3_pci_detach(struct comedi struct jr3_pci_dev_private *devpriv = dev->private;
if (devpriv) - del_timer_sync(&devpriv->timer); + timer_shutdown_sync(&devpriv->timer);
comedi_pci_detach(dev); }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu herbert@gondor.apana.org.au
commit 17ec3e71ba797cdb62164fea9532c81b60f47167 upstream.
The ARCH_MAY_HAVE patch missed arm64, mips and s390. But it may also lead to arch options being enabled but ineffective because of modular/built-in conflicts.
As the primary user of all these options wireguard is selecting the arch options anyway, make the same selections at the lib/crypto option level and hide the arch options from the user.
Instead of selecting them centrally from lib/crypto, simply set the default of each arch option as suggested by Eric Biggers.
Change the Crypto API generic algorithms to select the top-level lib/crypto options instead of the generic one as otherwise there is no way to enable the arch options (Eric Biggers). Introduce a set of INTERNAL options to work around dependency cycles on the CONFIG_CRYPTO symbol.
Fixes: 1047e21aecdf ("crypto: lib/Kconfig - Fix lib built-in failure when arch is modular") Reported-by: kernel test robot lkp@intel.com Reported-by: Arnd Bergmann arnd@kernel.org Closes: https://lore.kernel.org/oe-kbuild-all/202502232152.JC84YDLp-lkp@intel.com/ Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/arm/crypto/Kconfig | 16 ++++++++++------ arch/arm64/crypto/Kconfig | 6 ++++-- arch/mips/crypto/Kconfig | 7 +++++-- arch/powerpc/crypto/Kconfig | 11 +++++++---- arch/riscv/crypto/Kconfig | 1 - arch/s390/crypto/Kconfig | 3 ++- arch/x86/crypto/Kconfig | 17 +++++++++++------ crypto/Kconfig | 6 +++--- lib/crypto/Kconfig | 41 +++++++++++++++++++++-------------------- 9 files changed, 63 insertions(+), 45 deletions(-)
--- a/arch/arm/crypto/Kconfig +++ b/arch/arm/crypto/Kconfig @@ -3,10 +3,12 @@ menu "Accelerated Cryptographic Algorithms for CPU (arm)"
config CRYPTO_CURVE25519_NEON - tristate "Public key crypto: Curve25519 (NEON)" + tristate depends on KERNEL_MODE_NEON + select CRYPTO_KPP select CRYPTO_LIB_CURVE25519_GENERIC - select CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 + select CRYPTO_ARCH_HAVE_LIB_CURVE25519 + default CRYPTO_LIB_CURVE25519_INTERNAL help Curve25519 algorithm
@@ -45,9 +47,10 @@ config CRYPTO_NHPOLY1305_NEON - NEON (Advanced SIMD) extensions
config CRYPTO_POLY1305_ARM - tristate "Hash functions: Poly1305 (NEON)" + tristate select CRYPTO_HASH - select CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305 + select CRYPTO_ARCH_HAVE_LIB_POLY1305 + default CRYPTO_LIB_POLY1305_INTERNAL help Poly1305 authenticator algorithm (RFC7539)
@@ -212,9 +215,10 @@ config CRYPTO_AES_ARM_CE - ARMv8 Crypto Extensions
config CRYPTO_CHACHA20_NEON - tristate "Ciphers: ChaCha20, XChaCha20, XChaCha12 (NEON)" + tristate select CRYPTO_SKCIPHER - select CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA + select CRYPTO_ARCH_HAVE_LIB_CHACHA + default CRYPTO_LIB_CHACHA_INTERNAL help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms --- a/arch/arm64/crypto/Kconfig +++ b/arch/arm64/crypto/Kconfig @@ -26,10 +26,11 @@ config CRYPTO_NHPOLY1305_NEON - NEON (Advanced SIMD) extensions
config CRYPTO_POLY1305_NEON - tristate "Hash functions: Poly1305 (NEON)" + tristate depends on KERNEL_MODE_NEON select CRYPTO_HASH select CRYPTO_ARCH_HAVE_LIB_POLY1305 + default CRYPTO_LIB_POLY1305_INTERNAL help Poly1305 authenticator algorithm (RFC7539)
@@ -186,11 +187,12 @@ config CRYPTO_AES_ARM64_NEON_BLK - NEON (Advanced SIMD) extensions
config CRYPTO_CHACHA20_NEON - tristate "Ciphers: ChaCha (NEON)" + tristate depends on KERNEL_MODE_NEON select CRYPTO_SKCIPHER select CRYPTO_LIB_CHACHA_GENERIC select CRYPTO_ARCH_HAVE_LIB_CHACHA + default CRYPTO_LIB_CHACHA_INTERNAL help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms --- a/arch/mips/crypto/Kconfig +++ b/arch/mips/crypto/Kconfig @@ -3,9 +3,11 @@ menu "Accelerated Cryptographic Algorithms for CPU (mips)"
config CRYPTO_POLY1305_MIPS - tristate "Hash functions: Poly1305" + tristate depends on MIPS + select CRYPTO_HASH select CRYPTO_ARCH_HAVE_LIB_POLY1305 + default CRYPTO_LIB_POLY1305_INTERNAL help Poly1305 authenticator algorithm (RFC7539)
@@ -52,10 +54,11 @@ config CRYPTO_SHA512_OCTEON Architecture: mips OCTEON using crypto instructions, when available
config CRYPTO_CHACHA_MIPS - tristate "Ciphers: ChaCha20, XChaCha20, XChaCha12 (MIPS32r2)" + tristate depends on CPU_MIPS32_R2 select CRYPTO_SKCIPHER select CRYPTO_ARCH_HAVE_LIB_CHACHA + default CRYPTO_LIB_CHACHA_INTERNAL help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms --- a/arch/powerpc/crypto/Kconfig +++ b/arch/powerpc/crypto/Kconfig @@ -3,10 +3,12 @@ menu "Accelerated Cryptographic Algorithms for CPU (powerpc)"
config CRYPTO_CURVE25519_PPC64 - tristate "Public key crypto: Curve25519 (PowerPC64)" + tristate depends on PPC64 && CPU_LITTLE_ENDIAN + select CRYPTO_KPP select CRYPTO_LIB_CURVE25519_GENERIC - select CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 + select CRYPTO_ARCH_HAVE_LIB_CURVE25519 + default CRYPTO_LIB_CURVE25519_INTERNAL help Curve25519 algorithm
@@ -91,11 +93,12 @@ config CRYPTO_AES_GCM_P10 later CPU. This module supports stitched acceleration for AES/GCM.
config CRYPTO_CHACHA20_P10 - tristate "Ciphers: ChaCha20, XChacha20, XChacha12 (P10 or later)" + tristate depends on PPC64 && CPU_LITTLE_ENDIAN && VSX select CRYPTO_SKCIPHER select CRYPTO_LIB_CHACHA_GENERIC - select CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA + select CRYPTO_ARCH_HAVE_LIB_CHACHA + default CRYPTO_LIB_CHACHA_INTERNAL help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms --- a/arch/riscv/crypto/Kconfig +++ b/arch/riscv/crypto/Kconfig @@ -22,7 +22,6 @@ config CRYPTO_CHACHA_RISCV64 tristate "Ciphers: ChaCha" depends on 64BIT && RISCV_ISA_V && TOOLCHAIN_HAS_VECTOR_CRYPTO select CRYPTO_SKCIPHER - select CRYPTO_LIB_CHACHA_GENERIC help Length-preserving ciphers: ChaCha20 stream cipher algorithm
--- a/arch/s390/crypto/Kconfig +++ b/arch/s390/crypto/Kconfig @@ -108,11 +108,12 @@ config CRYPTO_DES_S390 As of z196 the CTR mode is hardware accelerated.
config CRYPTO_CHACHA_S390 - tristate "Ciphers: ChaCha20" + tristate depends on S390 select CRYPTO_SKCIPHER select CRYPTO_LIB_CHACHA_GENERIC select CRYPTO_ARCH_HAVE_LIB_CHACHA + default CRYPTO_LIB_CHACHA_INTERNAL help Length-preserving cipher: ChaCha20 stream cipher (RFC 7539)
--- a/arch/x86/crypto/Kconfig +++ b/arch/x86/crypto/Kconfig @@ -3,10 +3,12 @@ menu "Accelerated Cryptographic Algorithms for CPU (x86)"
config CRYPTO_CURVE25519_X86 - tristate "Public key crypto: Curve25519 (ADX)" + tristate depends on X86 && 64BIT + select CRYPTO_KPP select CRYPTO_LIB_CURVE25519_GENERIC - select CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 + select CRYPTO_ARCH_HAVE_LIB_CURVE25519 + default CRYPTO_LIB_CURVE25519_INTERNAL help Curve25519 algorithm
@@ -348,11 +350,12 @@ config CRYPTO_ARIA_GFNI_AVX512_X86_64 Processes 64 blocks in parallel.
config CRYPTO_CHACHA20_X86_64 - tristate "Ciphers: ChaCha20, XChaCha20, XChaCha12 (SSSE3/AVX2/AVX-512VL)" + tristate depends on X86 && 64BIT select CRYPTO_SKCIPHER select CRYPTO_LIB_CHACHA_GENERIC - select CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA + select CRYPTO_ARCH_HAVE_LIB_CHACHA + default CRYPTO_LIB_CHACHA_INTERNAL help Length-preserving ciphers: ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms @@ -417,10 +420,12 @@ config CRYPTO_POLYVAL_CLMUL_NI - CLMUL-NI (carry-less multiplication new instructions)
config CRYPTO_POLY1305_X86_64 - tristate "Hash functions: Poly1305 (SSE2/AVX2)" + tristate depends on X86 && 64BIT + select CRYPTO_HASH select CRYPTO_LIB_POLY1305_GENERIC - select CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305 + select CRYPTO_ARCH_HAVE_LIB_POLY1305 + default CRYPTO_LIB_POLY1305_INTERNAL help Poly1305 authenticator algorithm (RFC7539)
--- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -317,7 +317,7 @@ config CRYPTO_ECRDSA config CRYPTO_CURVE25519 tristate "Curve25519" select CRYPTO_KPP - select CRYPTO_LIB_CURVE25519_GENERIC + select CRYPTO_LIB_CURVE25519_INTERNAL help Curve25519 elliptic curve (RFC7748)
@@ -615,7 +615,7 @@ config CRYPTO_ARC4
config CRYPTO_CHACHA20 tristate "ChaCha" - select CRYPTO_LIB_CHACHA_GENERIC + select CRYPTO_LIB_CHACHA_INTERNAL select CRYPTO_SKCIPHER help The ChaCha20, XChaCha20, and XChaCha12 stream cipher algorithms @@ -936,7 +936,7 @@ config CRYPTO_POLYVAL config CRYPTO_POLY1305 tristate "Poly1305" select CRYPTO_HASH - select CRYPTO_LIB_POLY1305_GENERIC + select CRYPTO_LIB_POLY1305_INTERNAL help Poly1305 authenticator algorithm (RFC7539)
--- a/lib/crypto/Kconfig +++ b/lib/crypto/Kconfig @@ -48,11 +48,6 @@ config CRYPTO_ARCH_HAVE_LIB_CHACHA accelerated implementation of the ChaCha library interface, either builtin or as a module.
-config CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA - tristate - select CRYPTO_ARCH_HAVE_LIB_CHACHA if CRYPTO_LIB_CHACHA=m - select CRYPTO_ARCH_HAVE_LIB_CHACHA if CRYPTO_ARCH_MAY_HAVE_LIB_CHACHA=y - config CRYPTO_LIB_CHACHA_GENERIC tristate select CRYPTO_LIB_UTILS @@ -63,9 +58,14 @@ config CRYPTO_LIB_CHACHA_GENERIC implementation is enabled, this implementation serves the users of CRYPTO_LIB_CHACHA.
+config CRYPTO_LIB_CHACHA_INTERNAL + tristate + select CRYPTO_LIB_CHACHA_GENERIC if CRYPTO_ARCH_HAVE_LIB_CHACHA=n + config CRYPTO_LIB_CHACHA tristate "ChaCha library interface" - select CRYPTO_LIB_CHACHA_GENERIC if CRYPTO_ARCH_HAVE_LIB_CHACHA=n + select CRYPTO + select CRYPTO_LIB_CHACHA_INTERNAL help Enable the ChaCha library interface. This interface may be fulfilled by either the generic implementation or an arch-specific one, if one @@ -78,13 +78,9 @@ config CRYPTO_ARCH_HAVE_LIB_CURVE25519 accelerated implementation of the Curve25519 library interface, either builtin or as a module.
-config CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519 - tristate - select CRYPTO_ARCH_HAVE_LIB_CURVE25519 if CRYPTO_LIB_CURVE25519=m - select CRYPTO_ARCH_HAVE_LIB_CURVE25519 if CRYPTO_ARCH_MAY_HAVE_LIB_CURVE25519=y - config CRYPTO_LIB_CURVE25519_GENERIC tristate + select CRYPTO_LIB_UTILS help This symbol can be depended upon by arch implementations of the Curve25519 library interface that require the generic code as a @@ -92,10 +88,14 @@ config CRYPTO_LIB_CURVE25519_GENERIC implementation is enabled, this implementation serves the users of CRYPTO_LIB_CURVE25519.
+config CRYPTO_LIB_CURVE25519_INTERNAL + tristate + select CRYPTO_LIB_CURVE25519_GENERIC if CRYPTO_ARCH_HAVE_LIB_CURVE25519=n + config CRYPTO_LIB_CURVE25519 tristate "Curve25519 scalar multiplication library" - select CRYPTO_LIB_CURVE25519_GENERIC if CRYPTO_ARCH_HAVE_LIB_CURVE25519=n - select CRYPTO_LIB_UTILS + select CRYPTO + select CRYPTO_LIB_CURVE25519_INTERNAL help Enable the Curve25519 library interface. This interface may be fulfilled by either the generic implementation or an arch-specific @@ -118,11 +118,6 @@ config CRYPTO_ARCH_HAVE_LIB_POLY1305 accelerated implementation of the Poly1305 library interface, either builtin or as a module.
-config CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305 - tristate - select CRYPTO_ARCH_HAVE_LIB_POLY1305 if CRYPTO_LIB_POLY1305=m - select CRYPTO_ARCH_HAVE_LIB_POLY1305 if CRYPTO_ARCH_MAY_HAVE_LIB_POLY1305=y - config CRYPTO_LIB_POLY1305_GENERIC tristate help @@ -132,9 +127,14 @@ config CRYPTO_LIB_POLY1305_GENERIC implementation is enabled, this implementation serves the users of CRYPTO_LIB_POLY1305.
+config CRYPTO_LIB_POLY1305_INTERNAL + tristate + select CRYPTO_LIB_POLY1305_GENERIC if CRYPTO_ARCH_HAVE_LIB_POLY1305=n + config CRYPTO_LIB_POLY1305 tristate "Poly1305 library interface" - select CRYPTO_LIB_POLY1305_GENERIC if CRYPTO_ARCH_HAVE_LIB_POLY1305=n + select CRYPTO + select CRYPTO_LIB_POLY1305_INTERNAL help Enable the Poly1305 library interface. This interface may be fulfilled by either the generic implementation or an arch-specific one, if one @@ -142,9 +142,10 @@ config CRYPTO_LIB_POLY1305
config CRYPTO_LIB_CHACHA20POLY1305 tristate "ChaCha20-Poly1305 AEAD support (8-byte nonce library version)" - depends on CRYPTO + select CRYPTO select CRYPTO_LIB_CHACHA select CRYPTO_LIB_POLY1305 + select CRYPTO_LIB_UTILS select CRYPTO_ALGAPI
config CRYPTO_LIB_SHA1
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter dan.carpenter@linaro.org
commit 38985a25682c66d1a7599b0e95ceeb9c7ba89f84 upstream.
You can't pass uninitialized "ret" variables to cci_write(). It has to start as zero.
Fixes: 4f0aeba4f155 ("media: i2c: imx214: Convert to CCI register access helpers") Signed-off-by: Dan Carpenter dan.carpenter@linaro.org Reviewed-by: André Apitzsch git@apitzsch.eu Signed-off-by: Sakari Ailus sakari.ailus@linux.intel.com Signed-off-by: Hans Verkuil hverkuil@xs4all.nl Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/media/i2c/imx214.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/media/i2c/imx214.c +++ b/drivers/media/i2c/imx214.c @@ -840,7 +840,7 @@ static int imx214_s_stream(struct v4l2_s { struct imx214 *imx214 = to_imx214(subdev); struct v4l2_subdev_state *state; - int ret; + int ret = 0;
if (enable) { ret = pm_runtime_resume_and_get(imx214->dev);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Bogendoerfer tsbogend@alpha.franken.de
commit b73c3ccdca95c237750c981054997c71d33e09d7 upstream.
Commit e27fbe16af5c ("MIPS: cm: Detect CM quirks from device tree") introduced
arch/mips/include/asm/mips-cm.h:119:13: error: ‘mips_cm_update_property’ defined but not used [-Werror=unused-function]
Fix this by making empty function implementation inline
Fixes: e27fbe16af5c ("MIPS: cm: Detect CM quirks from device tree") Signed-off-by: Thomas Bogendoerfer tsbogend@alpha.franken.de Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- arch/mips/include/asm/mips-cm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/mips/include/asm/mips-cm.h +++ b/arch/mips/include/asm/mips-cm.h @@ -116,7 +116,7 @@ static inline bool mips_cm_present(void) #ifdef CONFIG_MIPS_CM extern void mips_cm_update_property(void); #else -static void mips_cm_update_property(void) {} +static inline void mips_cm_update_property(void) {} #endif
/**
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dimitri Fedrau dimitri.fedrau@liebherr.com
commit 8fa649fd7d3009769c7289d0c31c319b72bc42c4 upstream.
When CONFIG_OF_MDIO is not defined the index for selecting the transmit amplitude voltage for 100BASE-TX is set to 0, but it should be -1, if there is no need to modify the transmit amplitude voltage. Move initialization of the index from dp83822_of_init to dp8382x_probe.
Fixes: 4f3735e82d8a ("net: phy: dp83822: Add support for changing the transmit amplitude voltage") Reviewed-by: Gerhard Engleder gerhard@engleder-embedded.com Signed-off-by: Dimitri Fedrau dimitri.fedrau@liebherr.com Link: https://patch.msgid.link/20250317-dp83822-fix-transceiver-mdio-v2-1-fb094540... Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/net/phy/dp83822.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/phy/dp83822.c +++ b/drivers/net/phy/dp83822.c @@ -833,7 +833,6 @@ static int dp83822_of_init(struct phy_de dp83822->set_gpio2_clk_out = true; }
- dp83822->tx_amplitude_100base_tx_index = -1; ret = phy_get_tx_amplitude_gain(phydev, dev, ETHTOOL_LINK_MODE_100baseT_Full_BIT, &val); @@ -931,6 +930,7 @@ static int dp8382x_probe(struct phy_devi if (!dp83822) return -ENOMEM;
+ dp83822->tx_amplitude_100base_tx_index = -1; phydev->priv = dp83822;
return 0;
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda ojeda@kernel.org
commit 2c8725c1dca3de043670b38592b1b43105322496 upstream.
`rustdoc` only recognizes `--remap-path-prefix` starting with Rust 1.81.0, which is later than on minimum, so we cannot pass it unconditionally. Otherwise, we get:
error: Unrecognized option: 'remap-path-prefix'
Note that `rustc` (the compiler) does recognize the flag since a long time ago (1.26.0).
Moreover, `rustdoc` since Rust 1.82.0 ICEs in out-of-tree builds when using `--remap-path-prefix`. The issue has been reduced and reported upstream [1].
Thus workaround both issues by simply skipping the flag when generating the docs -- it is not critical there anyway.
The ICE does not reproduce under `--test`, but we still need to skip the flag as well for `RUSTDOC TK` since it is not recognized.
Fixes: dbdffaf50ff9 ("kbuild, rust: use -fremap-path-prefix to make paths relative") Link: https://github.com/rust-lang/rust/issues/138520 [1] Signed-off-by: Miguel Ojeda ojeda@kernel.org Reviewed-by: Tamir Duberstein tamird@gmail.com Signed-off-by: Masahiro Yamada masahiroy@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- rust/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
--- a/rust/Makefile +++ b/rust/Makefile @@ -57,10 +57,14 @@ endif core-cfgs = \ --cfg no_fp_fmt_parse
+# `rustc` recognizes `--remap-path-prefix` since 1.26.0, but `rustdoc` only +# since Rust 1.81.0. Moreover, `rustdoc` ICEs on out-of-tree builds since Rust +# 1.82.0 (https://github.com/rust-lang/rust/issues/138520). Thus workaround both +# issues skipping the flag. The former also applies to `RUSTDOC TK`. quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< cmd_rustdoc = \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) $(filter-out $(skip_flags),$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ + $(RUSTDOC) $(filter-out $(skip_flags) --remap-path-prefix=%,$(if $(rustdoc_host),$(rust_common_flags),$(rust_flags))) \ $(rustc_target_flags) -L$(objtree)/$(obj) \ -Zunstable-options --generate-link-to-definition \ --output $(rustdoc_output) \ @@ -171,7 +175,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC rm -rf $(objtree)/$(obj)/test/doctests/kernel; \ mkdir -p $(objtree)/$(obj)/test/doctests/kernel; \ OBJTREE=$(abspath $(objtree)) \ - $(RUSTDOC) --test $(rust_flags) \ + $(RUSTDOC) --test $(filter-out --remap-path-prefix=%,$(rust_flags)) \ -L$(objtree)/$(obj) --extern ffi --extern kernel \ --extern build_error --extern macros \ --extern bindings --extern uapi \
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Lei ming.lei@redhat.com
commit 18461f2a02be04f8bbbe3b37fecfc702e3fa5bc2 upstream.
ubq->canceling is set with request queue quiesced when io_uring context is exiting. USER_RECOVERY or !RECOVERY_FAIL_IO requires request to be re-queued and re-dispatch after device is recovered.
However commit d796cea7b9f3 ("ublk: implement ->queue_rqs()") still may fail any request in case of ubq->canceling, this way breaks USER_RECOVERY or !RECOVERY_FAIL_IO.
Fix it by calling __ublk_abort_rq() in case of ubq->canceling.
Reviewed-by: Uday Shankar ushankar@purestorage.com Reported-by: Uday Shankar ushankar@purestorage.com Closes: https://lore.kernel.org/linux-block/Z%2FQkkTRHfRxtN%2FmB@dev-ushankar.dev.pu... Fixes: d796cea7b9f3 ("ublk: implement ->queue_rqs()") Signed-off-by: Ming Lei ming.lei@redhat.com Link: https://lore.kernel.org/r/20250409011444.2142010-3-ming.lei@redhat.com Signed-off-by: Jens Axboe axboe@kernel.dk Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/block/ublk_drv.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
--- a/drivers/block/ublk_drv.c +++ b/drivers/block/ublk_drv.c @@ -1336,7 +1336,8 @@ static enum blk_eh_timer_return ublk_tim return BLK_EH_RESET_TIMER; }
-static blk_status_t ublk_prep_req(struct ublk_queue *ubq, struct request *rq) +static blk_status_t ublk_prep_req(struct ublk_queue *ubq, struct request *rq, + bool check_cancel) { blk_status_t res;
@@ -1355,7 +1356,7 @@ static blk_status_t ublk_prep_req(struct if (ublk_nosrv_should_queue_io(ubq) && unlikely(ubq->force_abort)) return BLK_STS_IOERR;
- if (unlikely(ubq->canceling)) + if (check_cancel && unlikely(ubq->canceling)) return BLK_STS_IOERR;
/* fill iod to slot in io cmd buffer */ @@ -1374,7 +1375,7 @@ static blk_status_t ublk_queue_rq(struct struct request *rq = bd->rq; blk_status_t res;
- res = ublk_prep_req(ubq, rq); + res = ublk_prep_req(ubq, rq, false); if (res != BLK_STS_OK) return res;
@@ -1406,7 +1407,7 @@ static void ublk_queue_rqs(struct rq_lis ublk_queue_cmd_list(ubq, &submit_list); ubq = this_q;
- if (ublk_prep_req(ubq, req) == BLK_STS_OK) + if (ublk_prep_req(ubq, req, true) == BLK_STS_OK) rq_list_add_tail(&submit_list, req); else rq_list_add_tail(&requeue_list, req);
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hannes Reinecke hare@kernel.org
commit 26d7fb4fd4ca1180e2fa96587dea544563b4962a upstream.
Commit 62baf70c3274 caused the ANA log page to be re-read, even on controllers that do not support ANA. While this should generally harmless, some controllers hang on the unsupported log page and never finish probing.
Fixes: 62baf70c3274 ("nvme: re-read ANA log page after ns scan completes") Signed-off-by: Hannes Reinecke hare@kernel.org Tested-by: Srikanth Aithal sraithal@amd.com [hch: more detailed commit message] Signed-off-by: Christoph Hellwig hch@lst.de Reviewed-by: Sagi Grimberg sagi@grimberg.me Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/nvme/host/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -4297,7 +4297,7 @@ static void nvme_scan_work(struct work_s if (test_bit(NVME_AER_NOTICE_NS_CHANGED, &ctrl->events)) nvme_queue_scan(ctrl); #ifdef CONFIG_NVME_MULTIPATH - else + else if (ctrl->ana_log_buf) /* Re-read the ANA log page to not miss updates */ queue_work(nvme_wq, &ctrl->ana_work); #endif
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michal Pecio michal.pecio@gmail.com
commit 9e3a28793d2fde7a709e814d2504652eaba6ae98 upstream.
A Short Packet event before the last TRB of a TD is followed by another event on the final TRB on spec-compliant HCs, which is most of them.
A 'last_td_was_short' flag was added to know if a TD has just completed as Short Packet and another event is to come. The flag was cleared after seeing the event (unless no TDs are pending, but that's a separate bug) or seeing a new TD complete as something other than Short Packet.
A rework replaced the flag with an 'old_trb_comp_code' variable. When an event doesn't match the pending TD and the previous event was Short Packet, the new event is silently ignored.
To preserve old behavior, 'old_trb_comp_code' should be cleared at this point, but instead it is being set to current comp code, which is often Short Packet again. This can cause more events to be silently ignored, even though they are no longer connected with the old TD that completed short and indicate a serious problem with the driver or the xHC.
Common device classes like UAC in async mode, UVC, serial or the UAS status pipe complete as Short Packet routinely and could be affected.
Clear 'old_trb_comp_code' to zero, which is an invalid completion code and the same value the variable starts with. This restores original behavior on Short Packet and also works for illegal Etron events, which the code has been extended to cover too.
Fixes: b331a3d8097f ("xhci: Handle spurious events on Etron host isoc enpoints") Signed-off-by: Michal Pecio michal.pecio@gmail.com Signed-off-by: Mathias Nyman mathias.nyman@linux.intel.com Link: https://lore.kernel.org/r/20250410151828.2868740-4-mathias.nyman@linux.intel... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/usb/host/xhci-ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c @@ -2926,7 +2926,7 @@ static int handle_tx_event(struct xhci_h if (xhci_spurious_success_tx_event(xhci, ep_ring)) { xhci_dbg(xhci, "Spurious event dma %pad, comp_code %u after %u\n", &ep_trb_dma, trb_comp_code, ep_ring->old_trb_comp_code); - ep_ring->old_trb_comp_code = trb_comp_code; + ep_ring->old_trb_comp_code = 0; return 0; }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
commit 0d7597749f5a3ac67851d3836635d084df15fb66 upstream.
When KCOV or GCOV is enabled, dead code can be left behind, in which case objtool silences unreachable and undefined behavior (fallthrough) warnings.
Fallthrough warnings, and their variant "end of section" warnings, were silenced with the following commit:
6b023c784204 ("objtool: Silence more KCOV warnings")
Another variant of a fallthrough warning is a jump to the end of a function. If that function happens to be at the end of a section, the jump destination doesn't actually exist.
Normally that would be a fatal objtool error, but for KCOV/GCOV it's just another undefined behavior fallthrough. Silence it like the others.
Fixes the following warning:
drivers/iommu/dma-iommu.o: warning: objtool: iommu_dma_sw_msi+0x92: can't find jump dest instruction at .text+0x54d5
Fixes: 6b023c784204 ("objtool: Silence more KCOV warnings") Reported-by: Randy Dunlap rdunlap@infradead.org Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/08fbe7d7e1e20612206f1df253077b94f178d93e.174348153... Closes: https://lore.kernel.org/314f8809-cd59-479b-97d7-49356bf1c8d1@infradead.org/ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- tools/objtool/check.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-)
--- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -1482,6 +1482,8 @@ static int add_jump_destinations(struct unsigned long dest_off;
for_each_insn(file, insn) { + struct symbol *func = insn_func(insn); + if (insn->jump_dest) { /* * handle_group_alt() may have previously set @@ -1505,7 +1507,7 @@ static int add_jump_destinations(struct } else if (reloc->sym->return_thunk) { add_return_call(file, insn, true); continue; - } else if (insn_func(insn)) { + } else if (func) { /* * External sibling call or internal sibling call with * STT_FUNC reloc. @@ -1538,6 +1540,15 @@ static int add_jump_destinations(struct continue; }
+ /* + * GCOV/KCOV dead code can jump to the end of the + * function/section. + */ + if (file->ignore_unreachables && func && + dest_sec == insn->sec && + dest_off == func->offset + func->len) + continue; + WARN_INSN(insn, "can't find jump dest instruction at %s+0x%lx", dest_sec->name, dest_off); return -1; @@ -1562,8 +1573,7 @@ static int add_jump_destinations(struct /* * Cross-function jump. */ - if (insn_func(insn) && insn_func(jump_dest) && - insn_func(insn) != insn_func(jump_dest)) { + if (func && insn_func(jump_dest) && func != insn_func(jump_dest)) {
/* * For GCC 8+, create parent/child links for any cold @@ -1580,10 +1590,10 @@ static int add_jump_destinations(struct * case where the parent function's only reference to a * subfunction is through a jump table. */ - if (!strstr(insn_func(insn)->name, ".cold") && + if (!strstr(func->name, ".cold") && strstr(insn_func(jump_dest)->name, ".cold")) { - insn_func(insn)->cfunc = insn_func(jump_dest); - insn_func(jump_dest)->pfunc = insn_func(insn); + func->cfunc = insn_func(jump_dest); + insn_func(jump_dest)->pfunc = func; } }
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf jpoimboe@kernel.org
commit 55c78035a1a8dfb05f1472018ce2a651701adb7d upstream.
Similar to GCOV, KCOV can leave behind dead code and undefined behavior. Warnings related to those should be ignored.
The previous commit:
6b023c784204 ("objtool: Silence more KCOV warnings")
... only did so for CONFIG_CGOV_KERNEL. Also do it for CONFIG_KCOV, but for real this time.
Fixes the following warning:
vmlinux.o: warning: objtool: synaptics_report_mt_data: unexpected end of section .text.synaptics_report_mt_data
Fixes: 6b023c784204 ("objtool: Silence more KCOV warnings") Reported-by: kernel test robot lkp@intel.com Signed-off-by: Josh Poimboeuf jpoimboe@kernel.org Signed-off-by: Ingo Molnar mingo@kernel.org Cc: Linus Torvalds torvalds@linux-foundation.org Link: https://lore.kernel.org/r/a44ba16e194bcbc52c1cef3d3cd9051a62622723.174348153... Closes: https://lore.kernel.org/oe-kbuild-all/202503282236.UhfRsF3B-lkp@intel.com/ Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- scripts/Makefile.lib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
--- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -275,7 +275,7 @@ objtool-args-$(CONFIG_MITIGATION_SLS) objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess -objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable +objtool-args-$(or $(CONFIG_GCOV_KERNEL),$(CONFIG_KCOV)) += --no-unreachable objtool-args-$(CONFIG_PREFIX_SYMBOLS) += --prefix=$(CONFIG_FUNCTION_PADDING_BYTES)
objtool-args = $(objtool-args-y) \
6.14-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu herbert@gondor.apana.org.au
commit 98330b9a61506de7df0d1725122111909c157864 upstream.
Select the generic LIB options if the Crypto API algorithm is enabled. Otherwise this may lead to a build failure as the Crypto API algorithm always uses the generic implementation.
Fixes: 17ec3e71ba79 ("crypto: lib/Kconfig - Hide arch options from user") Reported-by: kernel test robot lkp@intel.com Closes: https://lore.kernel.org/oe-kbuild-all/202503022113.79uEtUuy-lkp@intel.com/ Closes: https://lore.kernel.org/oe-kbuild-all/202503022115.9OOyDR5A-lkp@intel.com/ Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- crypto/Kconfig | 3 +++ 1 file changed, 3 insertions(+)
--- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -317,6 +317,7 @@ config CRYPTO_ECRDSA config CRYPTO_CURVE25519 tristate "Curve25519" select CRYPTO_KPP + select CRYPTO_LIB_CURVE25519_GENERIC select CRYPTO_LIB_CURVE25519_INTERNAL help Curve25519 elliptic curve (RFC7748) @@ -615,6 +616,7 @@ config CRYPTO_ARC4
config CRYPTO_CHACHA20 tristate "ChaCha" + select CRYPTO_LIB_CHACHA_GENERIC select CRYPTO_LIB_CHACHA_INTERNAL select CRYPTO_SKCIPHER help @@ -936,6 +938,7 @@ config CRYPTO_POLYVAL config CRYPTO_POLY1305 tristate "Poly1305" select CRYPTO_HASH + select CRYPTO_LIB_POLY1305_GENERIC select CRYPTO_LIB_POLY1305_INTERNAL help Poly1305 authenticator algorithm (RFC7539)
Hi Greg
no regressions here on x86_64 (RKL, Intel 11th Gen. CPU)
Thanks
Tested-by: Ronald Warsow rwarsow@gmx.de
The kernel, bpf tool and perf tool builds fine for v6.14.5-rc1 on x86 and arm64 Azure VM. Kernel binary size for x86 build: text data bss dec hex filename 31679632 14224334 6311936 52215902 31cc05e vmlinux Kernel binary size for arm64 build: text data bss dec hex filename 36856310 15166805 1048656 53071771 329cf9b vmlinux Tested-by: Hardik Garg hargar@linux.microsoft.com Thanks, Hardik
Hi!
This is the start of the stable review cycle for the 6.14.5 release. There are 311 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.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6...
6.12 and 6.6 pass our testing, too:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6... https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-6...
I'm still retrying 5.4 and 5.15.
Tested-by: Pavel Machek (CIP) pavel@denx.de
Best regards, Pavel
Hi Greg
On Wed, Apr 30, 2025 at 1:55 AM Greg Kroah-Hartman gregkh@linuxfoundation.org wrote:
This is the start of the stable review cycle for the 6.14.5 release. There are 311 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Thu, 01 May 2025 16:10:15 +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.14.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.14.y and the diffstat can be found below.
thanks,
greg k-h
6.14.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.14.5-rc1rv-g25b40e24731f (takeshi@ThinkPadX1Gen10J0764) (gcc (GCC) 14.2.1 20250207, GNU ld (GNU Binutils) 2.44) #1 SMP PREEMPT_DYNAMIC Wed Apr 30 10:38:19 JST 2025
Thanks
Tested-by: Takeshi Ogasawara takeshi.ogasawara@futuring-girl.com
On Tue, Apr 29, 2025 at 06:37:17PM +0200, Greg Kroah-Hartman wrote:
This is the start of the stable review cycle for the 6.14.5 release. There are 311 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.
test_progs, test_progs-no_alu32, test_progs-cpuv4, test_maps, test_verifier in BPF selftests all passes (with 82303a059aab cherry-picked from bpf tree to deal with sockmap_ktls failure, it will be sent to stable once it made its way to Linus' tree).
Link: https://github.com/shunghsiyu/libbpf/actions/runs/14738691393/job/4137110092... Tested-by: Shung-Hsi Yu shung-hsi.yu@suse.com
...
Am 29.04.2025 um 18:37 schrieb Greg Kroah-Hartman:
This is the start of the stable review cycle for the 6.14.5 release. There are 311 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.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Tested-by: Peter Schneider pschneider1968@googlemail.com
Beste Grüße, Peter Schneider
linux-stable-mirror@lists.linaro.org