]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 16 Jun 2026 05:25:46 +0000 (10:55 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 16 Jun 2026 05:25:46 +0000 (10:55 +0530)
added patches:
alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch
bluetooth-init-sk_peer_-on-bt_sock_alloc.patch
bluetooth-serialize-accept_q-access.patch
btrfs-fix-btrfs_ioctl_space_info-slot_count-toctou-which-can-lead-to-info-leak.patch
btrfs-fix-double-free-in-create_space_info_sub_group-error-path.patch
btrfs-fix-missing-last_unlink_trans-update-when-removing-a-directory.patch
btrfs-remove-fs_info-argument-from-btrfs_sysfs_add_space_info_type.patch
ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch
cgroup-cpuset-reset-dl-migration-state-on-can_attach-failure.patch
crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch
crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
crypto-nx-migrate-to-scomp-api.patch
erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
f2fs-fix-false-alarm-of-lockdep-on-cp_global_sem-lock.patch
f2fs-fix-incorrect-file-address-mapping-when-inline-inode-is-unwritten.patch
fbcon-avoid-oob-font-access-if-console-rotation-fails.patch
genetlink-use-internal-flags-for-multicast-groups.patch
hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch
hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch
hv_netvsc-use-kmap_local_page-in-netvsc_copy_to_send_buf.patch
ice-fix-vf-queue-configuration-with-low-mtu-values.patch
iio-adc-fix-the-return-value-handle-for-platform_get_irq.patch
iio-adc-npcm-convert-to-platform-remove-callback-returning-void.patch
iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch
mm-hugetlb-rename-folio_putback_active_hugetlb-to-folio_putback_hugetlb.patch
mm-hugetlb-rename-isolate_hugetlb-to-folio_isolate_hugetlb.patch
mm-hugetlb_cma-round-up-per_node-before-logging-it.patch
mm-memory-failure-fix-hugetlb_lock-aa-deadlock-in-get_huge_page_for_hwpoison.patch
mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch
mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
mm-migrate-don-t-call-folio_putback_active_hugetlb-on-dst-hugetlb-folio.patch
mptcp-do-not-drop-partial-packets.patch
mptcp-fastclose-msk-when-linger-time-is-0.patch
mptcp-pm-add_addr-rtx-allow-id-0.patch
mptcp-pm-add_addr-rtx-fix-potential-data-race.patch
mptcp-pm-add_addr-rtx-resched-blocked-add_addr-quicker.patch
mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch
mptcp-pm-kernel-correctly-retransmit-add_addr-id-0.patch
mptcp-pm-prio-skip-closed-subflows.patch
mptcp-reset-rcv-wnd-on-disconnect.patch
mtd-spi-nor-core-fix-implicit-declaration-warning.patch
mtd-spi-nor-debugfs-fix-out-of-bounds-read-in-spi_nor_params_show.patch
net-hsr-defer-node-table-free-until-after-rcu-readers.patch
net-ipv4-stop-checking-crypto_ahash_alignmask.patch
net-ipv6-stop-checking-crypto_ahash_alignmask.patch
net-stmmac-avoid-shadowing-global-buf_sz.patch
net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch
net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch
net-wwan-t7xx-validate-port_count-against-message-length-in-t7xx_port_enum_msg_handler.patch
netfilter-nft_fib-fix-stale-stack-leak-via-the-oifname-register.patch
octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch
octeontx2-af-replace-deprecated-strncpy-with-strscpy.patch
octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch
phy-tegra-xusb-disable-trk-clk-when-not-in-use.patch
phy-tegra-xusb-fix-per-pad-high-speed-termination-calibration.patch
platform-x86-intel-vsec-add-private-data-for-per-device-data.patch
platform-x86-intel-vsec-create-wrapper-to-walk-pci-config-space.patch
platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch
platform-x86-intel-vsec-make-driver_data-info-const.patch
pmdomain-core-fix-detach-procedure-for-virtual-devices-in-genpd.patch
printk-add-print_hex_dump_devel.patch
rdma-move-dma-block-iterator-logic-into-dedicated-files.patch
rdma-umem-fix-kernel-doc-warnings.patch
rdma-umem-fix-truncation-for-block-sizes-4g.patch
scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch
selftests-mptcp-drop-nanoseconds-width-specifier.patch
serial-qcom-geni-fix-uart_rx_par_en-bit-position.patch
serial-samsung_tty-use-port-lock-wrappers.patch
smb-client-require-net-admin-for-cifs-swn-netlink.patch
smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
smb-client-validate-dacloffset-before-building-dacl-pointers.patch
spi-convert-to-spi_controller_half_duplex.patch
spi-lantiq-ssc-fix-controller-deregistration.patch
spi-microchip-core-qspi-convert-to-platform-remove-callback-returning-void.patch
spi-microchip-core-qspi-fix-controller-deregistration.patch
spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch
spi-qup-fix-error-pointer-deref-after-dma-setup-failure.patch
spi-qup-switch-to-use-modern-name.patch
spi-s3c64xx-fix-null-deref-on-driver-unbind.patch
spi-s3c64xx-use-devm_clk_get_enabled.patch
spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch
spi-spi-ti-qspi-switch-to-use-modern-name.patch
spi-spi-zynq-do-not-check-for-0-return-after-calling-platform_get_irq.patch
spi-st-ssc4-fix-controller-deregistration.patch
spi-st-ssc4-switch-to-use-modern-name.patch
spi-sun4i-convert-to-platform-remove-callback-returning-void.patch
spi-sun4i-fix-controller-deregistration.patch
spi-sun4i-switch-to-use-modern-name.patch
spi-sun6i-fix-controller-deregistration.patch
spi-syncuacer-fix-controller-deregistration.patch
spi-synquacer-convert-to-platform-remove-callback-returning-void.patch
spi-synquacer-switch-to-use-modern-name.patch
spi-tegra114-fix-controller-deregistration.patch
spi-tegra20-sflash-fix-controller-deregistration.patch
spi-ti-qspi-fix-controller-deregistration.patch
spi-topcliff-pch-convert-to-platform-remove-callback-returning-void.patch
spi-uniphier-convert-to-platform-remove-callback-returning-void.patch
spi-uniphier-fix-controller-deregistration.patch
spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch
spi-uniphier-switch-to-use-modern-name.patch
spi-zynq-qspi-convert-to-platform-remove-callback-returning-void.patch
spi-zynq-qspi-fix-controller-deregistration.patch
spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch
spi-zynq-qspi-switch-to-use-modern-name.patch
thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch
tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
tracing-probes-limit-size-of-event-probe-to-3k.patch
tty-serial-qcom-geni-serial-align-define-values.patch
tty-serial-qcom-geni-serial-remove-unused-symbols.patch
tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch
tty-serial-samsung-use-u32-for-register-interactions.patch
udf-fix-partition-descriptor-append-bookkeeping.patch
usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch
usb-dwc3-move-guid-programming-after-phy-initialization.patch
usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch
usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch
usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch
usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch
usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch
usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch
wifi-brcmfmac-fix-potential-use-after-free-issue-when-stopping-watchdog-task.patch
wifi-mac80211-remove-station-if-connection-prep-fails.patch
xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch
xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch
xfs-fix-a-resource-leak-in-xfs_alloc_buftarg.patch

134 files changed:
queue-6.1/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch [new file with mode: 0644]
queue-6.1/arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch [new file with mode: 0644]
queue-6.1/bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch [new file with mode: 0644]
queue-6.1/bluetooth-init-sk_peer_-on-bt_sock_alloc.patch [new file with mode: 0644]
queue-6.1/bluetooth-serialize-accept_q-access.patch [new file with mode: 0644]
queue-6.1/btrfs-fix-btrfs_ioctl_space_info-slot_count-toctou-which-can-lead-to-info-leak.patch [new file with mode: 0644]
queue-6.1/btrfs-fix-double-free-in-create_space_info_sub_group-error-path.patch [new file with mode: 0644]
queue-6.1/btrfs-fix-missing-last_unlink_trans-update-when-removing-a-directory.patch [new file with mode: 0644]
queue-6.1/btrfs-remove-fs_info-argument-from-btrfs_sysfs_add_space_info_type.patch [new file with mode: 0644]
queue-6.1/ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch [new file with mode: 0644]
queue-6.1/cgroup-cpuset-reset-dl-migration-state-on-can_attach-failure.patch [new file with mode: 0644]
queue-6.1/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch [new file with mode: 0644]
queue-6.1/crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch [new file with mode: 0644]
queue-6.1/crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch [new file with mode: 0644]
queue-6.1/crypto-nx-migrate-to-scomp-api.patch [new file with mode: 0644]
queue-6.1/erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch [new file with mode: 0644]
queue-6.1/f2fs-fix-false-alarm-of-lockdep-on-cp_global_sem-lock.patch [new file with mode: 0644]
queue-6.1/f2fs-fix-incorrect-file-address-mapping-when-inline-inode-is-unwritten.patch [new file with mode: 0644]
queue-6.1/fbcon-avoid-oob-font-access-if-console-rotation-fails.patch [new file with mode: 0644]
queue-6.1/genetlink-use-internal-flags-for-multicast-groups.patch [new file with mode: 0644]
queue-6.1/hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch [new file with mode: 0644]
queue-6.1/hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch [new file with mode: 0644]
queue-6.1/hv_netvsc-use-kmap_local_page-in-netvsc_copy_to_send_buf.patch [new file with mode: 0644]
queue-6.1/ice-fix-vf-queue-configuration-with-low-mtu-values.patch [new file with mode: 0644]
queue-6.1/iio-adc-fix-the-return-value-handle-for-platform_get_irq.patch [new file with mode: 0644]
queue-6.1/iio-adc-npcm-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch [new file with mode: 0644]
queue-6.1/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch [new file with mode: 0644]
queue-6.1/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch [new file with mode: 0644]
queue-6.1/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch [new file with mode: 0644]
queue-6.1/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch [new file with mode: 0644]
queue-6.1/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch [new file with mode: 0644]
queue-6.1/mm-hugetlb-rename-folio_putback_active_hugetlb-to-folio_putback_hugetlb.patch [new file with mode: 0644]
queue-6.1/mm-hugetlb-rename-isolate_hugetlb-to-folio_isolate_hugetlb.patch [new file with mode: 0644]
queue-6.1/mm-hugetlb_cma-round-up-per_node-before-logging-it.patch [new file with mode: 0644]
queue-6.1/mm-memory-failure-fix-hugetlb_lock-aa-deadlock-in-get_huge_page_for_hwpoison.patch [new file with mode: 0644]
queue-6.1/mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch [new file with mode: 0644]
queue-6.1/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch [new file with mode: 0644]
queue-6.1/mm-migrate-don-t-call-folio_putback_active_hugetlb-on-dst-hugetlb-folio.patch [new file with mode: 0644]
queue-6.1/mptcp-do-not-drop-partial-packets.patch [new file with mode: 0644]
queue-6.1/mptcp-fastclose-msk-when-linger-time-is-0.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-add_addr-rtx-allow-id-0.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-add_addr-rtx-fix-potential-data-race.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-add_addr-rtx-resched-blocked-add_addr-quicker.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-kernel-correctly-retransmit-add_addr-id-0.patch [new file with mode: 0644]
queue-6.1/mptcp-pm-prio-skip-closed-subflows.patch [new file with mode: 0644]
queue-6.1/mptcp-reset-rcv-wnd-on-disconnect.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-core-fix-implicit-declaration-warning.patch [new file with mode: 0644]
queue-6.1/mtd-spi-nor-debugfs-fix-out-of-bounds-read-in-spi_nor_params_show.patch [new file with mode: 0644]
queue-6.1/net-hsr-defer-node-table-free-until-after-rcu-readers.patch [new file with mode: 0644]
queue-6.1/net-ipv4-stop-checking-crypto_ahash_alignmask.patch [new file with mode: 0644]
queue-6.1/net-ipv6-stop-checking-crypto_ahash_alignmask.patch [new file with mode: 0644]
queue-6.1/net-stmmac-avoid-shadowing-global-buf_sz.patch [new file with mode: 0644]
queue-6.1/net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch [new file with mode: 0644]
queue-6.1/net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch [new file with mode: 0644]
queue-6.1/net-wwan-t7xx-validate-port_count-against-message-length-in-t7xx_port_enum_msg_handler.patch [new file with mode: 0644]
queue-6.1/netfilter-nft_fib-fix-stale-stack-leak-via-the-oifname-register.patch [new file with mode: 0644]
queue-6.1/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch [new file with mode: 0644]
queue-6.1/octeontx2-af-replace-deprecated-strncpy-with-strscpy.patch [new file with mode: 0644]
queue-6.1/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch [new file with mode: 0644]
queue-6.1/phy-tegra-xusb-disable-trk-clk-when-not-in-use.patch [new file with mode: 0644]
queue-6.1/phy-tegra-xusb-fix-per-pad-high-speed-termination-calibration.patch [new file with mode: 0644]
queue-6.1/platform-x86-intel-vsec-add-private-data-for-per-device-data.patch [new file with mode: 0644]
queue-6.1/platform-x86-intel-vsec-create-wrapper-to-walk-pci-config-space.patch [new file with mode: 0644]
queue-6.1/platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch [new file with mode: 0644]
queue-6.1/platform-x86-intel-vsec-make-driver_data-info-const.patch [new file with mode: 0644]
queue-6.1/pmdomain-core-fix-detach-procedure-for-virtual-devices-in-genpd.patch [new file with mode: 0644]
queue-6.1/printk-add-print_hex_dump_devel.patch [new file with mode: 0644]
queue-6.1/rdma-move-dma-block-iterator-logic-into-dedicated-files.patch [new file with mode: 0644]
queue-6.1/rdma-umem-fix-kernel-doc-warnings.patch [new file with mode: 0644]
queue-6.1/rdma-umem-fix-truncation-for-block-sizes-4g.patch [new file with mode: 0644]
queue-6.1/scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch [new file with mode: 0644]
queue-6.1/selftests-mptcp-drop-nanoseconds-width-specifier.patch [new file with mode: 0644]
queue-6.1/serial-qcom-geni-fix-uart_rx_par_en-bit-position.patch [new file with mode: 0644]
queue-6.1/serial-samsung_tty-use-port-lock-wrappers.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/smb-client-require-net-admin-for-cifs-swn-netlink.patch [new file with mode: 0644]
queue-6.1/smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch [new file with mode: 0644]
queue-6.1/smb-client-validate-dacloffset-before-building-dacl-pointers.patch [new file with mode: 0644]
queue-6.1/spi-convert-to-spi_controller_half_duplex.patch [new file with mode: 0644]
queue-6.1/spi-lantiq-ssc-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-microchip-core-qspi-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/spi-microchip-core-qspi-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.1/spi-qup-fix-error-pointer-deref-after-dma-setup-failure.patch [new file with mode: 0644]
queue-6.1/spi-qup-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.1/spi-s3c64xx-fix-null-deref-on-driver-unbind.patch [new file with mode: 0644]
queue-6.1/spi-s3c64xx-use-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.1/spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/spi-spi-ti-qspi-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.1/spi-spi-zynq-do-not-check-for-0-return-after-calling-platform_get_irq.patch [new file with mode: 0644]
queue-6.1/spi-st-ssc4-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-st-ssc4-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.1/spi-sun4i-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/spi-sun4i-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-sun4i-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.1/spi-sun6i-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-syncuacer-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-synquacer-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/spi-synquacer-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.1/spi-tegra114-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-tegra20-sflash-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-ti-qspi-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-topcliff-pch-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/spi-uniphier-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/spi-uniphier-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.1/spi-uniphier-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.1/spi-zynq-qspi-convert-to-platform-remove-callback-returning-void.patch [new file with mode: 0644]
queue-6.1/spi-zynq-qspi-fix-controller-deregistration.patch [new file with mode: 0644]
queue-6.1/spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch [new file with mode: 0644]
queue-6.1/spi-zynq-qspi-switch-to-use-modern-name.patch [new file with mode: 0644]
queue-6.1/thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch [new file with mode: 0644]
queue-6.1/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch [new file with mode: 0644]
queue-6.1/tracing-probes-limit-size-of-event-probe-to-3k.patch [new file with mode: 0644]
queue-6.1/tty-serial-qcom-geni-serial-align-define-values.patch [new file with mode: 0644]
queue-6.1/tty-serial-qcom-geni-serial-remove-unused-symbols.patch [new file with mode: 0644]
queue-6.1/tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch [new file with mode: 0644]
queue-6.1/tty-serial-samsung-use-u32-for-register-interactions.patch [new file with mode: 0644]
queue-6.1/udf-fix-partition-descriptor-append-bookkeeping.patch [new file with mode: 0644]
queue-6.1/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch [new file with mode: 0644]
queue-6.1/usb-dwc3-move-guid-programming-after-phy-initialization.patch [new file with mode: 0644]
queue-6.1/usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch [new file with mode: 0644]
queue-6.1/usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch [new file with mode: 0644]
queue-6.1/usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch [new file with mode: 0644]
queue-6.1/usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch [new file with mode: 0644]
queue-6.1/usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch [new file with mode: 0644]
queue-6.1/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch [new file with mode: 0644]
queue-6.1/wifi-brcmfmac-fix-potential-use-after-free-issue-when-stopping-watchdog-task.patch [new file with mode: 0644]
queue-6.1/wifi-mac80211-remove-station-if-connection-prep-fails.patch [new file with mode: 0644]
queue-6.1/xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch [new file with mode: 0644]
queue-6.1/xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch [new file with mode: 0644]
queue-6.1/xfs-fix-a-resource-leak-in-xfs_alloc_buftarg.patch [new file with mode: 0644]

diff --git a/queue-6.1/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch b/queue-6.1/alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
new file mode 100644 (file)
index 0000000..961d83f
--- /dev/null
@@ -0,0 +1,74 @@
+From stable+bounces-260690-greg=kroah.com@vger.kernel.org Fri Jun  5 18:39:23 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 09:00:33 -0400
+Subject: ALSA: firewire-motu: Protect register DSP event queue positions
+To: stable@vger.kernel.org
+Cc: "Cássio Gabriel" <cassiogabrielcontato@gmail.com>, "Takashi Sakamoto" <o-takashi@sakamocchi.jp>, "Takashi Iwai" <tiwai@suse.de>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260605130033.370944-1-sashal@kernel.org>
+
+From: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+
+[ Upstream commit 98fb1c1bb11e29eb609b7200a25e136e05aa4498 ]
+
+The register DSP event queue is updated under parser->lock, but
+snd_motu_register_dsp_message_parser_count_event() reads pull_pos and
+push_pos without the lock.
+snd_motu_register_dsp_message_parser_copy_event() also reads both queue
+positions before taking the lock.
+
+Protect these accesses with parser->lock as well. This keeps the hwdep
+poll/read path consistent with the producer side and with the cached
+meter/parameter accessors.
+
+Fixes: 634ec0b2906e ("ALSA: firewire-motu: notify event for parameter change in register DSP model")
+Cc: stable@vger.kernel.org
+Signed-off-by: Cássio Gabriel <cassiogabrielcontato@gmail.com>
+Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Link: https://patch.msgid.link/20260521-alsa-firewire-motu-event-locking-v1-1-708e1c2b5e56@gmail.com
+[ converted copy_event() from manual spin_lock_irqsave/spin_unlock_irqrestore to guard(spinlock_irqsave) ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ sound/firewire/motu/motu-register-dsp-message-parser.c |   14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/sound/firewire/motu/motu-register-dsp-message-parser.c
++++ b/sound/firewire/motu/motu-register-dsp-message-parser.c
+@@ -390,6 +390,8 @@ unsigned int snd_motu_register_dsp_messa
+ {
+       struct msg_parser *parser = motu->message_parser;
++      guard(spinlock_irqsave)(&parser->lock);
++
+       if (parser->pull_pos > parser->push_pos)
+               return EVENT_QUEUE_SIZE - parser->pull_pos + parser->push_pos;
+       else
+@@ -399,14 +401,14 @@ unsigned int snd_motu_register_dsp_messa
+ bool snd_motu_register_dsp_message_parser_copy_event(struct snd_motu *motu, u32 *event)
+ {
+       struct msg_parser *parser = motu->message_parser;
+-      unsigned int pos = parser->pull_pos;
+-      unsigned long flags;
++      unsigned int pos;
+-      if (pos == parser->push_pos)
+-              return false;
++      guard(spinlock_irqsave)(&parser->lock);
+-      spin_lock_irqsave(&parser->lock, flags);
++      if (parser->pull_pos == parser->push_pos)
++              return false;
++      pos = parser->pull_pos;
+       *event = parser->event_queue[pos];
+       ++pos;
+@@ -414,7 +416,5 @@ bool snd_motu_register_dsp_message_parse
+               pos = 0;
+       parser->pull_pos = pos;
+-      spin_unlock_irqrestore(&parser->lock, flags);
+-
+       return true;
+ }
diff --git a/queue-6.1/arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch b/queue-6.1/arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
new file mode 100644 (file)
index 0000000..ae45021
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-259404-greg=kroah.com@vger.kernel.org Mon Jun  1 06:41:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 May 2026 21:11:52 -0400
+Subject: arm64: tlb: Flush walk cache when unsharing PMD tables
+To: stable@vger.kernel.org
+Cc: Zeng Heng <zengheng4@huawei.com>, Catalin Marinas <catalin.marinas@arm.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601011152.135244-1-sashal@kernel.org>
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit c2ff4764e03e7a8d758352f4aceb8fe1be6ac971 ]
+
+When huge_pmd_unshare() is called to unshare a PMD table, the
+tlb_unshare_pmd_ptdesc() function sets tlb->unshared_tables=true
+but the aarch64 tlb_flush() only checked tlb->freed_tables to
+determine whether to use TLBF_NONE (vae1is, invalidates walk
+cache) or TLBF_NOWALKCACHE (vale1is, leaf-only).
+
+This caused the stale PMD page table entry to remain in the walk cache
+after unshare, potentially leading to incorrect page table walks.
+
+Fix by including unshared_tables in the check, so that when
+unsharing tables, TLBF_NONE is used and the walk cache is properly
+invalidated.
+
+Here is the detailed distinction between vae1is and vale1is:
+
+| Instruction Combination  | Actual Invalidation Scope                         |
+| ------------------------ | --------------------------------------------------|
+| `VAE1IS`  + TTL=`0`      | All entries at all levels (full invalidation)     |
+| `VAE1IS`  + TTL=`2` (L2) | Non-leaf at Level 0/1 + leaf at Level 2           |
+| `VALE1IS` + TTL=`0`      | Leaf entries at all levels (non-leaf not cleared) |
+| `VALE1IS` + TTL=`2` (L2) | Leaf entry at Level 2 only                        |
+
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Fixes: 8ce720d5bd91 ("mm/hugetlb: fix excessive IPI broadcasts when unsharing PMD tables using mmu_gather")
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/include/asm/tlb.h |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/include/asm/tlb.h
++++ b/arch/arm64/include/asm/tlb.h
+@@ -53,7 +53,7 @@ static inline int tlb_get_level(struct m
+ static inline void tlb_flush(struct mmu_gather *tlb)
+ {
+       struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0);
+-      bool last_level = !tlb->freed_tables;
++      bool last_level = !(tlb->freed_tables || tlb->unshared_tables);
+       unsigned long stride = tlb_get_unmap_size(tlb);
+       int tlb_level = tlb_get_level(tlb);
diff --git a/queue-6.1/bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch b/queue-6.1/bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch
new file mode 100644 (file)
index 0000000..006ecf8
--- /dev/null
@@ -0,0 +1,155 @@
+From stable+bounces-256790-greg=kroah.com@vger.kernel.org Sat May 30 03:13:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 17:42:32 -0400
+Subject: Bluetooth: hci_qca: Convert timeout from jiffies to ms
+To: stable@vger.kernel.org
+Cc: Shuai Zhang <shuai.zhang@oss.qualcomm.com>, Paul Menzel <pmenzel@molgen.mpg.de>, Bartosz Golaszewski <bartosz.golaszewski@linaro.org>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529214232.1794166-1-sashal@kernel.org>
+
+From: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
+
+[ Upstream commit 375ba7484132662a4a8c7547d088fb6275c00282 ]
+
+Since the timer uses jiffies as its unit rather than ms, the timeout value
+must be converted from ms to jiffies when configuring the timer. Otherwise,
+the intended 8s timeout is incorrectly set to approximately 33s.
+
+To improve readability, embed msecs_to_jiffies() directly in the macro
+definitions and drop the _MS suffix from macros that now yield jiffies
+values: MEMDUMP_TIMEOUT, FW_DOWNLOAD_TIMEOUT, IBS_DISABLE_SSR_TIMEOUT,
+CMD_TRANS_TIMEOUT, and IBS_BTSOC_TX_IDLE_TIMEOUT.
+
+IBS_WAKE_RETRANS_TIMEOUT_MS and IBS_HOST_TX_IDLE_TIMEOUT_MS are
+intentionally left unchanged. Their values are stored in the struct fields
+wake_retrans and tx_idle_delay, which hold ms values at runtime and can be
+modified via debugfs. The msecs_to_jiffies() conversion happens at each
+call site against the field value, so it cannot be embedded in the macro.
+
+Wake timer depends on commit c347ca17d62a
+
+Cc: stable@vger.kernel.org
+Fixes: d841502c79e3 ("Bluetooth: hci_qca: Collect controller memory dump during SSR")
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Acked-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Signed-off-by: Shuai Zhang <shuai.zhang@oss.qualcomm.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+[ adapted to `vmalloc`-based memdump path and older `qca_serdev_shutdown(struct device *dev)` signature ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bluetooth/hci_qca.c |   33 ++++++++++++++++-----------------
+ 1 file changed, 16 insertions(+), 17 deletions(-)
+
+--- a/drivers/bluetooth/hci_qca.c
++++ b/drivers/bluetooth/hci_qca.c
+@@ -46,13 +46,12 @@
+ #define HCI_MAX_IBS_SIZE      10
+ #define IBS_WAKE_RETRANS_TIMEOUT_MS   100
+-#define IBS_BTSOC_TX_IDLE_TIMEOUT_MS  200
++#define IBS_BTSOC_TX_IDLE_TIMEOUT     msecs_to_jiffies(200)
+ #define IBS_HOST_TX_IDLE_TIMEOUT_MS   2000
+-#define CMD_TRANS_TIMEOUT_MS          100
+-#define MEMDUMP_TIMEOUT_MS            8000
+-#define IBS_DISABLE_SSR_TIMEOUT_MS \
+-      (MEMDUMP_TIMEOUT_MS + FW_DOWNLOAD_TIMEOUT_MS)
+-#define FW_DOWNLOAD_TIMEOUT_MS                3000
++#define CMD_TRANS_TIMEOUT             msecs_to_jiffies(100)
++#define MEMDUMP_TIMEOUT                       msecs_to_jiffies(8000)
++#define FW_DOWNLOAD_TIMEOUT           msecs_to_jiffies(3000)
++#define IBS_DISABLE_SSR_TIMEOUT               (MEMDUMP_TIMEOUT + FW_DOWNLOAD_TIMEOUT)
+ /* susclk rate */
+ #define SUSCLK_RATE_32KHZ     32768
+@@ -1059,7 +1058,7 @@ static void qca_controller_memdump(struc
+                                   dump_size);
+                       queue_delayed_work(qca->workqueue,
+                                          &qca->ctrl_memdump_timeout,
+-                                         msecs_to_jiffies(MEMDUMP_TIMEOUT_MS)
++                                         MEMDUMP_TIMEOUT
+                                         );
+                       skb_pull(skb, sizeof(dump_size));
+@@ -1327,7 +1326,7 @@ static int qca_set_baudrate(struct hci_d
+       if (hu->serdev)
+               serdev_device_wait_until_sent(hu->serdev,
+-                    msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
++                    CMD_TRANS_TIMEOUT);
+       /* Give the controller time to process the request */
+       switch (qca_soc_type(hu)) {
+@@ -1358,8 +1357,8 @@ static inline void host_set_baudrate(str
+ static int qca_send_power_pulse(struct hci_uart *hu, bool on)
+ {
++      int timeout = CMD_TRANS_TIMEOUT;
+       int ret;
+-      int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
+       u8 cmd = on ? QCA_WCN3990_POWERON_PULSE : QCA_WCN3990_POWEROFF_PULSE;
+       /* These power pulses are single byte command which are sent
+@@ -1561,7 +1560,7 @@ static void qca_wait_for_dump_collection
+       struct qca_data *qca = hu->priv;
+       wait_on_bit_timeout(&qca->flags, QCA_MEMDUMP_COLLECTION,
+-                          TASK_UNINTERRUPTIBLE, MEMDUMP_TIMEOUT_MS);
++                          TASK_UNINTERRUPTIBLE, MEMDUMP_TIMEOUT);
+       clear_bit(QCA_MEMDUMP_COLLECTION, &qca->flags);
+ }
+@@ -2390,7 +2389,7 @@ static void qca_serdev_remove(struct ser
+ static void qca_serdev_shutdown(struct device *dev)
+ {
+       int ret;
+-      int timeout = msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS);
++      int timeout = CMD_TRANS_TIMEOUT;
+       struct serdev_device *serdev = to_serdev_device(dev);
+       struct qca_serdev *qcadev = serdev_device_get_drvdata(serdev);
+       struct hci_uart *hu = &qcadev->serdev_hu;
+@@ -2448,7 +2447,7 @@ static int __maybe_unused qca_suspend(st
+       bool tx_pending = false;
+       int ret = 0;
+       u8 cmd;
+-      u32 wait_timeout = 0;
++      unsigned long wait_timeout = 0;
+       set_bit(QCA_SUSPENDING, &qca->flags);
+@@ -2469,15 +2468,15 @@ static int __maybe_unused qca_suspend(st
+       if (test_bit(QCA_IBS_DISABLED, &qca->flags) ||
+           test_bit(QCA_SSR_TRIGGERED, &qca->flags)) {
+               wait_timeout = test_bit(QCA_SSR_TRIGGERED, &qca->flags) ?
+-                                      IBS_DISABLE_SSR_TIMEOUT_MS :
+-                                      FW_DOWNLOAD_TIMEOUT_MS;
++                                      IBS_DISABLE_SSR_TIMEOUT :
++                                      FW_DOWNLOAD_TIMEOUT;
+               /* QCA_IBS_DISABLED flag is set to true, During FW download
+                * and during memory dump collection. It is reset to false,
+                * After FW download complete.
+                */
+               wait_on_bit_timeout(&qca->flags, QCA_IBS_DISABLED,
+-                          TASK_UNINTERRUPTIBLE, msecs_to_jiffies(wait_timeout));
++                          TASK_UNINTERRUPTIBLE, wait_timeout);
+               if (test_bit(QCA_IBS_DISABLED, &qca->flags)) {
+                       bt_dev_err(hu->hdev, "SSR or FW download time out");
+@@ -2529,7 +2528,7 @@ static int __maybe_unused qca_suspend(st
+       if (tx_pending) {
+               serdev_device_wait_until_sent(hu->serdev,
+-                                            msecs_to_jiffies(CMD_TRANS_TIMEOUT_MS));
++                                            CMD_TRANS_TIMEOUT);
+               serial_clock_vote(HCI_IBS_TX_VOTE_CLOCK_OFF, hu);
+       }
+@@ -2538,7 +2537,7 @@ static int __maybe_unused qca_suspend(st
+        */
+       ret = wait_event_interruptible_timeout(qca->suspend_wait_q,
+                       qca->rx_ibs_state == HCI_IBS_RX_ASLEEP,
+-                      msecs_to_jiffies(IBS_BTSOC_TX_IDLE_TIMEOUT_MS));
++                      IBS_BTSOC_TX_IDLE_TIMEOUT);
+       if (ret == 0) {
+               ret = -ETIMEDOUT;
+               goto error;
diff --git a/queue-6.1/bluetooth-init-sk_peer_-on-bt_sock_alloc.patch b/queue-6.1/bluetooth-init-sk_peer_-on-bt_sock_alloc.patch
new file mode 100644 (file)
index 0000000..3c0b35f
--- /dev/null
@@ -0,0 +1,139 @@
+From stable+bounces-256803-greg=kroah.com@vger.kernel.org Sat May 30 04:52:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 19:21:52 -0400
+Subject: Bluetooth: Init sk_peer_* on bt_sock_alloc
+To: stable@vger.kernel.org
+Cc: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529232154.1873470-1-sashal@kernel.org>
+
+From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+
+[ Upstream commit 464c702fb9374ff8f3f816f24fb7ac719dd20e1e ]
+
+This makes sure peer information is always available via sock when using
+bt_sock_alloc.
+
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: e83f5e24da74 ("Bluetooth: serialize accept_q access")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/bluetooth/af_bluetooth.c |   24 ++++++++++++++++++++++++
+ net/bluetooth/hidp/sock.c    |   10 +---------
+ net/bluetooth/l2cap_sock.c   |   19 -------------------
+ 3 files changed, 25 insertions(+), 28 deletions(-)
+
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -157,6 +157,14 @@ struct sock *bt_sock_alloc(struct net *n
+       sk->sk_protocol = proto;
+       sk->sk_state    = BT_OPEN;
++      /* Init peer information so it can be properly monitored */
++      if (!kern) {
++              spin_lock(&sk->sk_peer_lock);
++              sk->sk_peer_pid  = get_pid(task_tgid(current));
++              sk->sk_peer_cred = get_current_cred();
++              spin_unlock(&sk->sk_peer_lock);
++      }
++
+       return sk;
+ }
+ EXPORT_SYMBOL(bt_sock_alloc);
+@@ -201,6 +209,9 @@ EXPORT_SYMBOL(bt_sock_linked);
+ void bt_accept_enqueue(struct sock *parent, struct sock *sk, bool bh)
+ {
++      const struct cred *old_cred;
++      struct pid *old_pid;
++
+       BT_DBG("parent %p, sk %p", parent, sk);
+       sock_hold(sk);
+@@ -213,6 +224,19 @@ void bt_accept_enqueue(struct sock *pare
+       list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
+       bt_sk(sk)->parent = parent;
++      /* Copy credentials from parent since for incoming connections the
++       * socket is allocated by the kernel.
++       */
++      spin_lock(&sk->sk_peer_lock);
++      old_pid = sk->sk_peer_pid;
++      old_cred = sk->sk_peer_cred;
++      sk->sk_peer_pid = get_pid(parent->sk_peer_pid);
++      sk->sk_peer_cred = get_cred(parent->sk_peer_cred);
++      spin_unlock(&sk->sk_peer_lock);
++
++      put_pid(old_pid);
++      put_cred(old_cred);
++
+       if (bh)
+               bh_unlock_sock(sk);
+       else
+--- a/net/bluetooth/hidp/sock.c
++++ b/net/bluetooth/hidp/sock.c
+@@ -256,21 +256,13 @@ static int hidp_sock_create(struct net *
+       if (sock->type != SOCK_RAW)
+               return -ESOCKTNOSUPPORT;
+-      sk = sk_alloc(net, PF_BLUETOOTH, GFP_ATOMIC, &hidp_proto, kern);
++      sk = bt_sock_alloc(net, sock, &hidp_proto, protocol, GFP_ATOMIC, kern);
+       if (!sk)
+               return -ENOMEM;
+-      sock_init_data(sock, sk);
+-
+       sock->ops = &hidp_sock_ops;
+-
+       sock->state = SS_UNCONNECTED;
+-      sock_reset_flag(sk, SOCK_ZAPPED);
+-
+-      sk->sk_protocol = protocol;
+-      sk->sk_state    = BT_OPEN;
+-
+       bt_sock_link(&hidp_sk_list, sk);
+       return 0;
+--- a/net/bluetooth/l2cap_sock.c
++++ b/net/bluetooth/l2cap_sock.c
+@@ -178,21 +178,6 @@ done:
+       return err;
+ }
+-static void l2cap_sock_init_pid(struct sock *sk)
+-{
+-      struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+-
+-      /* Only L2CAP_MODE_EXT_FLOWCTL ever need to access the PID in order to
+-       * group the channels being requested.
+-       */
+-      if (chan->mode != L2CAP_MODE_EXT_FLOWCTL)
+-              return;
+-
+-      spin_lock(&sk->sk_peer_lock);
+-      sk->sk_peer_pid = get_pid(task_tgid(current));
+-      spin_unlock(&sk->sk_peer_lock);
+-}
+-
+ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr,
+                             int alen, int flags)
+ {
+@@ -268,8 +253,6 @@ static int l2cap_sock_connect(struct soc
+           chan->mode != L2CAP_MODE_EXT_FLOWCTL)
+               chan->mode = L2CAP_MODE_LE_FLOWCTL;
+-      l2cap_sock_init_pid(sk);
+-
+       err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid),
+                                &la.l2_bdaddr, la.l2_bdaddr_type);
+       if (err)
+@@ -325,8 +308,6 @@ static int l2cap_sock_listen(struct sock
+               goto done;
+       }
+-      l2cap_sock_init_pid(sk);
+-
+       sk->sk_max_ack_backlog = backlog;
+       sk->sk_ack_backlog = 0;
diff --git a/queue-6.1/bluetooth-serialize-accept_q-access.patch b/queue-6.1/bluetooth-serialize-accept_q-access.patch
new file mode 100644 (file)
index 0000000..831ce85
--- /dev/null
@@ -0,0 +1,222 @@
+From stable+bounces-256804-greg=kroah.com@vger.kernel.org Sat May 30 04:54:44 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 19:21:53 -0400
+Subject: Bluetooth: serialize accept_q access
+To: stable@vger.kernel.org
+Cc: Jiexun Wang <wangjiexun2025@gmail.com>, Jann Horn <jannh@google.com>, Yuan Tan <yuantan098@gmail.com>, Yifan Wu <yifanwucs@gmail.com>, Juefei Pu <tomapufckgml@gmail.com>, Xin Liu <bird@lzu.edu.cn>, Ren Wei <n05ec@lzu.edu.cn>, Luiz Augusto von Dentz <luiz.von.dentz@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529232154.1873470-2-sashal@kernel.org>
+
+From: Jiexun Wang <wangjiexun2025@gmail.com>
+
+[ Upstream commit e83f5e24da741fa9405aeeff00b08c5ee7c37b88 ]
+
+bt_sock_poll() walks the accept queue without synchronization, while
+child teardown can unlink the same socket and drop its last reference.
+The unsynchronized accept queue walk has existed since the initial
+Bluetooth import.
+
+Protect accept_q with a dedicated lock for queue updates and polling.
+Also rework bt_accept_dequeue() to take temporary child references under
+the queue lock before dropping it and locking the child socket.
+
+Fixes: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Reported-by: Jann Horn <jannh@google.com>
+Reported-by: Yuan Tan <yuantan098@gmail.com>
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Reported-by: Xin Liu <bird@lzu.edu.cn>
+Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: Jiexun Wang <wangjiexun2025@gmail.com>
+Reviewed-by: Jann Horn <jannh@google.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/bluetooth/bluetooth.h |    1 
+ net/bluetooth/af_bluetooth.c      |   87 ++++++++++++++++++++++++++++----------
+ 2 files changed, 66 insertions(+), 22 deletions(-)
+
+--- a/include/net/bluetooth/bluetooth.h
++++ b/include/net/bluetooth/bluetooth.h
+@@ -361,6 +361,7 @@ void baswap(bdaddr_t *dst, const bdaddr_
+ struct bt_sock {
+       struct sock sk;
+       struct list_head accept_q;
++      spinlock_t accept_q_lock; /* protects accept_q */
+       struct sock *parent;
+       unsigned long flags;
+       void (*skb_msg_name)(struct sk_buff *, void *, int *);
+--- a/net/bluetooth/af_bluetooth.c
++++ b/net/bluetooth/af_bluetooth.c
+@@ -151,6 +151,7 @@ struct sock *bt_sock_alloc(struct net *n
+       sock_init_data(sock, sk);
+       INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
++      spin_lock_init(&bt_sk(sk)->accept_q_lock);
+       sock_reset_flag(sk, SOCK_ZAPPED);
+@@ -211,6 +212,7 @@ void bt_accept_enqueue(struct sock *pare
+ {
+       const struct cred *old_cred;
+       struct pid *old_pid;
++      struct bt_sock *par = bt_sk(parent);
+       BT_DBG("parent %p, sk %p", parent, sk);
+@@ -221,9 +223,13 @@ void bt_accept_enqueue(struct sock *pare
+       else
+               lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
+-      list_add_tail(&bt_sk(sk)->accept_q, &bt_sk(parent)->accept_q);
+       bt_sk(sk)->parent = parent;
++      spin_lock_bh(&par->accept_q_lock);
++      list_add_tail(&bt_sk(sk)->accept_q, &par->accept_q);
++      sk_acceptq_added(parent);
++      spin_unlock_bh(&par->accept_q_lock);
++
+       /* Copy credentials from parent since for incoming connections the
+        * socket is allocated by the kernel.
+        */
+@@ -241,8 +247,6 @@ void bt_accept_enqueue(struct sock *pare
+               bh_unlock_sock(sk);
+       else
+               release_sock(sk);
+-
+-      sk_acceptq_added(parent);
+ }
+ EXPORT_SYMBOL(bt_accept_enqueue);
+@@ -251,45 +255,72 @@ EXPORT_SYMBOL(bt_accept_enqueue);
+  */
+ void bt_accept_unlink(struct sock *sk)
+ {
++      struct sock *parent = bt_sk(sk)->parent;
++
+       BT_DBG("sk %p state %d", sk, sk->sk_state);
++      spin_lock_bh(&bt_sk(parent)->accept_q_lock);
+       list_del_init(&bt_sk(sk)->accept_q);
+-      sk_acceptq_removed(bt_sk(sk)->parent);
++      sk_acceptq_removed(parent);
++      spin_unlock_bh(&bt_sk(parent)->accept_q_lock);
+       bt_sk(sk)->parent = NULL;
+       sock_put(sk);
+ }
+ EXPORT_SYMBOL(bt_accept_unlink);
++static struct sock *bt_accept_get(struct sock *parent, struct sock *sk)
++{
++      struct bt_sock *bt = bt_sk(parent);
++      struct sock *next = NULL;
++
++      /* accept_q is modified from child teardown paths too, so take a
++       * temporary reference before dropping the queue lock.
++       */
++      spin_lock_bh(&bt->accept_q_lock);
++
++      if (sk) {
++              if (bt_sk(sk)->parent != parent)
++                      goto out;
++
++              if (!list_is_last(&bt_sk(sk)->accept_q, &bt->accept_q)) {
++                      next = &list_next_entry(bt_sk(sk), accept_q)->sk;
++                      sock_hold(next);
++              }
++      } else if (!list_empty(&bt->accept_q)) {
++              next = &list_first_entry(&bt->accept_q,
++                                       struct bt_sock, accept_q)->sk;
++              sock_hold(next);
++      }
++
++out:
++      spin_unlock_bh(&bt->accept_q_lock);
++      return next;
++}
++
+ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
+ {
+-      struct bt_sock *s, *n;
+-      struct sock *sk;
++      struct sock *sk, *next;
+       BT_DBG("parent %p", parent);
+ restart:
+-      list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
+-              sk = (struct sock *)s;
+-
++      for (sk = bt_accept_get(parent, NULL); sk; sk = next) {
+               /* Prevent early freeing of sk due to unlink and sock_kill */
+-              sock_hold(sk);
+               lock_sock(sk);
+               /* Check sk has not already been unlinked via
+                * bt_accept_unlink() due to serialisation caused by sk locking
+                */
+-              if (!bt_sk(sk)->parent) {
++              if (bt_sk(sk)->parent != parent) {
+                       BT_DBG("sk %p, already unlinked", sk);
+                       release_sock(sk);
+                       sock_put(sk);
+-                      /* Restart the loop as sk is no longer in the list
+-                       * and also avoid a potential infinite loop because
+-                       * list_for_each_entry_safe() is not thread safe.
+-                       */
+                       goto restart;
+               }
++              next = bt_accept_get(parent, sk);
++
+               /* sk is safely in the parent list so reduce reference count */
+               sock_put(sk);
+@@ -317,6 +348,8 @@ restart:
+                       sock_hold(sk);
+                       release_sock(sk);
++                      if (next)
++                              sock_put(next);
+                       return sk;
+               }
+@@ -519,18 +552,28 @@ EXPORT_SYMBOL(bt_sock_stream_recvmsg);
+ static inline __poll_t bt_accept_poll(struct sock *parent)
+ {
+-      struct bt_sock *s, *n;
++      struct bt_sock *bt = bt_sk(parent);
++      struct bt_sock *s;
+       struct sock *sk;
++      __poll_t mask = 0;
++
++      spin_lock_bh(&bt->accept_q_lock);
++      list_for_each_entry(s, &bt->accept_q, accept_q) {
++              int state;
+-      list_for_each_entry_safe(s, n, &bt_sk(parent)->accept_q, accept_q) {
+               sk = (struct sock *)s;
+-              if (sk->sk_state == BT_CONNECTED ||
+-                  (test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags) &&
+-                   sk->sk_state == BT_CONNECT2))
+-                      return EPOLLIN | EPOLLRDNORM;
++              state = READ_ONCE(sk->sk_state);
++
++              if (state == BT_CONNECTED ||
++                  (test_bit(BT_SK_DEFER_SETUP, &bt->flags) &&
++                   state == BT_CONNECT2)) {
++                      mask = EPOLLIN | EPOLLRDNORM;
++                      break;
++              }
+       }
++      spin_unlock_bh(&bt->accept_q_lock);
+-      return 0;
++      return mask;
+ }
+ __poll_t bt_sock_poll(struct file *file, struct socket *sock,
diff --git a/queue-6.1/btrfs-fix-btrfs_ioctl_space_info-slot_count-toctou-which-can-lead-to-info-leak.patch b/queue-6.1/btrfs-fix-btrfs_ioctl_space_info-slot_count-toctou-which-can-lead-to-info-leak.patch
new file mode 100644 (file)
index 0000000..d6e8394
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-247736-greg=kroah.com@vger.kernel.org Fri May 15 18:19:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 08:15:04 -0400
+Subject: btrfs: fix btrfs_ioctl_space_info() slot_count TOCTOU which can lead to info-leak
+To: stable@vger.kernel.org
+Cc: Yochai Eisenrich <yochaie@sweet.security>, Yochai Eisenrich <echelonh@gmail.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515121504.3129260-1-sashal@kernel.org>
+
+From: Yochai Eisenrich <yochaie@sweet.security>
+
+[ Upstream commit 973e57c726c1f8e77259d1c8e519519f1e9aea77 ]
+
+btrfs_ioctl_space_info() has a TOCTOU race between two passes over the
+block group RAID type lists. The first pass counts entries to determine
+the allocation size, then the second pass fills the buffer. The
+groups_sem rwlock is released between passes, allowing concurrent block
+group removal to reduce the entry count.
+
+When the second pass fills fewer entries than the first pass counted,
+copy_to_user() copies the full alloc_size bytes including trailing
+uninitialized kmalloc bytes to userspace.
+
+Fix by copying only total_spaces entries (the actually-filled count from
+the second pass) instead of alloc_size bytes, and switch to kzalloc so
+any future copy size mismatch cannot leak heap data.
+
+Fixes: 7fde62bffb57 ("Btrfs: buffer results in the space_info ioctl")
+CC: stable@vger.kernel.org # 3.0
+Signed-off-by: Yochai Eisenrich <echelonh@gmail.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+[ adapted upstream's `return -EFAULT;` to stable's `ret = -EFAULT;` fall-through to existing `out:` cleanup label ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/ioctl.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3977,7 +3977,7 @@ static long btrfs_ioctl_space_info(struc
+               return -ENOMEM;
+       space_args.total_spaces = 0;
+-      dest = kmalloc(alloc_size, GFP_KERNEL);
++      dest = kzalloc(alloc_size, GFP_KERNEL);
+       if (!dest)
+               return -ENOMEM;
+       dest_orig = dest;
+@@ -4033,7 +4033,8 @@ static long btrfs_ioctl_space_info(struc
+       user_dest = (struct btrfs_ioctl_space_info __user *)
+               (arg + sizeof(struct btrfs_ioctl_space_args));
+-      if (copy_to_user(user_dest, dest_orig, alloc_size))
++      if (copy_to_user(user_dest, dest_orig,
++               space_args.total_spaces * sizeof(*dest_orig)))
+               ret = -EFAULT;
+       kfree(dest_orig);
diff --git a/queue-6.1/btrfs-fix-double-free-in-create_space_info_sub_group-error-path.patch b/queue-6.1/btrfs-fix-double-free-in-create_space_info_sub_group-error-path.patch
new file mode 100644 (file)
index 0000000..3dcb054
--- /dev/null
@@ -0,0 +1,58 @@
+From stable+bounces-247814-greg=kroah.com@vger.kernel.org Fri May 15 20:37:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 11:07:28 -0400
+Subject: btrfs: fix double free in create_space_info_sub_group() error path
+To: stable@vger.kernel.org
+Cc: Guangshuo Li <lgs201920130244@gmail.com>, Qu Wenruo <wqu@suse.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515150728.3262445-2-sashal@kernel.org>
+
+From: Guangshuo Li <lgs201920130244@gmail.com>
+
+[ Upstream commit a7449edf96143f192606ec8647e3167e1ecbd728 ]
+
+When kobject_init_and_add() fails, the call chain is:
+
+create_space_info_sub_group()
+-> btrfs_sysfs_add_space_info_type()
+-> kobject_init_and_add()
+-> failure
+-> kobject_put(&sub_group->kobj)
+-> space_info_release()
+-> kfree(sub_group)
+
+Then control returns to create_space_info_sub_group(), where:
+
+btrfs_sysfs_add_space_info_type() returns error
+-> kfree(sub_group)
+
+Thus, sub_group is freed twice.
+
+Keep parent->sub_group[index] = NULL for the failure path, but after
+btrfs_sysfs_add_space_info_type() has called kobject_put(), let the
+kobject release callback handle the cleanup.
+
+Fixes: f92ee31e031c ("btrfs: introduce btrfs_space_info sub-group")
+CC: stable@vger.kernel.org # 6.18+
+Reviewed-by: Qu Wenruo <wqu@suse.com>
+Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/space-info.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+--- a/fs/btrfs/space-info.c
++++ b/fs/btrfs/space-info.c
+@@ -260,10 +260,8 @@ static int create_space_info_sub_group(s
+       sub_group->subgroup_id = id;
+       ret = btrfs_sysfs_add_space_info_type(sub_group);
+-      if (ret) {
+-              kfree(sub_group);
++      if (ret)
+               parent->sub_group[index] = NULL;
+-      }
+       return ret;
+ }
diff --git a/queue-6.1/btrfs-fix-missing-last_unlink_trans-update-when-removing-a-directory.patch b/queue-6.1/btrfs-fix-missing-last_unlink_trans-update-when-removing-a-directory.patch
new file mode 100644 (file)
index 0000000..9029908
--- /dev/null
@@ -0,0 +1,224 @@
+From stable+bounces-249114-greg=kroah.com@vger.kernel.org Sun May 17 21:22:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 11:52:35 -0400
+Subject: btrfs: fix missing last_unlink_trans update when removing a directory
+To: stable@vger.kernel.org
+Cc: Filipe Manana <fdmanana@suse.com>, Slava0135 <slava.kovalevskiy.2014@gmail.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260517155235.302489-1-sashal@kernel.org>
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 999757231c49376cd1a37308d2c8c4c9932571e1 ]
+
+When removing a directory we are not updating its last_unlink_trans field,
+which can result in incorrect fsync behaviour in case some one fsyncs the
+directory after it was removed because it's holding a file descriptor on
+it.
+
+Example scenario:
+
+   mkdir /mnt/dir1
+   mkdir /mnt/dir1/dir2
+   mkdir /mnt/dir3
+
+   sync -f /mnt
+
+   # Do some change to the directory and fsync it.
+   chmod 700 /mnt/dir1
+   xfs_io -c fsync /mnt/dir1
+
+   # Move dir2 out of dir1 so that dir1 becomes empty.
+   mv /mnt/dir1/dir2 /mnt/dir3/
+
+   open fd on /mnt/dir1
+   call rmdir(2) on path "/mnt/dir1"
+   fsync fd
+
+   <trigger power failure>
+
+When attempting to mount the filesystem, the log replay will fail with
+an -EIO error and dmesg/syslog has the following:
+
+   [445771.626482] BTRFS info (device dm-0): first mount of filesystem 0368bbea-6c5e-44b5-b409-09abe496e650
+   [445771.626486] BTRFS info (device dm-0): using crc32c checksum algorithm
+   [445771.627912] BTRFS info (device dm-0): start tree-log replay
+   [445771.628335] page: refcount:2 mapcount:0 mapping:0000000061443ddc index:0x1d00 pfn:0x7072a5
+   [445771.629453] memcg:ffff89f400351b00
+   [445771.629892] aops:btree_aops [btrfs] ino:1
+   [445771.630737] flags: 0x17fffc00000402a(uptodate|lru|private|writeback|node=0|zone=2|lastcpupid=0x1ffff)
+   [445771.632359] raw: 017fffc00000402a fffff47284d950c8 fffff472907b7c08 ffff89f458e412b8
+   [445771.633713] raw: 0000000000001d00 ffff89f6c51d1a90 00000002ffffffff ffff89f400351b00
+   [445771.635029] page dumped because: eb page dump
+   [445771.635825] BTRFS critical (device dm-0): corrupt leaf: root=5 block=30408704 slot=10 ino=258, invalid nlink: has 2 expect no more than 1 for dir
+   [445771.638088] BTRFS info (device dm-0): leaf 30408704 gen 10 total ptrs 17 free space 14878 owner 5
+   [445771.638091] BTRFS info (device dm-0): refs 4 lock_owner 0 current 3581087
+   [445771.638094]     item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
+   [445771.638097]             inode generation 3 transid 9 size 16 nbytes 16384
+   [445771.638098]             block group 0 mode 40755 links 1 uid 0 gid 0
+   [445771.638100]             rdev 0 sequence 2 flags 0x0
+   [445771.638102]             atime 1775744884.0
+   [445771.660056]             ctime 1775744885.645502983
+   [445771.660058]             mtime 1775744885.645502983
+   [445771.660060]             otime 1775744884.0
+   [445771.660062]     item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
+   [445771.660064]             index 0 name_len 2
+   [445771.660066]     item 2 key (256 DIR_ITEM 1843588421) itemoff 16077 itemsize 34
+   [445771.660068]             location key (259 1 0) type 2
+   [445771.660070]             transid 9 data_len 0 name_len 4
+   [445771.660075]     item 3 key (256 DIR_ITEM 2363071922) itemoff 16043 itemsize 34
+   [445771.660076]             location key (257 1 0) type 2
+   [445771.660077]             transid 9 data_len 0 name_len 4
+   [445771.660078]     item 4 key (256 DIR_INDEX 2) itemoff 16009 itemsize 34
+   [445771.660079]             location key (257 1 0) type 2
+   [445771.660080]             transid 9 data_len 0 name_len 4
+   [445771.660081]     item 5 key (256 DIR_INDEX 3) itemoff 15975 itemsize 34
+   [445771.660082]             location key (259 1 0) type 2
+   [445771.660083]             transid 9 data_len 0 name_len 4
+   [445771.660084]     item 6 key (257 INODE_ITEM 0) itemoff 15815 itemsize 160
+   [445771.660086]             inode generation 9 transid 9 size 8 nbytes 0
+   [445771.660087]             block group 0 mode 40777 links 1 uid 0 gid 0
+   [445771.660088]             rdev 0 sequence 2 flags 0x0
+   [445771.660089]             atime 1775744885.641174097
+   [445771.660090]             ctime 1775744885.645502983
+   [445771.660091]             mtime 1775744885.645502983
+   [445771.660105]             otime 1775744885.641174097
+   [445771.660106]     item 7 key (257 INODE_REF 256) itemoff 15801 itemsize 14
+   [445771.660107]             index 2 name_len 4
+   [445771.660108]     item 8 key (257 DIR_ITEM 2676584006) itemoff 15767 itemsize 34
+   [445771.660109]             location key (258 1 0) type 2
+   [445771.660110]             transid 9 data_len 0 name_len 4
+   [445771.660111]     item 9 key (257 DIR_INDEX 2) itemoff 15733 itemsize 34
+   [445771.660112]             location key (258 1 0) type 2
+   [445771.660113]             transid 9 data_len 0 name_len 4
+   [445771.660114]     item 10 key (258 INODE_ITEM 0) itemoff 15573 itemsize 160
+   [445771.660115]             inode generation 9 transid 10 size 0 nbytes 0
+   [445771.660116]             block group 0 mode 40755 links 2 uid 0 gid 0
+   [445771.660117]             rdev 0 sequence 0 flags 0x0
+   [445771.660118]             atime 1775744885.645502983
+   [445771.660119]             ctime 1775744885.645502983
+   [445771.660120]             mtime 1775744885.645502983
+   [445771.660121]             otime 1775744885.645502983
+   [445771.660122]     item 11 key (258 INODE_REF 257) itemoff 15559 itemsize 14
+   [445771.660123]             index 2 name_len 4
+   [445771.660124]     item 12 key (258 INODE_REF 259) itemoff 15545 itemsize 14
+   [445771.660125]             index 2 name_len 4
+   [445771.660126]     item 13 key (259 INODE_ITEM 0) itemoff 15385 itemsize 160
+   [445771.660127]             inode generation 9 transid 10 size 8 nbytes 0
+   [445771.660128]             block group 0 mode 40755 links 1 uid 0 gid 0
+   [445771.660129]             rdev 0 sequence 1 flags 0x0
+   [445771.660130]             atime 1775744885.645502983
+   [445771.660130]             ctime 1775744885.645502983
+   [445771.660131]             mtime 1775744885.645502983
+   [445771.660132]             otime 1775744885.645502983
+   [445771.660133]     item 14 key (259 INODE_REF 256) itemoff 15371 itemsize 14
+   [445771.660134]             index 3 name_len 4
+   [445771.660135]     item 15 key (259 DIR_ITEM 2676584006) itemoff 15337 itemsize 34
+   [445771.660136]             location key (258 1 0) type 2
+   [445771.660137]             transid 10 data_len 0 name_len 4
+   [445771.660138]     item 16 key (259 DIR_INDEX 2) itemoff 15303 itemsize 34
+   [445771.660139]             location key (258 1 0) type 2
+   [445771.660140]             transid 10 data_len 0 name_len 4
+   [445771.660144] BTRFS error (device dm-0): block=30408704 write time tree block corruption detected
+   [445771.661650] ------------[ cut here ]------------
+   [445771.662358] WARNING: fs/btrfs/disk-io.c:326 at btree_csum_one_bio+0x217/0x230 [btrfs], CPU#8: mount/3581087
+   [445771.663588] Modules linked in: btrfs f2fs xfs (...)
+   [445771.671229] CPU: 8 UID: 0 PID: 3581087 Comm: mount Tainted: G        W           7.0.0-rc6-btrfs-next-230+ #2 PREEMPT(full)
+   [445771.672575] Tainted: [W]=WARN
+   [445771.672987] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-0-gea1b7a073390-prebuilt.qemu.org 04/01/2014
+   [445771.674460] RIP: 0010:btree_csum_one_bio+0x217/0x230 [btrfs]
+   [445771.675222] Code: 89 44 24 (...)
+   [445771.677364] RSP: 0018:ffffd23882247660 EFLAGS: 00010246
+   [445771.678029] RAX: 0000000000000000 RBX: ffff89f6c51d1a90 RCX: 0000000000000000
+   [445771.678975] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff89f406020000
+   [445771.679983] RBP: ffff89f821204000 R08: 0000000000000000 R09: 00000000ffefffff
+   [445771.680905] R10: ffffd23882247448 R11: 0000000000000003 R12: ffffd23882247668
+   [445771.681978] R13: ffff89f458e40fc0 R14: ffff89f737f4f500 R15: ffff89f737f4f500
+   [445771.682912] FS:  00007f0447a98840(0000) GS:ffff89fb9771d000(0000) knlGS:0000000000000000
+   [445771.684393] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+   [445771.685230] CR2: 00007f0447bf1330 CR3: 000000017cb02002 CR4: 0000000000370ef0
+   [445771.686273] Call Trace:
+   [445771.686646]  <TASK>
+   [445771.686969]  btrfs_submit_bbio+0x83f/0x860 [btrfs]
+   [445771.687750]  ? write_one_eb+0x28f/0x340 [btrfs]
+   [445771.688428]  btree_writepages+0x2e3/0x550 [btrfs]
+   [445771.689180]  ? kmem_cache_alloc_noprof+0x12a/0x490
+   [445771.689963]  ? alloc_extent_state+0x19/0x120 [btrfs]
+   [445771.690801]  ? kmem_cache_free+0x135/0x380
+   [445771.691328]  ? preempt_count_add+0x69/0xa0
+   [445771.691831]  ? set_extent_bit+0x252/0x8e0 [btrfs]
+   [445771.692468]  ? xas_load+0x9/0xc0
+   [445771.692873]  ? xas_find+0x14d/0x1a0
+   [445771.693304]  do_writepages+0xc6/0x160
+   [445771.693756]  filemap_writeback+0xb8/0xe0
+   [445771.694274]  btrfs_write_marked_extents+0x61/0x170 [btrfs]
+   [445771.694999]  btrfs_write_and_wait_transaction+0x4e/0xc0 [btrfs]
+   [445771.695818]  btrfs_commit_transaction+0x5c8/0xd10 [btrfs]
+   [445771.696530]  ? kmem_cache_free+0x135/0x380
+   [445771.697120]  ? release_extent_buffer+0x34/0x160 [btrfs]
+   [445771.697786]  btrfs_recover_log_trees+0x7be/0x7e0 [btrfs]
+   [445771.698525]  ? __pfx_replay_one_buffer+0x10/0x10 [btrfs]
+   [445771.699206]  open_ctree+0x11e5/0x1810 [btrfs]
+   [445771.699776]  btrfs_get_tree.cold+0xb/0x162 [btrfs]
+   [445771.700463]  ? fscontext_read+0x165/0x180
+   [445771.701146]  ? rw_verify_area+0x50/0x180
+   [445771.701866]  vfs_get_tree+0x25/0xd0
+   [445771.702491]  vfs_cmd_create+0x59/0xe0
+   [445771.703125]  __do_sys_fsconfig+0x303/0x610
+   [445771.703603]  do_syscall_64+0xe9/0xf20
+   [445771.703974]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+   [445771.704700] RIP: 0033:0x7f0447cbd4aa
+   [445771.705108] Code: 73 01 c3 (...)
+   [445771.707263] RSP: 002b:00007ffc4e528318 EFLAGS: 00000246 ORIG_RAX: 00000000000001af
+   [445771.708107] RAX: ffffffffffffffda RBX: 00005561585d8c20 RCX: 00007f0447cbd4aa
+   [445771.708931] RDX: 0000000000000000 RSI: 0000000000000006 RDI: 0000000000000003
+   [445771.709744] RBP: 00005561585d9120 R08: 0000000000000000 R09: 0000000000000000
+   [445771.710674] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+   [445771.711477] R13: 00007f0447e4f580 R14: 00007f0447e5126c R15: 00007f0447e36a23
+   [445771.712277]  </TASK>
+   [445771.712541] ---[ end trace 0000000000000000 ]---
+   [445771.713382] BTRFS error (device dm-0): error while writing out transaction: -5
+   [445771.714679] BTRFS warning (device dm-0): Skipping commit of aborted transaction.
+   [445771.715562] BTRFS error (device dm-0 state A): Transaction aborted (error -5)
+   [445771.716459] BTRFS: error (device dm-0 state A) in cleanup_transaction:2068: errno=-5 IO failure
+   [445771.717936] BTRFS error (device dm-0 state EA): failed to recover log trees with error: -5
+   [445771.719681] BTRFS error (device dm-0 state EA): open_ctree failed: -5
+
+The problem is that such a fsync should have result in a fallback to a
+transaction commit, but that did not happen because through the
+btrfs_rmdir() we never update the directory's last_unlink_trans field.
+Any inode that had a link removed must have its last_unlink_trans updated
+to the ID of transaction used for the operation, otherwise fsync and log
+replay will not work correctly.
+
+btrfs_rmdir() calls btrfs_unlink_inode() and through that call chain we
+never call btrfs_record_unlink_dir() in order to update last_unlink_trans.
+However btrfs_unlink(), which is used for unlinking regular files, calls
+btrfs_record_unlink_dir() and then calls btrfs_unlink_inode(). So fix
+this by moving the call to btrfs_record_unlink_dir() from btrfs_unlink()
+to btrfs_unlink_inode().
+
+A test case for fstests will follow soon.
+
+Reported-by: Slava0135 <slava.kovalevskiy.2014@gmail.com>
+Link: https://lore.kernel.org/linux-btrfs/CAAJYhww5ov62Hm+n+tmhcL-e_4cBobg+OWogKjOJxVUXivC=MQ@mail.gmail.com/
+CC: stable@vger.kernel.org
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+[ wrapped dir and inode arguments with BTRFS_I() since 6.1 btrfs_rmdir() uses struct inode * instead of struct btrfs_inode * ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/inode.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4915,6 +4915,8 @@ static int btrfs_rmdir(struct inode *dir
+       if (err)
+               goto out;
++      btrfs_record_unlink_dir(trans, BTRFS_I(dir), BTRFS_I(inode), false);
++
+       /* now the directory is empty */
+       err = btrfs_unlink_inode(trans, BTRFS_I(dir), BTRFS_I(d_inode(dentry)),
+                                &fname.disk_name);
diff --git a/queue-6.1/btrfs-remove-fs_info-argument-from-btrfs_sysfs_add_space_info_type.patch b/queue-6.1/btrfs-remove-fs_info-argument-from-btrfs_sysfs_add_space_info_type.patch
new file mode 100644 (file)
index 0000000..7ebf4c4
--- /dev/null
@@ -0,0 +1,78 @@
+From stable+bounces-247813-greg=kroah.com@vger.kernel.org Fri May 15 20:46:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 11:07:27 -0400
+Subject: btrfs: remove fs_info argument from btrfs_sysfs_add_space_info_type()
+To: stable@vger.kernel.org
+Cc: Filipe Manana <fdmanana@suse.com>, Johannes Thumshirn <johannes.thumshirn@wdc.com>, David Sterba <dsterba@suse.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515150728.3262445-1-sashal@kernel.org>
+
+From: Filipe Manana <fdmanana@suse.com>
+
+[ Upstream commit 771af6ff72e0ed0eb8bf97e5ae4fa5094e0c5d1d ]
+
+We don't need it since we can grab fs_info from the given space_info.
+So remove the fs_info argument.
+
+Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
+Signed-off-by: Filipe Manana <fdmanana@suse.com>
+Reviewed-by: David Sterba <dsterba@suse.com>
+Signed-off-by: David Sterba <dsterba@suse.com>
+Stable-dep-of: a7449edf9614 ("btrfs: fix double free in create_space_info_sub_group() error path")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/btrfs/space-info.c |    4 ++--
+ fs/btrfs/sysfs.c      |    5 ++---
+ fs/btrfs/sysfs.h      |    3 +--
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+--- a/fs/btrfs/space-info.c
++++ b/fs/btrfs/space-info.c
+@@ -259,7 +259,7 @@ static int create_space_info_sub_group(s
+       sub_group->parent = parent;
+       sub_group->subgroup_id = id;
+-      ret = btrfs_sysfs_add_space_info_type(fs_info, sub_group);
++      ret = btrfs_sysfs_add_space_info_type(sub_group);
+       if (ret) {
+               kfree(sub_group);
+               parent->sub_group[index] = NULL;
+@@ -288,7 +288,7 @@ static int create_space_info(struct btrf
+                       goto out_free;
+       }
+-      ret = btrfs_sysfs_add_space_info_type(info, space_info);
++      ret = btrfs_sysfs_add_space_info_type(space_info);
+       if (ret)
+               return ret;
+--- a/fs/btrfs/sysfs.c
++++ b/fs/btrfs/sysfs.c
+@@ -1618,13 +1618,12 @@ static const char *alloc_name(struct btr
+  * Create a sysfs entry for a space info type at path
+  * /sys/fs/btrfs/UUID/allocation/TYPE
+  */
+-int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info,
+-                                  struct btrfs_space_info *space_info)
++int btrfs_sysfs_add_space_info_type(struct btrfs_space_info *space_info)
+ {
+       int ret;
+       ret = kobject_init_and_add(&space_info->kobj, &space_info_ktype,
+-                                 fs_info->space_info_kobj, "%s",
++                                 space_info->fs_info->space_info_kobj, "%s",
+                                  alloc_name(space_info));
+       if (ret) {
+               kobject_put(&space_info->kobj);
+--- a/fs/btrfs/sysfs.h
++++ b/fs/btrfs/sysfs.h
+@@ -28,8 +28,7 @@ void __cold btrfs_exit_sysfs(void);
+ int btrfs_sysfs_add_mounted(struct btrfs_fs_info *fs_info);
+ void btrfs_sysfs_remove_mounted(struct btrfs_fs_info *fs_info);
+ void btrfs_sysfs_add_block_group_type(struct btrfs_block_group *cache);
+-int btrfs_sysfs_add_space_info_type(struct btrfs_fs_info *fs_info,
+-                                  struct btrfs_space_info *space_info);
++int btrfs_sysfs_add_space_info_type(struct btrfs_space_info *space_info);
+ void btrfs_sysfs_remove_space_info(struct btrfs_space_info *space_info);
+ void btrfs_sysfs_update_devid(struct btrfs_device *device);
diff --git a/queue-6.1/ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch b/queue-6.1/ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch
new file mode 100644 (file)
index 0000000..06e5211
--- /dev/null
@@ -0,0 +1,113 @@
+From stable+bounces-244962-greg=kroah.com@vger.kernel.org Sat May  9 20:23:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  9 May 2026 10:53:07 -0400
+Subject: ceph: only d_add() negative dentries when they are unhashed
+To: stable@vger.kernel.org
+Cc: Max Kellermann <max.kellermann@ionos.com>, Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>, Ilya Dryomov <idryomov@gmail.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509145307.3498924-1-sashal@kernel.org>
+
+From: Max Kellermann <max.kellermann@ionos.com>
+
+[ Upstream commit 803447f93d75ab6e40c85e6d12b5630d281d70d6 ]
+
+Ceph can call d_add(dentry, NULL) on a negative dentry that is already
+present in the primary dcache hash.
+
+In the current VFS that is not safe.  d_add() goes through __d_add()
+to __d_rehash(), which unconditionally reinserts dentry->d_hash into
+the hlist_bl bucket.  If the dentry is already hashed, reinserting the
+same node can corrupt the bucket, including creating a self-loop.
+Once that happens, __d_lookup() can spin forever in the hlist_bl walk,
+typically looping only on the d_name.hash mismatch check and
+eventually triggering RCU stall reports like this one:
+
+ rcu: INFO: rcu_sched self-detected stall on CPU
+ rcu:         87-....: (2100 ticks this GP) idle=3a4c/1/0x4000000000000000 softirq=25003319/25003319 fqs=829
+ rcu:         (t=2101 jiffies g=79058445 q=698988 ncpus=192)
+ CPU: 87 UID: 2952868916 PID: 3933303 Comm: php-cgi8.3 Not tainted 6.18.17-i1-amd #950 NONE
+ Hardware name: Dell Inc. PowerEdge R7615/0G9DHV, BIOS 1.6.6 09/22/2023
+ RIP: 0010:__d_lookup+0x46/0xb0
+ Code: c1 e8 07 48 8d 04 c2 48 8b 00 49 89 fc 49 89 f5 48 89 c3 48 83 e3 fe 48 83 f8 01 77 0f eb 2d 0f 1f 44 00 00 48 8b 1b 48 85 db <74> 20 39 6b 18 75 f3 48 8d 7b 78 e8 ba 85 d0 00 4c 39 63 10 74 1f
+ RSP: 0018:ff745a70c8253898 EFLAGS: 00000282
+ RAX: ff26e470054cb208 RBX: ff26e470054cb208 RCX: 000000006e958966
+ RDX: ff26e48267340000 RSI: ff745a70c82539b0 RDI: ff26e458f74655c0
+ RBP: 000000006e958966 R08: 0000000000000180 R09: 9cd08d909b919a89
+ R10: ff26e458f74655c0 R11: 0000000000000000 R12: ff26e458f74655c0
+ R13: ff745a70c82539b0 R14: d0d0d0d0d0d0d0d0 R15: 2f2f2f2f2f2f2f2f
+ FS:  00007f5770896980(0000) GS:ff26e482c5d88000(0000) knlGS:0000000000000000
+ CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+ CR2: 00007f5764de50c0 CR3: 000000a72abb5001 CR4: 0000000000771ef0
+ PKRU: 55555554
+ Call Trace:
+  <TASK>
+  lookup_fast+0x9f/0x100
+  walk_component+0x1f/0x150
+  link_path_walk+0x20e/0x3d0
+  path_lookupat+0x68/0x180
+  filename_lookup+0xdc/0x1e0
+  vfs_statx+0x6c/0x140
+  vfs_fstatat+0x67/0xa0
+  __do_sys_newfstatat+0x24/0x60
+  do_syscall_64+0x6a/0x230
+  entry_SYSCALL_64_after_hwframe+0x76/0x7e
+
+This is reachable with reused cached negative dentries.  A Ceph lookup
+or atomic_open can be handed a negative dentry that is already hashed,
+and fs/ceph/dir.c then hits one of two paths that incorrectly assume
+"negative" also means "unhashed":
+
+  - ceph_finish_lookup():
+      MDS reply is -ENOENT with no trace
+      -> d_add(dentry, NULL)
+
+  - ceph_lookup():
+      local ENOENT fast path for a complete directory with shared caps
+      -> d_add(dentry, NULL)
+
+Both paths can therefore re-add an already-hashed negative dentry.
+
+Ceph already uses the correct pattern elsewhere: ceph_fill_trace() only
+calls d_add(dn, NULL) for a negative null-dentry reply when d_unhashed(dn)
+is true.
+
+Fix both fs/ceph/dir.c sites the same way: only call d_add() for a
+negative dentry when it is actually unhashed.  If the negative dentry
+is already hashed, leave it in place and reuse it as-is.
+
+This preserves the existing behavior for unhashed dentries while
+avoiding d_hash list corruption for reused hashed negatives.
+
+Cc: stable@vger.kernel.org
+Fixes: 2817b000b02c ("ceph: directory operations")
+Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
+Reviewed-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+[ kept existing dout() debug call instead of upstream's doutc() form when adding the d_unhashed() guard around d_add() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/dir.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/fs/ceph/dir.c
++++ b/fs/ceph/dir.c
+@@ -721,7 +721,8 @@ struct dentry *ceph_finish_lookup(struct
+                               d_drop(dentry);
+                               err = -ENOENT;
+                       } else {
+-                              d_add(dentry, NULL);
++                              if (d_unhashed(dentry))
++                                      d_add(dentry, NULL);
+                       }
+               }
+       }
+@@ -777,7 +778,8 @@ static struct dentry *ceph_lookup(struct
+                       __ceph_touch_fmode(ci, mdsc, CEPH_FILE_MODE_RD);
+                       spin_unlock(&ci->i_ceph_lock);
+                       dout(" dir %p complete, -ENOENT\n", dir);
+-                      d_add(dentry, NULL);
++                      if (d_unhashed(dentry))
++                              d_add(dentry, NULL);
+                       di->lease_shared_gen = atomic_read(&ci->i_shared_gen);
+                       return NULL;
+               }
diff --git a/queue-6.1/cgroup-cpuset-reset-dl-migration-state-on-can_attach-failure.patch b/queue-6.1/cgroup-cpuset-reset-dl-migration-state-on-can_attach-failure.patch
new file mode 100644 (file)
index 0000000..6e5fcbc
--- /dev/null
@@ -0,0 +1,70 @@
+From stable+bounces-253851-greg=kroah.com@vger.kernel.org Sat May 23 02:21:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 May 2026 16:51:17 -0400
+Subject: cgroup/cpuset: Reset DL migration state on can_attach() failure
+To: stable@vger.kernel.org
+Cc: Guopeng Zhang <zhangguopeng@kylinos.cn>, Tejun Heo <tj@kernel.org>, Chen Ridong <chenridong@huaweicloud.com>, Waiman Long <longman@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260522205117.4065831-1-sashal@kernel.org>
+
+From: Guopeng Zhang <zhangguopeng@kylinos.cn>
+
+[ Upstream commit 4a39eda5fdd867fc39f3c039714dd432cee00268 ]
+
+cpuset_can_attach() accumulates temporary SCHED_DEADLINE migration
+state in the destination cpuset while walking the taskset.
+
+If a later task_can_attach() or security_task_setscheduler() check
+fails, cgroup_migrate_execute() treats cpuset as the failing subsystem
+and does not call cpuset_cancel_attach() for it. The partially
+accumulated state is then left behind and can be consumed by a later
+attach, corrupting cpuset DL task accounting and pending DL bandwidth
+accounting.
+
+Reset the pending DL migration state from the common error exit when
+ret is non-zero. Successful can_attach() keeps the state for
+cpuset_attach() or cpuset_cancel_attach().
+
+Fixes: 2ef269ef1ac0 ("cgroup/cpuset: Free DL BW in case can_attach() fails")
+Cc: stable@vger.kernel.org # v6.10+
+Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reviewed-by: Chen Ridong <chenridong@huaweicloud.com>
+Reviewed-by: Waiman Long <longman@redhat.com>
+[ omitted upstream context line `cs->dl_bw_cpu = cpu;` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/cgroup/cpuset.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/kernel/cgroup/cpuset.c
++++ b/kernel/cgroup/cpuset.c
+@@ -2579,16 +2579,13 @@ static int cpuset_can_attach(struct cgro
+               int cpu = cpumask_any_and(cpu_active_mask, cs->effective_cpus);
+               if (unlikely(cpu >= nr_cpu_ids)) {
+-                      reset_migrate_dl_data(cs);
+                       ret = -EINVAL;
+                       goto out_unlock;
+               }
+               ret = dl_bw_alloc(cpu, cs->sum_migrate_dl_bw);
+-              if (ret) {
+-                      reset_migrate_dl_data(cs);
++              if (ret)
+                       goto out_unlock;
+-              }
+       }
+ out_success:
+@@ -3401,7 +3398,10 @@ static int cpuset_can_fork(struct task_s
+        * changes which zero cpus/mems_allowed.
+        */
+       cs->attach_in_progress++;
++
+ out_unlock:
++      if (ret)
++              reset_migrate_dl_data(cs);
+       mutex_unlock(&cpuset_mutex);
+       return ret;
+ }
diff --git a/queue-6.1/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch b/queue-6.1/crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
new file mode 100644 (file)
index 0000000..9d601e5
--- /dev/null
@@ -0,0 +1,68 @@
+From stable+bounces-245029-greg=kroah.com@vger.kernel.org Sun May 10 19:52:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 10:22:50 -0400
+Subject: crypto: caam - guard HMAC key hex dumps in hash_digest_key
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510142250.4179491-2-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit 177730a273b18e195263ed953853273e901b5064 ]
+
+Use print_hex_dump_devel() for dumping sensitive HMAC key bytes in
+hash_digest_key() to avoid leaking secrets at runtime when
+CONFIG_DYNAMIC_DEBUG is enabled.
+
+Fixes: 045e36780f11 ("crypto: caam - ahash hmac support")
+Fixes: 3f16f6c9d632 ("crypto: caam/qi2 - add support for ahash algorithms")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/caam/caamalg_qi2.c |    4 ++--
+ drivers/crypto/caam/caamhash.c    |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/crypto/caam/caamalg_qi2.c
++++ b/drivers/crypto/caam/caamalg_qi2.c
+@@ -3264,7 +3264,7 @@ static int hash_digest_key(struct caam_h
+       dpaa2_fl_set_addr(out_fle, key_dma);
+       dpaa2_fl_set_len(out_fle, digestsize);
+-      print_hex_dump_debug("key_in@" __stringify(__LINE__)": ",
++      print_hex_dump_devel("key_in@" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1);
+       print_hex_dump_debug("shdesc@" __stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
+@@ -3284,7 +3284,7 @@ static int hash_digest_key(struct caam_h
+               /* in progress */
+               wait_for_completion(&result.completion);
+               ret = result.err;
+-              print_hex_dump_debug("digested key@" __stringify(__LINE__)": ",
++              print_hex_dump_devel("digested key@" __stringify(__LINE__)": ",
+                                    DUMP_PREFIX_ADDRESS, 16, 4, key,
+                                    digestsize, 1);
+       }
+--- a/drivers/crypto/caam/caamhash.c
++++ b/drivers/crypto/caam/caamhash.c
+@@ -390,7 +390,7 @@ static int hash_digest_key(struct caam_h
+       append_seq_store(desc, digestsize, LDST_CLASS_2_CCB |
+                        LDST_SRCDST_BYTE_CONTEXT);
+-      print_hex_dump_debug("key_in@"__stringify(__LINE__)": ",
++      print_hex_dump_devel("key_in@"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, key, *keylen, 1);
+       print_hex_dump_debug("jobdesc@"__stringify(__LINE__)": ",
+                            DUMP_PREFIX_ADDRESS, 16, 4, desc, desc_bytes(desc),
+@@ -405,7 +405,7 @@ static int hash_digest_key(struct caam_h
+               wait_for_completion(&result.completion);
+               ret = result.err;
+-              print_hex_dump_debug("digested key@"__stringify(__LINE__)": ",
++              print_hex_dump_devel("digested key@"__stringify(__LINE__)": ",
+                                    DUMP_PREFIX_ADDRESS, 16, 4, key,
+                                    digestsize, 1);
+       }
diff --git a/queue-6.1/crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch b/queue-6.1/crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch
new file mode 100644 (file)
index 0000000..daaa07b
--- /dev/null
@@ -0,0 +1,120 @@
+From stable+bounces-244904-greg=kroah.com@vger.kernel.org Sat May  9 09:14:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 23:44:17 -0400
+Subject: crypto: nx - Avoid -Wflex-array-member-not-at-end warning
+To: stable@vger.kernel.org
+Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509034419.3105450-1-sashal@kernel.org>
+
+From: "Gustavo A. R. Silva" <gustavoars@kernel.org>
+
+[ Upstream commit 1e6b251ce1759392666856908113dd5d7cea044d ]
+
+-Wflex-array-member-not-at-end is coming in GCC-14, and we are getting
+ready to enable it globally. So, we are deprecating flexible-array
+members in the middle of another structure.
+
+There is currently an object (`header`) in `struct nx842_crypto_ctx`
+that contains a flexible structure (`struct nx842_crypto_header`):
+
+struct nx842_crypto_ctx {
+       ...
+        struct nx842_crypto_header header;
+        struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
+       ...
+};
+
+So, in order to avoid ending up with a flexible-array member in the
+middle of another struct, we use the `struct_group_tagged()` helper to
+separate the flexible array from the rest of the members in the flexible
+structure:
+
+struct nx842_crypto_header {
+       struct_group_tagged(nx842_crypto_header_hdr, hdr,
+
+               ... the rest of the members
+
+       );
+        struct nx842_crypto_header_group group[];
+} __packed;
+
+With the change described above, we can now declare an object of the
+type of the tagged struct, without embedding the flexible array in the
+middle of another struct:
+
+struct nx842_crypto_ctx {
+       ...
+        struct nx842_crypto_header_hdr header;
+        struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
+       ...
+ } __packed;
+
+We also use `container_of()` whenever we need to retrieve a pointer to
+the flexible structure, through which we can access the flexible
+array if needed.
+
+So, with these changes, fix the following warning:
+
+In file included from drivers/crypto/nx/nx-842.c:55:
+drivers/crypto/nx/nx-842.h:174:36: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
+  174 |         struct nx842_crypto_header header;
+      |                                    ^~~~~~
+
+Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: adb3faf2db1a ("crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/nx/nx-842.c |    6 ++++--
+ drivers/crypto/nx/nx-842.h |   10 ++++++----
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+--- a/drivers/crypto/nx/nx-842.c
++++ b/drivers/crypto/nx/nx-842.c
+@@ -251,7 +251,9 @@ int nx842_crypto_compress(struct crypto_
+                         u8 *dst, unsigned int *dlen)
+ {
+       struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
+-      struct nx842_crypto_header *hdr = &ctx->header;
++      struct nx842_crypto_header *hdr =
++                              container_of(&ctx->header,
++                                           struct nx842_crypto_header, hdr);
+       struct nx842_crypto_param p;
+       struct nx842_constraints c = *ctx->driver->constraints;
+       unsigned int groups, hdrsize, h;
+@@ -490,7 +492,7 @@ int nx842_crypto_decompress(struct crypt
+       }
+       memcpy(&ctx->header, src, hdr_len);
+-      hdr = &ctx->header;
++      hdr = container_of(&ctx->header, struct nx842_crypto_header, hdr);
+       for (n = 0; n < hdr->groups; n++) {
+               /* ignore applies to last group */
+--- a/drivers/crypto/nx/nx-842.h
++++ b/drivers/crypto/nx/nx-842.h
+@@ -157,9 +157,11 @@ struct nx842_crypto_header_group {
+ } __packed;
+ struct nx842_crypto_header {
+-      __be16 magic;           /* NX842_CRYPTO_MAGIC */
+-      __be16 ignore;          /* decompressed end bytes to ignore */
+-      u8 groups;              /* total groups in this header */
++      struct_group_tagged(nx842_crypto_header_hdr, hdr,
++              __be16 magic;           /* NX842_CRYPTO_MAGIC */
++              __be16 ignore;          /* decompressed end bytes to ignore */
++              u8 groups;              /* total groups in this header */
++      );
+       struct nx842_crypto_header_group group[];
+ } __packed;
+@@ -171,7 +173,7 @@ struct nx842_crypto_ctx {
+       u8 *wmem;
+       u8 *sbounce, *dbounce;
+-      struct nx842_crypto_header header;
++      struct nx842_crypto_header_hdr header;
+       struct nx842_crypto_header_group group[NX842_CRYPTO_GROUP_MAX];
+       struct nx842_driver *driver;
diff --git a/queue-6.1/crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch b/queue-6.1/crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
new file mode 100644 (file)
index 0000000..244ef83
--- /dev/null
@@ -0,0 +1,51 @@
+From stable+bounces-244906-greg=kroah.com@vger.kernel.org Sat May  9 09:14:35 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 23:44:19 -0400
+Subject: crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509034419.3105450-3-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit adb3faf2db1a66d0f015b44ac909a32dfc7f2f9c ]
+
+The bounce buffers are allocated with __get_free_pages() using
+BOUNCE_BUFFER_ORDER (order 2 = 4 pages), but both the allocation error
+path and nx842_crypto_free_ctx() release the buffers with free_page().
+Use free_pages() with the matching order instead.
+
+Fixes: ed70b479c2c0 ("crypto: nx - add hardware 842 crypto comp alg")
+Cc: stable@vger.kernel.org
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/nx/nx-842.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/crypto/nx/nx-842.c
++++ b/drivers/crypto/nx/nx-842.c
+@@ -116,8 +116,8 @@ void *nx842_crypto_alloc_ctx(struct nx84
+       ctx->dbounce = (u8 *)__get_free_pages(GFP_KERNEL, BOUNCE_BUFFER_ORDER);
+       if (!ctx->wmem || !ctx->sbounce || !ctx->dbounce) {
+               kfree(ctx->wmem);
+-              free_page((unsigned long)ctx->sbounce);
+-              free_page((unsigned long)ctx->dbounce);
++              free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER);
++              free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER);
+               kfree(ctx);
+               return ERR_PTR(-ENOMEM);
+       }
+@@ -131,8 +131,8 @@ void nx842_crypto_free_ctx(void *p)
+       struct nx842_crypto_ctx *ctx = p;
+       kfree(ctx->wmem);
+-      free_page((unsigned long)ctx->sbounce);
+-      free_page((unsigned long)ctx->dbounce);
++      free_pages((unsigned long)ctx->sbounce, BOUNCE_BUFFER_ORDER);
++      free_pages((unsigned long)ctx->dbounce, BOUNCE_BUFFER_ORDER);
+ }
+ EXPORT_SYMBOL_GPL(nx842_crypto_free_ctx);
diff --git a/queue-6.1/crypto-nx-migrate-to-scomp-api.patch b/queue-6.1/crypto-nx-migrate-to-scomp-api.patch
new file mode 100644 (file)
index 0000000..959beba
--- /dev/null
@@ -0,0 +1,279 @@
+From stable+bounces-244905-greg=kroah.com@vger.kernel.org Sat May  9 09:14:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 23:44:18 -0400
+Subject: crypto: nx - Migrate to scomp API
+To: stable@vger.kernel.org
+Cc: Ard Biesheuvel <ardb@kernel.org>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509034419.3105450-2-sashal@kernel.org>
+
+From: Ard Biesheuvel <ardb@kernel.org>
+
+[ Upstream commit 980b5705f4e73f567e405cd18337cc32fd51cf79 ]
+
+The only remaining user of 842 compression has been migrated to the
+acomp compression API, and so the NX hardware driver has to follow suit,
+given that no users of the obsolete 'comp' API remain, and it is going
+to be removed.
+
+So migrate the NX driver code to scomp. These will be wrapped and
+exposed as acomp implementation via the crypto subsystem's
+acomp-to-scomp adaptation layer.
+
+Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: adb3faf2db1a ("crypto: nx - fix bounce buffer leaks in nx842_crypto_{alloc,free}_ctx")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/crypto/nx/nx-842.c            |   33 +++++++++++++++++++--------------
+ drivers/crypto/nx/nx-842.h            |   14 ++++++++------
+ drivers/crypto/nx/nx-common-powernv.c |   31 +++++++++++++++----------------
+ drivers/crypto/nx/nx-common-pseries.c |   33 ++++++++++++++++-----------------
+ 4 files changed, 58 insertions(+), 53 deletions(-)
+
+--- a/drivers/crypto/nx/nx-842.c
++++ b/drivers/crypto/nx/nx-842.c
+@@ -101,9 +101,13 @@ static int update_param(struct nx842_cry
+       return 0;
+ }
+-int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver)
++void *nx842_crypto_alloc_ctx(struct nx842_driver *driver)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx;
++
++      ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
++      if (!ctx)
++              return ERR_PTR(-ENOMEM);
+       spin_lock_init(&ctx->lock);
+       ctx->driver = driver;
+@@ -114,22 +118,23 @@ int nx842_crypto_init(struct crypto_tfm
+               kfree(ctx->wmem);
+               free_page((unsigned long)ctx->sbounce);
+               free_page((unsigned long)ctx->dbounce);
+-              return -ENOMEM;
++              kfree(ctx);
++              return ERR_PTR(-ENOMEM);
+       }
+-      return 0;
++      return ctx;
+ }
+-EXPORT_SYMBOL_GPL(nx842_crypto_init);
++EXPORT_SYMBOL_GPL(nx842_crypto_alloc_ctx);
+-void nx842_crypto_exit(struct crypto_tfm *tfm)
++void nx842_crypto_free_ctx(void *p)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx = p;
+       kfree(ctx->wmem);
+       free_page((unsigned long)ctx->sbounce);
+       free_page((unsigned long)ctx->dbounce);
+ }
+-EXPORT_SYMBOL_GPL(nx842_crypto_exit);
++EXPORT_SYMBOL_GPL(nx842_crypto_free_ctx);
+ static void check_constraints(struct nx842_constraints *c)
+ {
+@@ -246,11 +251,11 @@ nospc:
+       return update_param(p, slen, dskip + dlen);
+ }
+-int nx842_crypto_compress(struct crypto_tfm *tfm,
++int nx842_crypto_compress(struct crypto_scomp *tfm,
+                         const u8 *src, unsigned int slen,
+-                        u8 *dst, unsigned int *dlen)
++                        u8 *dst, unsigned int *dlen, void *pctx)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx = pctx;
+       struct nx842_crypto_header *hdr =
+                               container_of(&ctx->header,
+                                            struct nx842_crypto_header, hdr);
+@@ -431,11 +436,11 @@ usesw:
+       return update_param(p, slen + padding, dlen);
+ }
+-int nx842_crypto_decompress(struct crypto_tfm *tfm,
++int nx842_crypto_decompress(struct crypto_scomp *tfm,
+                           const u8 *src, unsigned int slen,
+-                          u8 *dst, unsigned int *dlen)
++                          u8 *dst, unsigned int *dlen, void *pctx)
+ {
+-      struct nx842_crypto_ctx *ctx = crypto_tfm_ctx(tfm);
++      struct nx842_crypto_ctx *ctx = pctx;
+       struct nx842_crypto_header *hdr;
+       struct nx842_crypto_param p;
+       struct nx842_constraints c = *ctx->driver->constraints;
+--- a/drivers/crypto/nx/nx-842.h
++++ b/drivers/crypto/nx/nx-842.h
+@@ -101,6 +101,8 @@
+ #define LEN_ON_SIZE(pa, size) ((size) - ((pa) & ((size) - 1)))
+ #define LEN_ON_PAGE(pa)               LEN_ON_SIZE(pa, PAGE_SIZE)
++struct crypto_scomp;
++
+ static inline unsigned long nx842_get_pa(void *addr)
+ {
+       if (!is_vmalloc_addr(addr))
+@@ -179,13 +181,13 @@ struct nx842_crypto_ctx {
+       struct nx842_driver *driver;
+ };
+-int nx842_crypto_init(struct crypto_tfm *tfm, struct nx842_driver *driver);
+-void nx842_crypto_exit(struct crypto_tfm *tfm);
+-int nx842_crypto_compress(struct crypto_tfm *tfm,
++void *nx842_crypto_alloc_ctx(struct nx842_driver *driver);
++void nx842_crypto_free_ctx(void *ctx);
++int nx842_crypto_compress(struct crypto_scomp *tfm,
+                         const u8 *src, unsigned int slen,
+-                        u8 *dst, unsigned int *dlen);
+-int nx842_crypto_decompress(struct crypto_tfm *tfm,
++                        u8 *dst, unsigned int *dlen, void *ctx);
++int nx842_crypto_decompress(struct crypto_scomp *tfm,
+                           const u8 *src, unsigned int slen,
+-                          u8 *dst, unsigned int *dlen);
++                          u8 *dst, unsigned int *dlen, void *ctx);
+ #endif /* __NX_842_H__ */
+--- a/drivers/crypto/nx/nx-common-powernv.c
++++ b/drivers/crypto/nx/nx-common-powernv.c
+@@ -9,6 +9,7 @@
+ #include "nx-842.h"
++#include <crypto/internal/scompress.h>
+ #include <linux/timer.h>
+ #include <asm/prom.h>
+@@ -1034,23 +1035,21 @@ static struct nx842_driver nx842_powernv
+       .decompress =   nx842_powernv_decompress,
+ };
+-static int nx842_powernv_crypto_init(struct crypto_tfm *tfm)
++static void *nx842_powernv_crypto_alloc_ctx(void)
+ {
+-      return nx842_crypto_init(tfm, &nx842_powernv_driver);
++      return nx842_crypto_alloc_ctx(&nx842_powernv_driver);
+ }
+-static struct crypto_alg nx842_powernv_alg = {
+-      .cra_name               = "842",
+-      .cra_driver_name        = "842-nx",
+-      .cra_priority           = 300,
+-      .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
+-      .cra_ctxsize            = sizeof(struct nx842_crypto_ctx),
+-      .cra_module             = THIS_MODULE,
+-      .cra_init               = nx842_powernv_crypto_init,
+-      .cra_exit               = nx842_crypto_exit,
+-      .cra_u                  = { .compress = {
+-      .coa_compress           = nx842_crypto_compress,
+-      .coa_decompress         = nx842_crypto_decompress } }
++static struct scomp_alg nx842_powernv_alg = {
++      .base.cra_name          = "842",
++      .base.cra_driver_name   = "842-nx",
++      .base.cra_priority      = 300,
++      .base.cra_module        = THIS_MODULE,
++
++      .alloc_ctx              = nx842_powernv_crypto_alloc_ctx,
++      .free_ctx               = nx842_crypto_free_ctx,
++      .compress               = nx842_crypto_compress,
++      .decompress             = nx842_crypto_decompress,
+ };
+ static __init int nx_compress_powernv_init(void)
+@@ -1110,7 +1109,7 @@ static __init int nx_compress_powernv_in
+               nx842_powernv_exec = nx842_exec_vas;
+       }
+-      ret = crypto_register_alg(&nx842_powernv_alg);
++      ret = crypto_register_scomp(&nx842_powernv_alg);
+       if (ret) {
+               nx_delete_coprocs();
+               return ret;
+@@ -1131,7 +1130,7 @@ static void __exit nx_compress_powernv_e
+       if (!nx842_ct)
+               vas_unregister_api_powernv();
+-      crypto_unregister_alg(&nx842_powernv_alg);
++      crypto_unregister_scomp(&nx842_powernv_alg);
+       nx_delete_coprocs();
+ }
+--- a/drivers/crypto/nx/nx-common-pseries.c
++++ b/drivers/crypto/nx/nx-common-pseries.c
+@@ -11,6 +11,7 @@
+ #include <asm/vio.h>
+ #include <asm/hvcall.h>
+ #include <asm/vas.h>
++#include <crypto/internal/scompress.h>
+ #include "nx-842.h"
+ #include "nx_csbcpb.h" /* struct nx_csbcpb */
+@@ -1006,23 +1007,21 @@ static struct nx842_driver nx842_pseries
+       .decompress =   nx842_pseries_decompress,
+ };
+-static int nx842_pseries_crypto_init(struct crypto_tfm *tfm)
++static void *nx842_pseries_crypto_alloc_ctx(void)
+ {
+-      return nx842_crypto_init(tfm, &nx842_pseries_driver);
++      return nx842_crypto_alloc_ctx(&nx842_pseries_driver);
+ }
+-static struct crypto_alg nx842_pseries_alg = {
+-      .cra_name               = "842",
+-      .cra_driver_name        = "842-nx",
+-      .cra_priority           = 300,
+-      .cra_flags              = CRYPTO_ALG_TYPE_COMPRESS,
+-      .cra_ctxsize            = sizeof(struct nx842_crypto_ctx),
+-      .cra_module             = THIS_MODULE,
+-      .cra_init               = nx842_pseries_crypto_init,
+-      .cra_exit               = nx842_crypto_exit,
+-      .cra_u                  = { .compress = {
+-      .coa_compress           = nx842_crypto_compress,
+-      .coa_decompress         = nx842_crypto_decompress } }
++static struct scomp_alg nx842_pseries_alg = {
++      .base.cra_name          = "842",
++      .base.cra_driver_name   = "842-nx",
++      .base.cra_priority      = 300,
++      .base.cra_module        = THIS_MODULE,
++
++      .alloc_ctx              = nx842_pseries_crypto_alloc_ctx,
++      .free_ctx               = nx842_crypto_free_ctx,
++      .compress               = nx842_crypto_compress,
++      .decompress             = nx842_crypto_decompress,
+ };
+ static int nx842_probe(struct vio_dev *viodev,
+@@ -1070,7 +1069,7 @@ static int nx842_probe(struct vio_dev *v
+       if (ret)
+               goto error;
+-      ret = crypto_register_alg(&nx842_pseries_alg);
++      ret = crypto_register_scomp(&nx842_pseries_alg);
+       if (ret) {
+               dev_err(&viodev->dev, "could not register comp alg: %d\n", ret);
+               goto error;
+@@ -1118,7 +1117,7 @@ static void nx842_remove(struct vio_dev
+       if (caps_feat)
+               sysfs_remove_group(&viodev->dev.kobj, &nxcop_caps_attr_group);
+-      crypto_unregister_alg(&nx842_pseries_alg);
++      crypto_unregister_scomp(&nx842_pseries_alg);
+       spin_lock_irqsave(&devdata_mutex, flags);
+       old_devdata = rcu_dereference_check(devdata,
+@@ -1250,7 +1249,7 @@ static void __exit nx842_pseries_exit(vo
+       vas_unregister_api_pseries();
+-      crypto_unregister_alg(&nx842_pseries_alg);
++      crypto_unregister_scomp(&nx842_pseries_alg);
+       spin_lock_irqsave(&devdata_mutex, flags);
+       old_devdata = rcu_dereference_check(devdata,
diff --git a/queue-6.1/erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch b/queue-6.1/erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
new file mode 100644 (file)
index 0000000..e80a067
--- /dev/null
@@ -0,0 +1,58 @@
+From stable+bounces-244936-greg=kroah.com@vger.kernel.org Sat May  9 17:56:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  9 May 2026 08:26:09 -0400
+Subject: erofs: fix unsigned underflow in z_erofs_lz4_handle_overlap()
+To: stable@vger.kernel.org
+Cc: Junrui Luo <moonafterrain@outlook.com>, Yuhao Jiang <danisjiang@gmail.com>, Gao Xiang <hsiangkao@linux.alibaba.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509122609.3351909-1-sashal@kernel.org>
+
+From: Junrui Luo <moonafterrain@outlook.com>
+
+[ Upstream commit 21e161de2dc660b1bb70ef5b156ab8e6e1cca3ab ]
+
+Some crafted images can have illegal (!partial_decoding &&
+m_llen < m_plen) extents, and the LZ4 inplace decompression path
+can be wrongly hit, but it cannot handle (outpages < inpages)
+properly: "outpages - inpages" wraps to a large value and
+the subsequent rq->out[] access reads past the decompressed_pages
+array.
+
+However, such crafted cases can correctly result in a corruption
+report in the normal LZ4 non-inplace path.
+
+Let's add an additional check to fix this for backporting.
+
+Reproducible image (base64-encoded gzipped blob):
+
+H4sIAJGR12kCA+3SPUoDQRgG4MkmkkZk8QRbRFIIi9hbpEjrHQI5ghfwCN5BLCzTGtLbBI+g
+dilSJo1CnIm7GEXFxhT6PDDwfrs73/ywIQD/1ePD4r7Ou6ETsrq4mu7XcWfj++Pb58nJU/9i
+PNtbjhan04/9GtX4qVYc814WDqt6FaX5s+ZwXXeq52lndT6IuVvlblytLMvh4Gzwaf90nsvz
+2DF/21+20T/ldgp5s1jXRaN4t/8izsy/OUB6e/Qa79r+JwAAAAAAAL52vQVuGQAAAP6+my1w
+ywAAAAAAAADwu14ATsEYtgBQAAA=
+
+$ mount -t erofs -o cache_strategy=disabled foo.erofs /mnt
+$ dd if=/mnt/data of=/dev/null bs=4096 count=1
+
+Fixes: 598162d05080 ("erofs: support decompress big pcluster for lz4 backend")
+Reported-by: Yuhao Jiang <danisjiang@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
+Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
+[ inverted condition to early-out `goto docopy` form and used `ctx->inpages`/`ctx->outpages` instead of `rq->` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/erofs/decompressor.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/erofs/decompressor.c
++++ b/fs/erofs/decompressor.c
+@@ -133,6 +133,7 @@ static void *z_erofs_lz4_handle_overlap(
+       if (rq->inplace_io) {
+               omargin = PAGE_ALIGN(ctx->oend) - ctx->oend;
+               if (rq->partial_decoding || !may_inplace ||
++                  ctx->outpages < ctx->inpages ||
+                   omargin < LZ4_DECOMPRESS_INPLACE_MARGIN(rq->inputsize))
+                       goto docopy;
diff --git a/queue-6.1/f2fs-fix-false-alarm-of-lockdep-on-cp_global_sem-lock.patch b/queue-6.1/f2fs-fix-false-alarm-of-lockdep-on-cp_global_sem-lock.patch
new file mode 100644 (file)
index 0000000..1d86452
--- /dev/null
@@ -0,0 +1,102 @@
+From stable+bounces-249888-greg=kroah.com@vger.kernel.org Wed May 20 17:12:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 07:29:17 -0400
+Subject: f2fs: fix false alarm of lockdep on cp_global_sem lock
+To: stable@vger.kernel.org
+Cc: Chao Yu <chao@kernel.org>, stable@kernel.org, Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>, Jaegeuk Kim <jaegeuk@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520112917.3439771-1-sashal@kernel.org>
+
+From: Chao Yu <chao@kernel.org>
+
+[ Upstream commit 6a5e3de9c2bb0b691d16789a5d19e9276a09b308 ]
+
+lockdep reported a potential deadlock:
+
+a) TCMU device removal context:
+ - call del_gendisk() to get q->q_usage_counter
+ - call start_flush_work() to get work_completion of wb->dwork
+b) f2fs writeback context:
+ - in wb_workfn(), which holds work_completion of wb->dwork
+ - call f2fs_balance_fs() to get sbi->gc_lock
+c) f2fs vfs_write context:
+ - call f2fs_gc() to get sbi->gc_lock
+ - call f2fs_write_checkpoint() to get sbi->cp_global_sem
+d) f2fs mount context:
+ - call recover_fsync_data() to get sbi->cp_global_sem
+ - call f2fs_check_and_fix_write_pointer() to call blkdev_report_zones()
+   that goes down to blk_mq_alloc_request and get q->q_usage_counter
+
+Original callstack is in Closes tag.
+
+However, I think this is a false alarm due to before mount returns
+successfully (context d), we can not access file therein via vfs_write
+(context c).
+
+Let's introduce per-sb cp_global_sem_key, and assign the key for
+cp_global_sem, so that lockdep can recognize cp_global_sem from
+different super block correctly.
+
+A lot of work are done by Shin'ichiro Kawasaki, thanks a lot for
+the work.
+
+Fixes: c426d99127b1 ("f2fs: Check write pointer consistency of open zones")
+Cc: stable@kernel.org
+Reported-and-tested-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Closes: https://lore.kernel.org/linux-f2fs-devel/20260218125237.3340441-1-shinichiro.kawasaki@wdc.com
+Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com>
+Signed-off-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+[ re-anchored lockdep_register_key after init_f2fs_rwsem and placed lockdep_unregister_key before kfree(sbi) in f2fs_put_super instead of kill_f2fs_super ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/f2fs.h  |    3 +++
+ fs/f2fs/super.c |   11 +++++++++++
+ 2 files changed, 14 insertions(+)
+
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -1853,6 +1853,9 @@ struct f2fs_sb_info {
+       spinlock_t iostat_lat_lock;
+       struct iostat_lat_info *iostat_io_lat;
+ #endif
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++      struct lock_class_key cp_global_sem_key;
++#endif
+ };
+ #ifdef CONFIG_F2FS_FAULT_INJECTION
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -1687,6 +1687,9 @@ static void f2fs_put_super(struct super_
+ #if IS_ENABLED(CONFIG_UNICODE)
+       utf8_unload(sb->s_encoding);
+ #endif
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++      lockdep_unregister_key(&sbi->cp_global_sem_key);
++#endif
+       kfree(sbi);
+ }
+@@ -4188,6 +4191,11 @@ try_onemore:
+       init_f2fs_rwsem(&sbi->gc_lock);
+       mutex_init(&sbi->writepages);
+       init_f2fs_rwsem(&sbi->cp_global_sem);
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++      lockdep_register_key(&sbi->cp_global_sem_key);
++      lockdep_set_class(&sbi->cp_global_sem.internal_rwsem,
++                                      &sbi->cp_global_sem_key);
++#endif
+       init_f2fs_rwsem(&sbi->node_write);
+       init_f2fs_rwsem(&sbi->node_change);
+       spin_lock_init(&sbi->stat_lock);
+@@ -4651,6 +4659,9 @@ free_sb_buf:
+ free_sbi:
+       if (sbi->s_chksum_driver)
+               crypto_free_shash(sbi->s_chksum_driver);
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++      lockdep_unregister_key(&sbi->cp_global_sem_key);
++#endif
+       kfree(sbi);
+       /* give only one another chance */
diff --git a/queue-6.1/f2fs-fix-incorrect-file-address-mapping-when-inline-inode-is-unwritten.patch b/queue-6.1/f2fs-fix-incorrect-file-address-mapping-when-inline-inode-is-unwritten.patch
new file mode 100644 (file)
index 0000000..e5aff72
--- /dev/null
@@ -0,0 +1,68 @@
+From stable+bounces-249813-greg=kroah.com@vger.kernel.org Wed May 20 16:52:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 07:16:27 -0400
+Subject: f2fs: fix incorrect file address mapping when inline inode is unwritten
+To: stable@vger.kernel.org
+Cc: Yongpeng Yang <yangyongpeng@xiaomi.com>, stable@kernel.org, Chao Yu <chao@kernel.org>, Jaegeuk Kim <jaegeuk@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520111627.3416675-1-sashal@kernel.org>
+
+From: Yongpeng Yang <yangyongpeng@xiaomi.com>
+
+[ Upstream commit 68a0178981a0f493295afa29f8880246e561494c ]
+
+When `fileinfo->fi_flags` does not have the `FIEMAP_FLAG_SYNC` bit set
+and inline data has not been persisted yet, the physical address of the
+extent is calculated incorrectly for unwritten inline inodes.
+
+root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1
+root@vm:/mnt/f2fs# f2fs_io fiemap 0 100 data.3k
+Fiemap: offset = 0 len = 100
+       logical addr.    physical addr.   length           flags
+0      0000000000000000 00000ffffffff16c 0000000000000c00 00000301
+
+This patch fixes the issue by checking if the inode's address is valid.
+If the inline inode is unwritten, set the physical address to 0 and
+mark the extent with `FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC`
+flags.
+
+Cc: stable@kernel.org
+Fixes: 67f8cf3cee6f ("f2fs: support fiemap for inline_data")
+Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
+Reviewed-by: Chao Yu <chao@kernel.org>
+Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
+[ renamed `ifolio` to `ipage` in `inline_data_addr()` and `F2FS_INODE()` calls ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/f2fs/inline.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/fs/f2fs/inline.c
++++ b/fs/f2fs/inline.c
+@@ -774,7 +774,7 @@ int f2fs_read_inline_dir(struct file *fi
+ int f2fs_inline_data_fiemap(struct inode *inode,
+               struct fiemap_extent_info *fieinfo, __u64 start, __u64 len)
+ {
+-      __u64 byteaddr, ilen;
++      __u64 byteaddr = 0, ilen;
+       __u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
+               FIEMAP_EXTENT_LAST;
+       struct node_info ni;
+@@ -807,9 +807,14 @@ int f2fs_inline_data_fiemap(struct inode
+       if (err)
+               goto out;
+-      byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
+-      byteaddr += (char *)inline_data_addr(inode, ipage) -
+-                                      (char *)F2FS_INODE(ipage);
++      if (__is_valid_data_blkaddr(ni.blk_addr)) {
++              byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
++              byteaddr += (char *)inline_data_addr(inode, ipage) -
++                                              (char *)F2FS_INODE(ipage);
++      } else {
++              f2fs_bug_on(F2FS_I_SB(inode), ni.blk_addr != NEW_ADDR);
++              flags |= FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN;
++      }
+       err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags);
+       trace_f2fs_fiemap(inode, start, byteaddr, ilen, flags, err);
+ out:
diff --git a/queue-6.1/fbcon-avoid-oob-font-access-if-console-rotation-fails.patch b/queue-6.1/fbcon-avoid-oob-font-access-if-console-rotation-fails.patch
new file mode 100644 (file)
index 0000000..1599889
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-247665-greg=kroah.com@vger.kernel.org Fri May 15 17:31:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 07:31:45 -0400
+Subject: fbcon: Avoid OOB font access if console rotation fails
+To: stable@vger.kernel.org
+Cc: Thomas Zimmermann <tzimmermann@suse.de>, Helge Deller <deller@gmx.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515113145.2964271-1-sashal@kernel.org>
+
+From: Thomas Zimmermann <tzimmermann@suse.de>
+
+[ Upstream commit e4ef723d8975a2694cc90733a6b888a5e2841842 ]
+
+Clear the font buffer if the reallocation during console rotation fails
+in fbcon_rotate_font(). The putcs implementations for the rotated buffer
+will return early in this case. See [1] for an example.
+
+Currently, fbcon_rotate_font() keeps the old buffer, which is too small
+for the rotated font. Printing to the rotated console with a high-enough
+character code will overflow the font buffer.
+
+v2:
+- fix typos in commit message
+
+Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
+Fixes: 6cc50e1c5b57 ("[PATCH] fbcon: Console Rotation - Add support to rotate font bitmap")
+Cc: stable@vger.kernel.org # v2.6.15+
+Link: https://elixir.bootlin.com/linux/v6.19/source/drivers/video/fbdev/core/fbcon_ccw.c#L144 # [1]
+Signed-off-by: Helge Deller <deller@gmx.de>
+[ renamed `par` to `ops` to match the 6.12 local pointer name ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/video/fbdev/core/fbcon_rotate.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/video/fbdev/core/fbcon_rotate.c
++++ b/drivers/video/fbdev/core/fbcon_rotate.c
+@@ -46,6 +46,10 @@ static int fbcon_rotate_font(struct fb_i
+               info->fbops->fb_sync(info);
+       if (ops->fd_size < d_cellsize * len) {
++              kfree(ops->fontbuffer);
++              ops->fontbuffer = NULL;
++              ops->fd_size = 0;
++
+               dst = kmalloc_array(len, d_cellsize, GFP_KERNEL);
+               if (dst == NULL) {
+@@ -54,7 +58,6 @@ static int fbcon_rotate_font(struct fb_i
+               }
+               ops->fd_size = d_cellsize * len;
+-              kfree(ops->fontbuffer);
+               ops->fontbuffer = dst;
+       }
diff --git a/queue-6.1/genetlink-use-internal-flags-for-multicast-groups.patch b/queue-6.1/genetlink-use-internal-flags-for-multicast-groups.patch
new file mode 100644 (file)
index 0000000..ccf91f0
--- /dev/null
@@ -0,0 +1,116 @@
+From stable+bounces-256667-greg=kroah.com@vger.kernel.org Fri May 29 22:36:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 13:06:09 -0400
+Subject: genetlink: Use internal flags for multicast groups
+To: stable@vger.kernel.org
+Cc: Ido Schimmel <idosch@nvidia.com>, Mat Martineau <martineau@kernel.org>, Andy Shevchenko <andriy.shevchenko@linux.intel.com>, "David S. Miller" <davem@davemloft.net>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529170610.1279657-1-sashal@kernel.org>
+
+From: Ido Schimmel <idosch@nvidia.com>
+
+[ Upstream commit cd4d7263d58ab98fd4dee876776e4da6c328faa3 ]
+
+As explained in commit e03781879a0d ("drop_monitor: Require
+'CAP_SYS_ADMIN' when joining "events" group"), the "flags" field in the
+multicast group structure reuses uAPI flags despite the field not being
+exposed to user space. This makes it impossible to extend its use
+without adding new uAPI flags, which is inappropriate for internal
+kernel checks.
+
+Solve this by adding internal flags (i.e., "GENL_MCAST_*") and convert
+the existing users to use them instead of the uAPI flags.
+
+Tested using the reproducers in commit 44ec98ea5ea9 ("psample: Require
+'CAP_NET_ADMIN' when joining "packets" group") and commit e03781879a0d
+("drop_monitor: Require 'CAP_SYS_ADMIN' when joining "events" group").
+
+No functional changes intended.
+
+Signed-off-by: Ido Schimmel <idosch@nvidia.com>
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: d1ebfce2c1d1 ("smb: client: require net admin for CIFS SWN netlink")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/genetlink.h |    9 ++++++---
+ net/core/drop_monitor.c |    2 +-
+ net/mptcp/pm_netlink.c  |    2 +-
+ net/netlink/genetlink.c |    4 ++--
+ net/psample/psample.c   |    2 +-
+ 5 files changed, 11 insertions(+), 8 deletions(-)
+
+--- a/include/net/genetlink.h
++++ b/include/net/genetlink.h
+@@ -8,16 +8,19 @@
+ #define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
++/* Binding to multicast group requires %CAP_NET_ADMIN */
++#define GENL_MCAST_CAP_NET_ADMIN      BIT(0)
++/* Binding to multicast group requires %CAP_SYS_ADMIN */
++#define GENL_MCAST_CAP_SYS_ADMIN      BIT(1)
++
+ /**
+  * struct genl_multicast_group - generic netlink multicast group
+  * @name: name of the multicast group, names are per-family
+- * @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
+- * @cap_sys_admin: whether %CAP_SYS_ADMIN is required for binding
++ * @flags: GENL_MCAST_* flags
+  */
+ struct genl_multicast_group {
+       char                    name[GENL_NAMSIZ];
+       u8                      flags;
+-      u8                      cap_sys_admin:1;
+ };
+ struct genl_ops;
+--- a/net/core/drop_monitor.c
++++ b/net/core/drop_monitor.c
+@@ -181,7 +181,7 @@ out:
+ }
+ static const struct genl_multicast_group dropmon_mcgrps[] = {
+-      { .name = "events", .cap_sys_admin = 1 },
++      { .name = "events", .flags = GENL_MCAST_CAP_SYS_ADMIN, },
+ };
+ static void send_dm_alert(struct work_struct *work)
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -1313,7 +1313,7 @@ bool mptcp_pm_nl_is_backup(struct mptcp_
+ static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
+       [MPTCP_PM_CMD_GRP_OFFSET]       = { .name = MPTCP_PM_CMD_GRP_NAME, },
+       [MPTCP_PM_EV_GRP_OFFSET]        = { .name = MPTCP_PM_EV_GRP_NAME,
+-                                          .flags = GENL_UNS_ADMIN_PERM,
++                                          .flags = GENL_MCAST_CAP_NET_ADMIN,
+                                         },
+ };
+--- a/net/netlink/genetlink.c
++++ b/net/netlink/genetlink.c
+@@ -1431,10 +1431,10 @@ static int genl_bind(struct net *net, in
+                       continue;
+               grp = &family->mcgrps[i];
+-              if ((grp->flags & GENL_UNS_ADMIN_PERM) &&
++              if ((grp->flags & GENL_MCAST_CAP_NET_ADMIN) &&
+                   !ns_capable(net->user_ns, CAP_NET_ADMIN))
+                       ret = -EPERM;
+-              if (grp->cap_sys_admin &&
++              if ((grp->flags & GENL_MCAST_CAP_SYS_ADMIN) &&
+                   !ns_capable(net->user_ns, CAP_SYS_ADMIN))
+                       ret = -EPERM;
+--- a/net/psample/psample.c
++++ b/net/psample/psample.c
+@@ -32,7 +32,7 @@ enum psample_nl_multicast_groups {
+ static const struct genl_multicast_group psample_nl_mcgrps[] = {
+       [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
+       [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME,
+-                                    .flags = GENL_UNS_ADMIN_PERM },
++                                    .flags = GENL_MCAST_CAP_NET_ADMIN, },
+ };
+ static struct genl_family psample_nl_family __ro_after_init;
diff --git a/queue-6.1/hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch b/queue-6.1/hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch
new file mode 100644 (file)
index 0000000..6dedc97
--- /dev/null
@@ -0,0 +1,142 @@
+From stable+bounces-244868-greg=kroah.com@vger.kernel.org Sat May  9 06:28:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 20:58:08 -0400
+Subject: hfsplus: fix held lock freed on hfsplus_fill_super()
+To: stable@vger.kernel.org
+Cc: Zilin Guan <zilin@seu.edu.cn>, Viacheslav Dubeyko <slava@dubeyko.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509005809.2569358-2-sashal@kernel.org>
+
+From: Zilin Guan <zilin@seu.edu.cn>
+
+[ Upstream commit 90c500e4fd83fa33c09bc7ee23b6d9cc487ac733 ]
+
+hfsplus_fill_super() calls hfs_find_init() to initialize a search
+structure, which acquires tree->tree_lock. If the subsequent call to
+hfsplus_cat_build_key() fails, the function jumps to the out_put_root
+error label without releasing the lock. The later cleanup path then
+frees the tree data structure with the lock still held, triggering a
+held lock freed warning.
+
+Fix this by adding the missing hfs_find_exit(&fd) call before jumping
+to the out_put_root error label. This ensures that tree->tree_lock is
+properly released on the error path.
+
+The bug was originally detected on v6.13-rc1 using an experimental
+static analysis tool we are developing, and we have verified that the
+issue persists in the latest mainline kernel. The tool is specifically
+designed to detect memory management issues. It is currently under active
+development and not yet publicly available.
+
+We confirmed the bug by runtime testing under QEMU with x86_64 defconfig,
+lockdep enabled, and CONFIG_HFSPLUS_FS=y. To trigger the error path, we
+used GDB to dynamically shrink the max_unistr_len parameter to 1 before
+hfsplus_asc2uni() is called. This forces hfsplus_asc2uni() to naturally
+return -ENAMETOOLONG, which propagates to hfsplus_cat_build_key() and
+exercises the faulty error path. The following warning was observed
+during mount:
+
+       =========================
+       WARNING: held lock freed!
+       7.0.0-rc3-00016-gb4f0dd314b39 #4 Not tainted
+       -------------------------
+       mount/174 is freeing memory ffff888103f92000-ffff888103f92fff, with a lock still held there!
+       ffff888103f920b0 (&tree->tree_lock){+.+.}-{4:4}, at: hfsplus_find_init+0x154/0x1e0
+       2 locks held by mount/174:
+       #0: ffff888103f960e0 (&type->s_umount_key#42/1){+.+.}-{4:4}, at: alloc_super.constprop.0+0x167/0xa40
+       #1: ffff888103f920b0 (&tree->tree_lock){+.+.}-{4:4}, at: hfsplus_find_init+0x154/0x1e0
+
+       stack backtrace:
+       CPU: 2 UID: 0 PID: 174 Comm: mount Not tainted 7.0.0-rc3-00016-gb4f0dd314b39 #4 PREEMPT(lazy)
+       Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014
+       Call Trace:
+       <TASK>
+       dump_stack_lvl+0x82/0xd0
+       debug_check_no_locks_freed+0x13a/0x180
+       kfree+0x16b/0x510
+       ? hfsplus_fill_super+0xcb4/0x18a0
+       hfsplus_fill_super+0xcb4/0x18a0
+       ? __pfx_hfsplus_fill_super+0x10/0x10
+       ? srso_return_thunk+0x5/0x5f
+       ? bdev_open+0x65f/0xc30
+       ? srso_return_thunk+0x5/0x5f
+       ? pointer+0x4ce/0xbf0
+       ? trace_contention_end+0x11c/0x150
+       ? __pfx_pointer+0x10/0x10
+       ? srso_return_thunk+0x5/0x5f
+       ? bdev_open+0x79b/0xc30
+       ? srso_return_thunk+0x5/0x5f
+       ? srso_return_thunk+0x5/0x5f
+       ? vsnprintf+0x6da/0x1270
+       ? srso_return_thunk+0x5/0x5f
+       ? __mutex_unlock_slowpath+0x157/0x740
+       ? __pfx_vsnprintf+0x10/0x10
+       ? srso_return_thunk+0x5/0x5f
+       ? srso_return_thunk+0x5/0x5f
+       ? mark_held_locks+0x49/0x80
+       ? srso_return_thunk+0x5/0x5f
+       ? srso_return_thunk+0x5/0x5f
+       ? irqentry_exit+0x17b/0x5e0
+       ? trace_irq_disable.constprop.0+0x116/0x150
+       ? __pfx_hfsplus_fill_super+0x10/0x10
+       ? __pfx_hfsplus_fill_super+0x10/0x10
+       get_tree_bdev_flags+0x302/0x580
+       ? __pfx_get_tree_bdev_flags+0x10/0x10
+       ? vfs_parse_fs_qstr+0x129/0x1a0
+       ? __pfx_vfs_parse_fs_qstr+0x3/0x10
+       vfs_get_tree+0x89/0x320
+       fc_mount+0x10/0x1d0
+       path_mount+0x5c5/0x21c0
+       ? __pfx_path_mount+0x10/0x10
+       ? trace_irq_enable.constprop.0+0x116/0x150
+       ? trace_irq_enable.constprop.0+0x116/0x150
+       ? srso_return_thunk+0x5/0x5f
+       ? srso_return_thunk+0x5/0x5f
+       ? kmem_cache_free+0x307/0x540
+       ? user_path_at+0x51/0x60
+       ? __x64_sys_mount+0x212/0x280
+       ? srso_return_thunk+0x5/0x5f
+       __x64_sys_mount+0x212/0x280
+       ? __pfx___x64_sys_mount+0x10/0x10
+       ? srso_return_thunk+0x5/0x5f
+       ? trace_irq_enable.constprop.0+0x116/0x150
+       ? srso_return_thunk+0x5/0x5f
+       do_syscall_64+0x111/0x680
+       entry_SYSCALL_64_after_hwframe+0x77/0x7f
+       RIP: 0033:0x7ffacad55eae
+       Code: 48 8b 0d 85 1f 0f 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 49 89 ca b8 a5 00 00 8
+       RSP: 002b:00007fff1ab55718 EFLAGS: 00000246 ORIG_RAX: 00000000000000a5
+       RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007ffacad55eae
+       RDX: 000055740c64e5b0 RSI: 000055740c64e630 RDI: 000055740c651ab0
+       RBP: 000055740c64e380 R08: 0000000000000000 R09: 0000000000000001
+       R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
+       R13: 000055740c64e5b0 R14: 000055740c651ab0 R15: 000055740c64e380
+       </TASK>
+
+After applying this patch, the warning no longer appears.
+
+Fixes: 89ac9b4d3d1a ("hfsplus: fix longname handling")
+CC: stable@vger.kernel.org
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Tested-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfsplus/super.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/hfsplus/super.c
++++ b/fs/hfsplus/super.c
+@@ -539,8 +539,10 @@ static int hfsplus_fill_super(struct sup
+       if (err)
+               goto out_put_root;
+       err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
+-      if (unlikely(err < 0))
++      if (unlikely(err < 0)) {
++              hfs_find_exit(&fd);
+               goto out_put_root;
++      }
+       if (!hfsplus_brec_read_cat(&fd, &entry)) {
+               hfs_find_exit(&fd);
+               if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
diff --git a/queue-6.1/hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch b/queue-6.1/hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch
new file mode 100644 (file)
index 0000000..81851f6
--- /dev/null
@@ -0,0 +1,189 @@
+From stable+bounces-244867-greg=kroah.com@vger.kernel.org Sat May  9 06:28:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 20:58:07 -0400
+Subject: hfsplus: fix uninit-value by validating catalog record size
+To: stable@vger.kernel.org
+Cc: Deepanshu Kartikey <kartikey406@gmail.com>, syzbot+d80abb5b890d39261e72@syzkaller.appspotmail.com, Viacheslav Dubeyko <slava@dubeyko.com>, Charalampos Mitrodimas <charmitro@posteo.net>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260509005809.2569358-1-sashal@kernel.org>
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit b6b592275aeff184aa82fcf6abccd833fb71b393 ]
+
+Syzbot reported a KMSAN uninit-value issue in hfsplus_strcasecmp(). The
+root cause is that hfs_brec_read() doesn't validate that the on-disk
+record size matches the expected size for the record type being read.
+
+When mounting a corrupted filesystem, hfs_brec_read() may read less data
+than expected. For example, when reading a catalog thread record, the
+debug output showed:
+
+  HFSPLUS_BREC_READ: rec_len=520, fd->entrylength=26
+  HFSPLUS_BREC_READ: WARNING - entrylength (26) < rec_len (520) - PARTIAL READ!
+
+hfs_brec_read() only validates that entrylength is not greater than the
+buffer size, but doesn't check if it's less than expected. It successfully
+reads 26 bytes into a 520-byte structure and returns success, leaving 494
+bytes uninitialized.
+
+This uninitialized data in tmp.thread.nodeName then gets copied by
+hfsplus_cat_build_key_uni() and used by hfsplus_strcasecmp(), triggering
+the KMSAN warning when the uninitialized bytes are used as array indices
+in case_fold().
+
+Fix by introducing hfsplus_brec_read_cat() wrapper that:
+1. Calls hfs_brec_read() to read the data
+2. Validates the record size based on the type field:
+   - Fixed size for folder and file records
+   - Variable size for thread records (depends on string length)
+3. Returns -EIO if size doesn't match expected
+
+For thread records, check against HFSPLUS_MIN_THREAD_SZ before reading
+nodeName.length to avoid reading uninitialized data at call sites that
+don't zero-initialize the entry structure.
+
+Also initialize the tmp variable in hfsplus_find_cat() as defensive
+programming to ensure no uninitialized data even if validation is
+bypassed.
+
+Reported-by: syzbot+d80abb5b890d39261e72@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=d80abb5b890d39261e72
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Tested-by: syzbot+d80abb5b890d39261e72@syzkaller.appspotmail.com
+Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Tested-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Suggested-by: Charalampos Mitrodimas <charmitro@posteo.net>
+Link: https://lore.kernel.org/all/20260120051114.1281285-1-kartikey406@gmail.com/ [v1]
+Link: https://lore.kernel.org/all/20260121063109.1830263-1-kartikey406@gmail.com/ [v2]
+Link: https://lore.kernel.org/all/20260212014233.2422046-1-kartikey406@gmail.com/ [v3]
+Link: https://lore.kernel.org/all/20260214002100.436125-1-kartikey406@gmail.com/T/ [v4]
+Link: https://lore.kernel.org/all/20260221061626.15853-1-kartikey406@gmail.com/T/ [v5]
+Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Link: https://lore.kernel.org/r/20260307010302.41547-1-kartikey406@gmail.com
+Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
+Stable-dep-of: 90c500e4fd83 ("hfsplus: fix held lock freed on hfsplus_fill_super()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/hfsplus/bfind.c      |   51 ++++++++++++++++++++++++++++++++++++++++++++++++
+ fs/hfsplus/catalog.c    |    4 +--
+ fs/hfsplus/dir.c        |    2 -
+ fs/hfsplus/hfsplus_fs.h |    9 ++++++++
+ fs/hfsplus/super.c      |    2 -
+ 5 files changed, 64 insertions(+), 4 deletions(-)
+
+--- a/fs/hfsplus/bfind.c
++++ b/fs/hfsplus/bfind.c
+@@ -287,3 +287,54 @@ out:
+       fd->bnode = bnode;
+       return res;
+ }
++
++/**
++ * hfsplus_brec_read_cat - read and validate a catalog record
++ * @fd: find data structure
++ * @entry: pointer to catalog entry to read into
++ *
++ * Reads a catalog record and validates its size matches the expected
++ * size based on the record type.
++ *
++ * Returns 0 on success, or negative error code on failure.
++ */
++int hfsplus_brec_read_cat(struct hfs_find_data *fd, hfsplus_cat_entry *entry)
++{
++      int res;
++      u32 expected_size;
++
++      res = hfs_brec_read(fd, entry, sizeof(hfsplus_cat_entry));
++      if (res)
++              return res;
++
++      /* Validate catalog record size based on type */
++      switch (be16_to_cpu(entry->type)) {
++      case HFSPLUS_FOLDER:
++              expected_size = sizeof(struct hfsplus_cat_folder);
++              break;
++      case HFSPLUS_FILE:
++              expected_size = sizeof(struct hfsplus_cat_file);
++              break;
++      case HFSPLUS_FOLDER_THREAD:
++      case HFSPLUS_FILE_THREAD:
++              /* Ensure we have at least the fixed fields before reading nodeName.length */
++              if (fd->entrylength < HFSPLUS_MIN_THREAD_SZ) {
++                      pr_err("thread record too short (got %u)\n", fd->entrylength);
++                      return -EIO;
++              }
++              expected_size = hfsplus_cat_thread_size(&entry->thread);
++              break;
++      default:
++              pr_err("unknown catalog record type %d\n",
++                     be16_to_cpu(entry->type));
++              return -EIO;
++      }
++
++      if (fd->entrylength != expected_size) {
++              pr_err("catalog record size mismatch (type %d, got %u, expected %u)\n",
++                     be16_to_cpu(entry->type), fd->entrylength, expected_size);
++              return -EIO;
++      }
++
++      return 0;
++}
+--- a/fs/hfsplus/catalog.c
++++ b/fs/hfsplus/catalog.c
+@@ -194,12 +194,12 @@ static int hfsplus_fill_cat_thread(struc
+ int hfsplus_find_cat(struct super_block *sb, u32 cnid,
+                    struct hfs_find_data *fd)
+ {
+-      hfsplus_cat_entry tmp;
++      hfsplus_cat_entry tmp = {0};
+       int err;
+       u16 type;
+       hfsplus_cat_build_key_with_cnid(sb, fd->search_key, cnid);
+-      err = hfs_brec_read(fd, &tmp, sizeof(hfsplus_cat_entry));
++      err = hfsplus_brec_read_cat(fd, &tmp);
+       if (err)
+               return err;
+--- a/fs/hfsplus/dir.c
++++ b/fs/hfsplus/dir.c
+@@ -49,7 +49,7 @@ static struct dentry *hfsplus_lookup(str
+       if (unlikely(err < 0))
+               goto fail;
+ again:
+-      err = hfs_brec_read(&fd, &entry, sizeof(entry));
++      err = hfsplus_brec_read_cat(&fd, &entry);
+       if (err) {
+               if (err == -ENOENT) {
+                       hfs_find_exit(&fd);
+--- a/fs/hfsplus/hfsplus_fs.h
++++ b/fs/hfsplus/hfsplus_fs.h
+@@ -535,6 +535,15 @@ int hfsplus_submit_bio(struct super_bloc
+                      void **data, blk_opf_t opf);
+ int hfsplus_read_wrapper(struct super_block *sb);
++static inline u32 hfsplus_cat_thread_size(const struct hfsplus_cat_thread *thread)
++{
++      return offsetof(struct hfsplus_cat_thread, nodeName) +
++             offsetof(struct hfsplus_unistr, unicode) +
++             be16_to_cpu(thread->nodeName.length) * sizeof(hfsplus_unichr);
++}
++
++int hfsplus_brec_read_cat(struct hfs_find_data *fd, hfsplus_cat_entry *entry);
++
+ /*
+  * time helpers: convert between 1904-base and 1970-base timestamps
+  *
+--- a/fs/hfsplus/super.c
++++ b/fs/hfsplus/super.c
+@@ -541,7 +541,7 @@ static int hfsplus_fill_super(struct sup
+       err = hfsplus_cat_build_key(sb, fd.search_key, HFSPLUS_ROOT_CNID, &str);
+       if (unlikely(err < 0))
+               goto out_put_root;
+-      if (!hfs_brec_read(&fd, &entry, sizeof(entry))) {
++      if (!hfsplus_brec_read_cat(&fd, &entry)) {
+               hfs_find_exit(&fd);
+               if (entry.type != cpu_to_be16(HFSPLUS_FOLDER)) {
+                       err = -EIO;
diff --git a/queue-6.1/hv_netvsc-use-kmap_local_page-in-netvsc_copy_to_send_buf.patch b/queue-6.1/hv_netvsc-use-kmap_local_page-in-netvsc_copy_to_send_buf.patch
new file mode 100644 (file)
index 0000000..1fc27a7
--- /dev/null
@@ -0,0 +1,92 @@
+From stable+bounces-263427-greg=kroah.com@vger.kernel.org Mon Jun 15 23:43:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 14:13:00 -0400
+Subject: hv_netvsc: use kmap_local_page in netvsc_copy_to_send_buf
+To: stable@vger.kernel.org
+Cc: Anton Leontev <leontyevantony@gmail.com>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260615181300.2319407-1-sashal@kernel.org>
+
+From: Anton Leontev <leontyevantony@gmail.com>
+
+[ Upstream commit 004e9ecfe6c5384f9e0b2f6f6389d42ec22789af ]
+
+netvsc_copy_to_send_buf() copies page buffer entries into the VMBus
+send buffer using phys_to_virt() on the entry PFN. Entries for the
+RNDIS header and the skb linear data come from kmalloc'd memory and
+are always in the kernel direct map, but entries for skb fragments
+reference page cache or user pages, which on 32-bit x86 with
+CONFIG_HIGHMEM=y can live above the LOWMEM boundary. For such a page
+phys_to_virt() returns an address outside the direct map and the
+subsequent memcpy() faults on the transmit softirq path, which is
+fatal.
+
+Map the pages with kmap_local_page() instead, handling two properties
+of the page buffer entries:
+
+ - pb[i].pfn is a Hyper-V PFN at HV_HYP_PAGE_SIZE (4K) granularity,
+   not a native PFN. Reconstruct the physical address first and derive
+   the native page from it, so the mapping stays correct where
+   PAGE_SIZE > HV_HYP_PAGE_SIZE (e.g. arm64 with 64K pages).
+
+ - Since commit 41a6328b2c55 ("hv_netvsc: Preserve contiguous PFN
+   grouping in the page buffer array"), an entry describes a full
+   physically contiguous fragment and pb[i].len can exceed PAGE_SIZE,
+   while kmap_local_page() maps a single page. Copy page by page,
+   splitting at native page boundaries.
+
+The copy path only handles packets smaller than the send section size
+(6144 bytes by default); larger packets take the cp_partial path where
+only the RNDIS header is copied. So entries here are bounded by the
+section size and a copy is split at most once on 4K-page systems. On
+!CONFIG_HIGHMEM configs kmap_local_page() folds to page_address() and
+no mapping work is added.
+
+Fixes: c25aaf814a63 ("hyperv: Enable sendbuf mechanism on the send path")
+Cc: stable@vger.kernel.org
+Signed-off-by: Anton Leontev <leontyevantony@gmail.com>
+Link: https://patch.msgid.link/20260604165938.32033-1-leontyevantony@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+[ adapted `phys_to_page(paddr)` to `pfn_to_page(PHYS_PFN(paddr))` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/hyperv/netvsc.c |   19 +++++++++++++++----
+ 1 file changed, 15 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/hyperv/netvsc.c
++++ b/drivers/net/hyperv/netvsc.c
+@@ -12,6 +12,7 @@
+ #include <linux/sched.h>
+ #include <linux/wait.h>
+ #include <linux/mm.h>
++#include <linux/highmem.h>
+ #include <linux/delay.h>
+ #include <linux/io.h>
+ #include <linux/slab.h>
+@@ -992,12 +993,22 @@ static void netvsc_copy_to_send_buf(stru
+       }
+       for (i = 0; i < page_count; i++) {
+-              char *src = phys_to_virt(pb[i].pfn << HV_HYP_PAGE_SHIFT);
+-              u32 offset = pb[i].offset;
++              phys_addr_t paddr = (pb[i].pfn << HV_HYP_PAGE_SHIFT) +
++                                  pb[i].offset;
+               u32 len = pb[i].len;
+-              memcpy(dest, (src + offset), len);
+-              dest += len;
++              while (len) {
++                      struct page *page = pfn_to_page(PHYS_PFN(paddr));
++                      u32 off = offset_in_page(paddr);
++                      u32 chunk = min_t(u32, len, PAGE_SIZE - off);
++                      char *src = kmap_local_page(page);
++
++                      memcpy(dest, src + off, chunk);
++                      kunmap_local(src);
++                      dest += chunk;
++                      paddr += chunk;
++                      len -= chunk;
++              }
+       }
+       if (padding)
diff --git a/queue-6.1/ice-fix-vf-queue-configuration-with-low-mtu-values.patch b/queue-6.1/ice-fix-vf-queue-configuration-with-low-mtu-values.patch
new file mode 100644 (file)
index 0000000..2db4d2e
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-256850-greg=kroah.com@vger.kernel.org Sat May 30 06:53:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 21:23:43 -0400
+Subject: ice: fix VF queue configuration with low MTU values
+To: stable@vger.kernel.org
+Cc: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>, Jacob Keller <jacob.e.keller@intel.com>, Michal Swiatkowski <michal.swiatkowski@linux.intel.com>, Paul Menzel <pmenzel@molgen.mpg.de>, Rafal Romanowski <rafal.romanowski@intel.com>, Tony Nguyen <anthony.l.nguyen@intel.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530012343.2600440-1-sashal@kernel.org>
+
+From: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+
+[ Upstream commit 3ba4dd024d26372733d1c02e13e076c6016e3320 ]
+
+The ice driver's VF queue configuration validation rejects
+databuffer_size values below 1024 bytes, which prevents VFs from
+using MTU values below 871 bytes.
+
+The iavf driver calculates databuffer_size based on the MTU using:
+  databuffer_size = ALIGN(MTU + LIBETH_RX_LL_LEN, 128)
+
+where LIBETH_RX_LL_LEN = 26 (ETH_HLEN + 2*VLAN_HLEN + ETH_FCS_LEN).
+
+For MTU values below 871:
+  MTU 870: 870 + 26 = 896, aligned to 128 = 896 (< 1024, rejected)
+  MTU 871: 871 + 26 = 897, aligned to 128 = 1024 (>= 1024, accepted)
+
+The 1024-byte minimum seems unnecessarily restrictive, because the hardware
+supports databuffer_size as low as 128 bytes (the alignment boundary),
+which should allow MTU values down to the standard minimum of 68 bytes.
+
+I haven't found the reason why the limit was configured in the commit
+9c7dd7566d18 ("ice: add validation in OP_CONFIG_VSI_QUEUES VF message"), so
+with no more information and since it is working, change the minimum
+databuffer_size validation from 1024 to 128 bytes to allow standard low
+MTU values while still preventing invalid configurations.
+
+Fixes: 9c7dd7566d18 ("ice: add validation in OP_CONFIG_VSI_QUEUES VF message")
+cc: stable@vger.kernel.org
+Signed-off-by: Jose Ignacio Tornos Martinez <jtornosm@redhat.com>
+Reviewed-by: Jacob Keller <jacob.e.keller@intel.com>
+Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com>
+Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
+Tested-by: Rafal Romanowski <rafal.romanowski@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Link: https://patch.msgid.link/20260515182419.1597859-3-anthony.l.nguyen@intel.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied the change to ice_virtchnl.c ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/intel/ice/ice_virtchnl.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/intel/ice/ice_virtchnl.c
++++ b/drivers/net/ethernet/intel/ice/ice_virtchnl.c
+@@ -1648,7 +1648,7 @@ static int ice_vc_cfg_qs_msg(struct ice_
+                       if (qpi->rxq.databuffer_size != 0 &&
+                           (qpi->rxq.databuffer_size > ((16 * 1024) - 128) ||
+-                           qpi->rxq.databuffer_size < 1024))
++                           qpi->rxq.databuffer_size < 128))
+                               goto error_param;
+                       vsi->rx_buf_len = qpi->rxq.databuffer_size;
+                       vsi->rx_rings[i]->rx_buf_len = vsi->rx_buf_len;
diff --git a/queue-6.1/iio-adc-fix-the-return-value-handle-for-platform_get_irq.patch b/queue-6.1/iio-adc-fix-the-return-value-handle-for-platform_get_irq.patch
new file mode 100644 (file)
index 0000000..7af6578
--- /dev/null
@@ -0,0 +1,81 @@
+From stable+bounces-260504-greg=kroah.com@vger.kernel.org Thu Jun  4 19:33:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 09:54:45 -0400
+Subject: iio: adc: fix the return value handle for platform_get_irq()
+To: stable@vger.kernel.org
+Cc: Ruan Jinjie <ruanjinjie@huawei.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604135447.3493139-1-sashal@kernel.org>
+
+From: Ruan Jinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit c09ddcdd4dd32ee9768dc233ead4b3d726f26d38 ]
+
+There is no possible for platform_get_irq() to return 0
+and the return value of platform_get_irq() is more sensible
+to show the error reason.
+
+Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20230727131607.2897937-1-ruanjinjie@huawei.com
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 0d42e2c0bd6c ("iio: adc: npcm: fix unbalanced clk_disable_unprepare()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/bcm_iproc_adc.c |    4 ++--
+ drivers/iio/adc/lpc32xx_adc.c   |    4 ++--
+ drivers/iio/adc/npcm_adc.c      |    4 ++--
+ drivers/iio/adc/spear_adc.c     |    4 ++--
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+--- a/drivers/iio/adc/bcm_iproc_adc.c
++++ b/drivers/iio/adc/bcm_iproc_adc.c
+@@ -540,8 +540,8 @@ static int iproc_adc_probe(struct platfo
+       }
+       adc_priv->irqno = platform_get_irq(pdev, 0);
+-      if (adc_priv->irqno <= 0)
+-              return -ENODEV;
++      if (adc_priv->irqno < 0)
++              return adc_priv->irqno;
+       ret = regmap_update_bits(adc_priv->regmap, IPROC_REGCTL2,
+                               IPROC_ADC_AUXIN_SCAN_ENA, 0);
+--- a/drivers/iio/adc/lpc32xx_adc.c
++++ b/drivers/iio/adc/lpc32xx_adc.c
+@@ -173,8 +173,8 @@ static int lpc32xx_adc_probe(struct plat
+       }
+       irq = platform_get_irq(pdev, 0);
+-      if (irq <= 0)
+-              return -ENXIO;
++      if (irq < 0)
++              return irq;
+       retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
+                                 LPC32XXAD_NAME, st);
+--- a/drivers/iio/adc/npcm_adc.c
++++ b/drivers/iio/adc/npcm_adc.c
+@@ -244,8 +244,8 @@ static int npcm_adc_probe(struct platfor
+       info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2);
+       irq = platform_get_irq(pdev, 0);
+-      if (irq <= 0) {
+-              ret = -EINVAL;
++      if (irq < 0) {
++              ret = irq;
+               goto err_disable_clk;
+       }
+--- a/drivers/iio/adc/spear_adc.c
++++ b/drivers/iio/adc/spear_adc.c
+@@ -311,8 +311,8 @@ static int spear_adc_probe(struct platfo
+       }
+       irq = platform_get_irq(pdev, 0);
+-      if (irq <= 0) {
+-              ret = -EINVAL;
++      if (irq < 0) {
++              ret = irq;
+               goto errout2;
+       }
diff --git a/queue-6.1/iio-adc-npcm-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/iio-adc-npcm-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..3af4072
--- /dev/null
@@ -0,0 +1,60 @@
+From stable+bounces-260505-greg=kroah.com@vger.kernel.org Thu Jun  4 19:35:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 09:54:46 -0400
+Subject: iio: adc: npcm: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Jonathan Cameron" <Jonathan.Cameron@huawei.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260604135447.3493139-2-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 5253a5cc7709688b9a000f7928bfaa3366d0af98 ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new() which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20230919174931.1417681-18-u.kleine-koenig@pengutronix.de
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 0d42e2c0bd6c ("iio: adc: npcm: fix unbalanced clk_disable_unprepare()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/npcm_adc.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/iio/adc/npcm_adc.c
++++ b/drivers/iio/adc/npcm_adc.c
+@@ -320,7 +320,7 @@ err_disable_clk:
+       return ret;
+ }
+-static int npcm_adc_remove(struct platform_device *pdev)
++static void npcm_adc_remove(struct platform_device *pdev)
+ {
+       struct iio_dev *indio_dev = platform_get_drvdata(pdev);
+       struct npcm_adc *info = iio_priv(indio_dev);
+@@ -333,13 +333,11 @@ static int npcm_adc_remove(struct platfo
+       if (!IS_ERR(info->vref))
+               regulator_disable(info->vref);
+       clk_disable_unprepare(info->adc_clk);
+-
+-      return 0;
+ }
+ static struct platform_driver npcm_adc_driver = {
+       .probe          = npcm_adc_probe,
+-      .remove         = npcm_adc_remove,
++      .remove_new     = npcm_adc_remove,
+       .driver         = {
+               .name   = "npcm_adc",
+               .of_match_table = npcm_adc_match,
diff --git a/queue-6.1/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch b/queue-6.1/iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
new file mode 100644 (file)
index 0000000..260c8e9
--- /dev/null
@@ -0,0 +1,112 @@
+From stable+bounces-260506-greg=kroah.com@vger.kernel.org Thu Jun  4 19:46:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 09:54:47 -0400
+Subject: iio: adc: npcm: fix unbalanced clk_disable_unprepare()
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604135447.3493139-3-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit 0d42e2c0bd6ceb89e44c6e065f9bdf9b1df3ef0c ]
+
+The driver acquired the ADC clock with devm_clk_get() and read its
+rate, but never called clk_prepare_enable(). The probe error path and
+npcm_adc_remove() both called clk_disable_unprepare() unconditionally,
+causing the clk framework's enable/prepare counts to underflow on
+probe failure or module unbind.
+
+The issue went unnoticed because NPCM BMC firmware leaves the ADC
+clock enabled at boot, so the driver happened to work in practice.
+
+Switch to devm_clk_get_enabled() so the clock is properly enabled
+during probe and automatically released by the device-managed
+cleanup, and drop the now-redundant clk_disable_unprepare() from
+both the probe error path and remove().
+
+While at it, drop the duplicate error message on devm_request_irq()
+failure since the IRQ core already logs it.
+
+Fixes: 9bf85fbc9d8f ("iio: adc: add NPCM ADC driver")
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/adc/npcm_adc.c |   25 ++++++++-----------------
+ 1 file changed, 8 insertions(+), 17 deletions(-)
+
+--- a/drivers/iio/adc/npcm_adc.c
++++ b/drivers/iio/adc/npcm_adc.c
+@@ -231,7 +231,7 @@ static int npcm_adc_probe(struct platfor
+       if (IS_ERR(info->reset))
+               return PTR_ERR(info->reset);
+-      info->adc_clk = devm_clk_get(&pdev->dev, NULL);
++      info->adc_clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(info->adc_clk)) {
+               dev_warn(&pdev->dev, "ADC clock failed: can't read clk\n");
+               return PTR_ERR(info->adc_clk);
+@@ -244,17 +244,13 @@ static int npcm_adc_probe(struct platfor
+       info->adc_sample_hz = clk_get_rate(info->adc_clk) / ((div + 1) * 2);
+       irq = platform_get_irq(pdev, 0);
+-      if (irq < 0) {
+-              ret = irq;
+-              goto err_disable_clk;
+-      }
++      if (irq < 0)
++              return irq;
+       ret = devm_request_irq(&pdev->dev, irq, npcm_adc_isr, 0,
+                              "NPCM_ADC", indio_dev);
+-      if (ret < 0) {
+-              dev_err(dev, "failed requesting interrupt\n");
+-              goto err_disable_clk;
+-      }
++      if (ret < 0)
++              return ret;
+       reg_con = ioread32(info->regs + NPCM_ADCCON);
+       info->vref = devm_regulator_get_optional(&pdev->dev, "vref");
+@@ -262,7 +258,7 @@ static int npcm_adc_probe(struct platfor
+               ret = regulator_enable(info->vref);
+               if (ret) {
+                       dev_err(&pdev->dev, "Can't enable ADC reference voltage\n");
+-                      goto err_disable_clk;
++                      return ret;
+               }
+               iowrite32(reg_con & ~NPCM_ADCCON_REFSEL,
+@@ -272,10 +268,8 @@ static int npcm_adc_probe(struct platfor
+                * Any error which is not ENODEV indicates the regulator
+                * has been specified and so is a failure case.
+                */
+-              if (PTR_ERR(info->vref) != -ENODEV) {
+-                      ret = PTR_ERR(info->vref);
+-                      goto err_disable_clk;
+-              }
++              if (PTR_ERR(info->vref) != -ENODEV)
++                      return PTR_ERR(info->vref);
+               /* Use internal reference */
+               iowrite32(reg_con | NPCM_ADCCON_REFSEL,
+@@ -314,8 +308,6 @@ err_iio_register:
+       iowrite32(reg_con & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
+       if (!IS_ERR(info->vref))
+               regulator_disable(info->vref);
+-err_disable_clk:
+-      clk_disable_unprepare(info->adc_clk);
+       return ret;
+ }
+@@ -332,7 +324,6 @@ static void npcm_adc_remove(struct platf
+       iowrite32(regtemp & ~NPCM_ADCCON_ADC_EN, info->regs + NPCM_ADCCON);
+       if (!IS_ERR(info->vref))
+               regulator_disable(info->vref);
+-      clk_disable_unprepare(info->adc_clk);
+ }
+ static struct platform_driver npcm_adc_driver = {
diff --git a/queue-6.1/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch b/queue-6.1/iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
new file mode 100644 (file)
index 0000000..0c03b8a
--- /dev/null
@@ -0,0 +1,38 @@
+From stable+bounces-260563-greg=kroah.com@vger.kernel.org Fri Jun  5 00:48:04 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 15:17:50 -0400
+Subject: iio: chemical: scd30: fix division by zero in write_raw
+To: stable@vger.kernel.org
+Cc: Antoniu Miclaus <antoniu.miclaus@analog.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604191751.743012-2-sashal@kernel.org>
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 5aba4f94b225617a55fed442a70329b2ee19c0a5 ]
+
+Add a zero check for val2 before using it as a divisor when setting the
+sampling frequency. A user writing a zero fractional part to the
+sampling_frequency sysfs attribute triggers a division by zero in the
+kernel.
+
+Fixes: 64b3d8b1b0f5 ("iio: chemical: scd30: add core driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -257,7 +257,7 @@ static int scd30_write_raw(struct iio_de
+       guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+-              if (val)
++              if (val || !val2)
+                       return -EINVAL;
+               val = 1000000000 / val2;
diff --git a/queue-6.1/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch b/queue-6.1/iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
new file mode 100644 (file)
index 0000000..2f8e05c
--- /dev/null
@@ -0,0 +1,178 @@
+From stable+bounces-260562-greg=kroah.com@vger.kernel.org Fri Jun  5 00:48:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 15:17:49 -0400
+Subject: iio: chemical: scd30: Use guard(mutex) to allow early returns
+To: stable@vger.kernel.org
+Cc: Jonathan Cameron <Jonathan.Cameron@huawei.com>, David Lechner <dlechner@baylibre.com>, Tomasz Duszynski <tomasz.duszynski@octakon.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260604191751.743012-1-sashal@kernel.org>
+
+From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+
+[ Upstream commit 5feb5532870fbced5d6f450b8061a33f461b88ca ]
+
+Auto cleanup based release of the lock allows for simpler code flow in a
+few functions with large multiplexing style switch statements and no
+common operations following the switch.
+
+Suggested-by: David Lechner <dlechner@baylibre.com>
+Cc: Tomasz Duszynski <tomasz.duszynski@octakon.com>
+Reviewed-by: David Lechner <dlechner@baylibre.com>
+Link: https://patch.msgid.link/20250209180624.701140-3-jic23@kernel.org
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Stable-dep-of: 5aba4f94b225 ("iio: chemical: scd30: fix division by zero in write_raw")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/chemical/scd30_core.c |   63 ++++++++++++++++----------------------
+ 1 file changed, 28 insertions(+), 35 deletions(-)
+
+--- a/drivers/iio/chemical/scd30_core.c
++++ b/drivers/iio/chemical/scd30_core.c
+@@ -5,6 +5,7 @@
+  * Copyright (c) 2020 Tomasz Duszynski <tomasz.duszynski@octakon.com>
+  */
+ #include <linux/bits.h>
++#include <linux/cleanup.h>
+ #include <linux/completion.h>
+ #include <linux/delay.h>
+ #include <linux/device.h>
+@@ -198,112 +199,104 @@ static int scd30_read_raw(struct iio_dev
+                         int *val, int *val2, long mask)
+ {
+       struct scd30_state *state = iio_priv(indio_dev);
+-      int ret = -EINVAL;
++      int ret;
+       u16 tmp;
+-      mutex_lock(&state->lock);
++      guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_RAW:
+       case IIO_CHAN_INFO_PROCESSED:
+               if (chan->output) {
+                       *val = state->pressure_comp;
+-                      ret = IIO_VAL_INT;
+-                      break;
++                      return IIO_VAL_INT;
+               }
+               ret = iio_device_claim_direct_mode(indio_dev);
+               if (ret)
+-                      break;
++                      return ret;
+               ret = scd30_read(state);
+               if (ret) {
+                       iio_device_release_direct_mode(indio_dev);
+-                      break;
++                      return ret;
+               }
+               *val = state->meas[chan->address];
+               iio_device_release_direct_mode(indio_dev);
+-              ret = IIO_VAL_INT;
+-              break;
++              return IIO_VAL_INT;
+       case IIO_CHAN_INFO_SCALE:
+               *val = 0;
+               *val2 = 1;
+-              ret = IIO_VAL_INT_PLUS_MICRO;
+-              break;
++              return IIO_VAL_INT_PLUS_MICRO;
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               ret = scd30_command_read(state, CMD_MEAS_INTERVAL, &tmp);
+               if (ret)
+-                      break;
++                      return ret;
+               *val = 0;
+               *val2 = 1000000000 / tmp;
+-              ret = IIO_VAL_INT_PLUS_NANO;
+-              break;
++              return IIO_VAL_INT_PLUS_NANO;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               ret = scd30_command_read(state, CMD_TEMP_OFFSET, &tmp);
+               if (ret)
+-                      break;
++                      return ret;
+               *val = tmp;
+-              ret = IIO_VAL_INT;
+-              break;
++              return IIO_VAL_INT;
++      default:
++              return -EINVAL;
+       }
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+ }
+ static int scd30_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
+                          int val, int val2, long mask)
+ {
+       struct scd30_state *state = iio_priv(indio_dev);
+-      int ret = -EINVAL;
++      int ret;
+-      mutex_lock(&state->lock);
++      guard(mutex)(&state->lock);
+       switch (mask) {
+       case IIO_CHAN_INFO_SAMP_FREQ:
+               if (val)
+-                      break;
++                      return -EINVAL;
+               val = 1000000000 / val2;
+               if (val < SCD30_MEAS_INTERVAL_MIN_S || val > SCD30_MEAS_INTERVAL_MAX_S)
+-                      break;
++                      return -EINVAL;
+               ret = scd30_command_write(state, CMD_MEAS_INTERVAL, val);
+               if (ret)
+-                      break;
++                      return ret;
+               state->meas_interval = val;
+-              break;
++              return 0;
+       case IIO_CHAN_INFO_RAW:
+               switch (chan->type) {
+               case IIO_PRESSURE:
+                       if (val < SCD30_PRESSURE_COMP_MIN_MBAR ||
+                           val > SCD30_PRESSURE_COMP_MAX_MBAR)
+-                              break;
++                              return -EINVAL;
+                       ret = scd30_command_write(state, CMD_START_MEAS, val);
+                       if (ret)
+-                              break;
++                              return ret;
+                       state->pressure_comp = val;
+-                      break;
++                      return 0;
+               default:
+-                      break;
++                      return -EINVAL;
+               }
+-              break;
+       case IIO_CHAN_INFO_CALIBBIAS:
+               if (val < 0 || val > SCD30_TEMP_OFFSET_MAX)
+-                      break;
++                      return -EINVAL;
+               /*
+                * Manufacturer does not explicitly specify min/max sensible
+                * values hence check is omitted for simplicity.
+                */
+-              ret = scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++              return scd30_command_write(state, CMD_TEMP_OFFSET / 10, val);
++      default:
++              return -EINVAL;
+       }
+-      mutex_unlock(&state->lock);
+-
+-      return ret;
+ }
+ static int scd30_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
diff --git a/queue-6.1/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch b/queue-6.1/iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
new file mode 100644 (file)
index 0000000..fc17007
--- /dev/null
@@ -0,0 +1,65 @@
+From stable+bounces-260596-greg=kroah.com@vger.kernel.org Fri Jun  5 06:30:09 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 20:59:16 -0400
+Subject: iio: dac: ad5686: fix ref bit initialization for single-channel parts
+To: stable@vger.kernel.org
+Cc: Rodrigo Alencar <rodrigo.alencar@analog.com>, Andy Shevchenko <andriy.shevchenko@intel.com>, Stable@vger.kernel.org, Jonathan Cameron <jic23@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605005916.2803184-1-sashal@kernel.org>
+
+From: Rodrigo Alencar <rodrigo.alencar@analog.com>
+
+[ Upstream commit ecae2ae606d493cf11457946436335bd0e726663 ]
+
+The reference bit position was ignored when writing the register at the
+probe() function (!!val was used). When such bit is 1, internal voltage
+reference is disabled so that an external one can be used. For
+multi-channel devices, bit 0 of the Internal Reference Setup command
+behaves the same way, so AD5686_REF_BIT_MSK is created. The issue exists
+since support for single-channel devices were first introduced.
+
+Fixes: be1b24d24541 ("iio:dac:ad5686: Add AD5691R/AD5692R/AD5693/AD5693R support")
+Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
+Signed-off-by: Rodrigo Alencar <rodrigo.alencar@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <jic23@kernel.org>
+[ adapted `has_external_vref` to the in-tree equivalent `voltage_uv` variable in the `val =` computation ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/dac/ad5686.c |    6 +++---
+ drivers/iio/dac/ad5686.h |    1 +
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/iio/dac/ad5686.c
++++ b/drivers/iio/dac/ad5686.c
+@@ -521,7 +521,7 @@ int ad5686_probe(struct device *dev,
+               break;
+       case AD5686_REGMAP:
+               cmd = AD5686_CMD_INTERNAL_REFER_SETUP;
+-              ref_bit_msk = 0;
++              ref_bit_msk = AD5686_REF_BIT_MSK;
+               break;
+       case AD5693_REGMAP:
+               cmd = AD5686_CMD_CONTROL_REG;
+@@ -533,9 +533,9 @@ int ad5686_probe(struct device *dev,
+               goto error_disable_reg;
+       }
+-      val = (voltage_uv | ref_bit_msk);
++      val = voltage_uv ? ref_bit_msk : 0;
+-      ret = st->write(st, cmd, 0, !!val);
++      ret = st->write(st, cmd, 0, val);
+       if (ret)
+               goto error_disable_reg;
+--- a/drivers/iio/dac/ad5686.h
++++ b/drivers/iio/dac/ad5686.h
+@@ -46,6 +46,7 @@
+ #define AD5310_REF_BIT_MSK                    BIT(8)
+ #define AD5683_REF_BIT_MSK                    BIT(12)
++#define AD5686_REF_BIT_MSK                    BIT(0)
+ #define AD5693_REF_BIT_MSK                    BIT(12)
+ /**
diff --git a/queue-6.1/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch b/queue-6.1/iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
new file mode 100644 (file)
index 0000000..b56280a
--- /dev/null
@@ -0,0 +1,39 @@
+From stable+bounces-260561-greg=kroah.com@vger.kernel.org Fri Jun  5 00:33:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 14:57:19 -0400
+Subject: iio: gyro: adis16260: fix division by zero in write_raw
+To: stable@vger.kernel.org
+Cc: "Antoniu Miclaus" <antoniu.miclaus@analog.com>, "Nuno Sá" <nuno.sa@analog.com>, Stable@vger.kernel.org, "Jonathan Cameron" <Jonathan.Cameron@huawei.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260604185720.605937-1-sashal@kernel.org>
+
+From: Antoniu Miclaus <antoniu.miclaus@analog.com>
+
+[ Upstream commit 761e8b489e6cf166c574034b70637f8a7eadd0ee ]
+
+Add a validation check for the sampling frequency value before using it
+as a divisor. A user writing zero to the sampling_frequency sysfs
+attribute triggers a division by zero in the kernel.
+
+Fixes: 089a41985c6c ("staging: iio: adis16260 digital gyro driver")
+Signed-off-by: Antoniu Miclaus <antoniu.miclaus@analog.com>
+Reviewed-by: Nuno Sá <nuno.sa@analog.com>
+Cc: <Stable@vger.kernel.org>
+Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/iio/gyro/adis16260.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/iio/gyro/adis16260.c
++++ b/drivers/iio/gyro/adis16260.c
+@@ -288,6 +288,9 @@ static int adis16260_write_raw(struct ii
+               addr = adis16260_addresses[chan->scan_index][1];
+               return adis_write_reg_16(adis, addr, val);
+       case IIO_CHAN_INFO_SAMP_FREQ:
++              if (val <= 0)
++                      return -EINVAL;
++
+               adis_dev_lock(adis);
+               if (spi_get_device_id(adis->spi)->driver_data)
+                       t = 256 / val;
diff --git a/queue-6.1/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch b/queue-6.1/ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch
new file mode 100644 (file)
index 0000000..2f5e2a0
--- /dev/null
@@ -0,0 +1,76 @@
+From stable+bounces-256844-greg=kroah.com@vger.kernel.org Sat May 30 06:27:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 20:50:58 -0400
+Subject: ipv6: ioam: add NULL check for idev in ipv6_hop_ioam()
+To: stable@vger.kernel.org
+Cc: Justin Iurman <justin.iurman@gmail.com>, Ido Schimmel <idosch@nvidia.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530005058.2390235-1-sashal@kernel.org>
+
+From: Justin Iurman <justin.iurman@gmail.com>
+
+[ Upstream commit d4ea0dfd75011b78cebf3808f98ac4c4f51a6fb9 ]
+
+Reported by Sashiko:
+
+The function ipv6_hop_ioam() accesses
+__in6_dev_get(skb->dev)->cnf.ioam6_enabled without validating the returned
+idev pointer. Because addrconf_ifdown() can concurrently clear dev->ip6_ptr
+via RCU, __in6_dev_get() can return NULL during interface teardown, which
+could cause a NULL pointer dereference when processing an IOAM Hop-by-Hop
+option.
+
+Let's add a check and use SKB_DROP_REASON_IPV6DISABLED accordingly.
+
+Fixes: 9ee11f0fff20 ("ipv6: ioam: Data plane support for Pre-allocated Trace")
+Cc: stable@vger.kernel.org
+Signed-off-by: Justin Iurman <justin.iurman@gmail.com>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20260517183059.29140-1-justin.iurman@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ dropped READ_ONCE() wrapper from idev->cnf.ioam6_enabled ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/exthdrs.c |   15 +++++++++++++--
+ 1 file changed, 13 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/exthdrs.c
++++ b/net/ipv6/exthdrs.c
+@@ -952,16 +952,27 @@ static bool ipv6_hop_ra(struct sk_buff *
+ static bool ipv6_hop_ioam(struct sk_buff *skb, int optoff)
+ {
++      enum skb_drop_reason drop_reason;
+       struct ioam6_trace_hdr *trace;
+       struct ioam6_namespace *ns;
++      struct inet6_dev *idev;
+       struct ioam6_hdr *hdr;
++      drop_reason = SKB_DROP_REASON_IP_INHDR;
++
+       /* Bad alignment (must be 4n-aligned) */
+       if (optoff & 3)
+               goto drop;
++      /* Does the device still have IPv6 configuration? */
++      idev = __in6_dev_get(skb->dev);
++      if (!idev) {
++              drop_reason = SKB_DROP_REASON_IPV6DISABLED;
++              goto drop;
++      }
++
+       /* Ignore if IOAM is not enabled on ingress */
+-      if (!__in6_dev_get(skb->dev)->cnf.ioam6_enabled)
++      if (!idev->cnf.ioam6_enabled)
+               goto ignore;
+       /* Truncated Option header */
+@@ -1011,7 +1022,7 @@ ignore:
+       return true;
+ drop:
+-      kfree_skb_reason(skb, SKB_DROP_REASON_IP_INHDR);
++      kfree_skb_reason(skb, drop_reason);
+       return false;
+ }
diff --git a/queue-6.1/mm-hugetlb-rename-folio_putback_active_hugetlb-to-folio_putback_hugetlb.patch b/queue-6.1/mm-hugetlb-rename-folio_putback_active_hugetlb-to-folio_putback_hugetlb.patch
new file mode 100644 (file)
index 0000000..e65edf1
--- /dev/null
@@ -0,0 +1,114 @@
+From stable+bounces-263445-greg=kroah.com@vger.kernel.org Tue Jun 16 01:12:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 15:42:35 -0400
+Subject: mm/hugetlb: rename folio_putback_active_hugetlb() to folio_putback_hugetlb()
+To: stable@vger.kernel.org
+Cc: David Hildenbrand <david@redhat.com>, Baolin Wang <baolin.wang@linux.alibaba.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org>, Muchun Song <muchun.song@linux.dev>, Sidhartha Kumar <sidhartha.kumar@oracle.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260615194237.2391157-3-sashal@kernel.org>
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit b235448e8cab7eea17d164efc7bf55505985ba65 ]
+
+Now that folio_putback_hugetlb() is only called on folios that were
+previously isolated through folio_isolate_hugetlb(), let's rename it to
+match folio_putback_lru().
+
+Add some kernel doc to clarify how this function is supposed to be used.
+
+Link: https://lkml.kernel.org/r/20250113131611.2554758-5-david@redhat.com
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 3c2d42b8ee34 ("mm/memory-failure: fix hugetlb_lock AA deadlock in get_huge_page_for_hwpoison")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/hugetlb.h |    4 ++--
+ mm/hugetlb.c            |   15 +++++++++++++--
+ mm/migrate.c            |    6 +++---
+ 3 files changed, 18 insertions(+), 7 deletions(-)
+
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -185,7 +185,7 @@ long hugetlb_unreserve_pages(struct inod
+ int folio_isolate_hugetlb(struct page *page, struct list_head *list);
+ int get_hwpoison_huge_page(struct page *page, bool *hugetlb);
+ int get_huge_page_for_hwpoison(unsigned long pfn, int flags);
+-void putback_active_hugepage(struct page *page);
++void folio_putback_hugetlb(struct page *page);
+ void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason);
+ void free_huge_page(struct page *page);
+ void hugetlb_fix_reserve_counts(struct inode *inode);
+@@ -443,7 +443,7 @@ static inline int get_huge_page_for_hwpo
+       return 0;
+ }
+-static inline void putback_active_hugepage(struct page *page)
++static inline void folio_putback_hugetlb(struct page *page)
+ {
+ }
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -7458,7 +7458,7 @@ follow_huge_pgd(struct mm_struct *mm, un
+  * it is already isolated/non-migratable.
+  *
+  * On success, an additional page reference is taken that must be dropped
+- * using putback_active_hugepage() to undo the isolation.
++ * using folio_putback_hugetlb() to undo the isolation.
+  *
+  * Return: 0 if isolation worked, otherwise -EBUSY.
+  */
+@@ -7509,7 +7509,18 @@ int get_huge_page_for_hwpoison(unsigned
+       return ret;
+ }
+-void putback_active_hugepage(struct page *page)
++/**
++ * folio_putback_hugetlb - unisolate a hugetlb page
++ * @page: the isolated hugetlb page
++ *
++ * Putback/un-isolate the hugetlb page that was previous isolated using
++ * folio_isolate_hugetlb(): marking it non-isolated/migratable and putting it
++ * back onto the active list.
++ *
++ * Will drop the additional page reference obtained through
++ * folio_isolate_hugetlb().
++ */
++void folio_putback_hugetlb(struct page *page)
+ {
+       spin_lock_irq(&hugetlb_lock);
+       SetHPageMigratable(page);
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -142,7 +142,7 @@ void putback_movable_pages(struct list_h
+       list_for_each_entry_safe(page, page2, l, lru) {
+               if (unlikely(PageHuge(page))) {
+-                      putback_active_hugepage(page);
++                      folio_putback_hugetlb(page);
+                       continue;
+               }
+               list_del(&page->lru);
+@@ -1371,7 +1371,7 @@ static int unmap_and_move_huge_page(new_
+       if (folio_ref_count(src) == 1) {
+               /* page was freed from under us. So we are done. */
+-              putback_active_hugepage(hpage);
++              folio_putback_hugetlb(hpage);
+               return MIGRATEPAGE_SUCCESS;
+       }
+@@ -1455,7 +1455,7 @@ out_unlock:
+       folio_unlock(src);
+ out:
+       if (rc == MIGRATEPAGE_SUCCESS)
+-              putback_active_hugepage(hpage);
++              folio_putback_hugetlb(hpage);
+       else if (rc != -EAGAIN)
+               list_move_tail(&src->lru, ret);
diff --git a/queue-6.1/mm-hugetlb-rename-isolate_hugetlb-to-folio_isolate_hugetlb.patch b/queue-6.1/mm-hugetlb-rename-isolate_hugetlb-to-folio_isolate_hugetlb.patch
new file mode 100644 (file)
index 0000000..104e83d
--- /dev/null
@@ -0,0 +1,165 @@
+From stable+bounces-263443-greg=kroah.com@vger.kernel.org Tue Jun 16 01:12:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 15:42:33 -0400
+Subject: mm/hugetlb: rename isolate_hugetlb() to folio_isolate_hugetlb()
+To: stable@vger.kernel.org
+Cc: David Hildenbrand <david@redhat.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org>, Baolin Wang <baolin.wang@linux.alibaba.com>, Muchun Song <muchun.song@linux.dev>, Sidhartha Kumar <sidhartha.kumar@oracle.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260615194237.2391157-1-sashal@kernel.org>
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit 4c640f128074e0d4459ecf072595a44df5c2ae18 ]
+
+Let's make the function name match "folio_isolate_lru()", and add some
+kernel doc.
+
+Link: https://lkml.kernel.org/r/20250113131611.2554758-3-david@redhat.com
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 3c2d42b8ee34 ("mm/memory-failure: fix hugetlb_lock AA deadlock in get_huge_page_for_hwpoison")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/hugetlb.h |    4 ++--
+ mm/gup.c                |    2 +-
+ mm/hugetlb.c            |   23 ++++++++++++++++++++---
+ mm/memory-failure.c     |    2 +-
+ mm/memory_hotplug.c     |    2 +-
+ mm/mempolicy.c          |    2 +-
+ mm/migrate.c            |    4 ++--
+ 7 files changed, 28 insertions(+), 11 deletions(-)
+
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -182,7 +182,7 @@ bool hugetlb_reserve_pages(struct inode
+                                               vm_flags_t vm_flags);
+ long hugetlb_unreserve_pages(struct inode *inode, long start, long end,
+                                               long freed);
+-int isolate_hugetlb(struct page *page, struct list_head *list);
++int folio_isolate_hugetlb(struct page *page, struct list_head *list);
+ int get_hwpoison_huge_page(struct page *page, bool *hugetlb);
+ int get_huge_page_for_hwpoison(unsigned long pfn, int flags);
+ void putback_active_hugepage(struct page *page);
+@@ -428,7 +428,7 @@ static inline pte_t *huge_pte_offset(str
+       return NULL;
+ }
+-static inline int isolate_hugetlb(struct page *page, struct list_head *list)
++static inline int folio_isolate_hugetlb(struct page *page, struct list_head *list)
+ {
+       return -EBUSY;
+ }
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -1986,7 +1986,7 @@ static unsigned long collect_longterm_un
+                       continue;
+               if (folio_test_hugetlb(folio)) {
+-                      isolate_hugetlb(&folio->page, movable_page_list);
++                      folio_isolate_hugetlb(&folio->page, movable_page_list);
+                       continue;
+               }
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -2994,7 +2994,7 @@ retry:
+                * Fail with -EBUSY if not possible.
+                */
+               spin_unlock_irq(&hugetlb_lock);
+-              ret = isolate_hugetlb(old_page, list);
++              ret = folio_isolate_hugetlb(old_page, list);
+               spin_lock_irq(&hugetlb_lock);
+               goto free_new;
+       } else if (!HPageFreed(old_page)) {
+@@ -3070,7 +3070,7 @@ int isolate_or_dissolve_huge_page(struct
+       if (hstate_is_gigantic(h))
+               return -ENOMEM;
+-      if (page_count(head) && !isolate_hugetlb(head, list))
++      if (page_count(head) && !folio_isolate_hugetlb(head, list))
+               ret = 0;
+       else if (!page_count(head))
+               ret = alloc_and_dissolve_huge_page(h, head, list);
+@@ -7445,7 +7445,24 @@ follow_huge_pgd(struct mm_struct *mm, un
+       return pte_page(*(pte_t *)pgd) + ((address & ~PGDIR_MASK) >> PAGE_SHIFT);
+ }
+-int isolate_hugetlb(struct page *page, struct list_head *list)
++/**
++ * folio_isolate_hugetlb - try to isolate an allocated hugetlb page
++ * @page: the page to isolate
++ * @list: the list to add the page to on success
++ *
++ * Isolate an allocated (refcount > 0) hugetlb page, marking it as
++ * isolated/non-migratable, and moving it from the active list to the
++ * given list.
++ *
++ * Isolation will fail if @page is not an allocated hugetlb page, or if
++ * it is already isolated/non-migratable.
++ *
++ * On success, an additional page reference is taken that must be dropped
++ * using putback_active_hugepage() to undo the isolation.
++ *
++ * Return: 0 if isolation worked, otherwise -EBUSY.
++ */
++int folio_isolate_hugetlb(struct page *page, struct list_head *list)
+ {
+       int ret = 0;
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -2444,7 +2444,7 @@ static bool isolate_page(struct page *pa
+       bool isolated = false;
+       if (PageHuge(page)) {
+-              isolated = !isolate_hugetlb(page, pagelist);
++              isolated = !folio_isolate_hugetlb(page, pagelist);
+       } else {
+               bool lru = !__PageMovable(page);
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -1641,7 +1641,7 @@ do_migrate_range(unsigned long start_pfn
+               if (PageHuge(page)) {
+                       pfn = page_to_pfn(head) + compound_nr(head) - 1;
+-                      isolate_hugetlb(head, &source);
++                      folio_isolate_hugetlb(head, &source);
+                       continue;
+               } else if (PageTransHuge(page))
+                       pfn = page_to_pfn(head) + thp_nr_pages(page) - 1;
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -598,7 +598,7 @@ static int queue_pages_hugetlb(pte_t *pt
+       if (flags & (MPOL_MF_MOVE_ALL) ||
+           (flags & MPOL_MF_MOVE && page_mapcount(page) == 1 &&
+            !hugetlb_pmd_shared(pte))) {
+-              if (isolate_hugetlb(page, qp->pagelist) &&
++              if (folio_isolate_hugetlb(page, qp->pagelist) &&
+                       (flags & MPOL_MF_STRICT))
+                       /*
+                        * Failed to isolate page but allow migrating pages
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -133,7 +133,7 @@ static void putback_movable_page(struct
+  *
+  * This function shall be used whenever the isolated pageset has been
+  * built from lru, balloon, hugetlbfs page. See isolate_migratepages_range()
+- * and isolate_hugetlb().
++ * and folio_isolate_hugetlb().
+  */
+ void putback_movable_pages(struct list_head *l)
+ {
+@@ -1995,7 +1995,7 @@ static int add_page_for_migration(struct
+       if (PageHuge(page)) {
+               if (PageHead(page)) {
+-                      err = isolate_hugetlb(page, pagelist);
++                      err = folio_isolate_hugetlb(page, pagelist);
+                       if (!err)
+                               err = 1;
+               }
diff --git a/queue-6.1/mm-hugetlb_cma-round-up-per_node-before-logging-it.patch b/queue-6.1/mm-hugetlb_cma-round-up-per_node-before-logging-it.patch
new file mode 100644 (file)
index 0000000..d56b086
--- /dev/null
@@ -0,0 +1,79 @@
+From stable+bounces-247231-greg=kroah.com@vger.kernel.org Thu May 14 20:41:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 11:08:40 -0400
+Subject: mm/hugetlb_cma: round up per_node before logging it
+To: stable@vger.kernel.org
+Cc: Sang-Heon Jeon <ekffu200098@gmail.com>, Muchun Song <muchun.song@linux.dev>, David Hildenbrand <david@kernel.org>, Oscar Salvador <osalvador@suse.de>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514150840.275599-1-sashal@kernel.org>
+
+From: Sang-Heon Jeon <ekffu200098@gmail.com>
+
+[ Upstream commit 8f5ce56b76303c55b78a87af996e2e0f8535f979 ]
+
+When the user requests a total hugetlb CMA size without per-node
+specification, hugetlb_cma_reserve() computes per_node from
+hugetlb_cma_size and the number of nodes that have memory
+
+        per_node = DIV_ROUND_UP(hugetlb_cma_size,
+                                nodes_weight(hugetlb_bootmem_nodes));
+
+The reservation loop later computes
+
+        size = round_up(min(per_node, hugetlb_cma_size - reserved),
+                          PAGE_SIZE << order);
+
+So the actually reserved per_node size is multiple of (PAGE_SIZE <<
+order), but the logged per_node is not rounded up, so it may be smaller
+than the actual reserved size.
+
+For example, as the existing comment describes, if a 3 GB area is
+requested on a machine with 4 NUMA nodes that have memory, 1 GB is
+allocated on the first three nodes, but the printed log is
+
+        hugetlb_cma: reserve 3072 MiB, up to 768 MiB per node
+
+Round per_node up to (PAGE_SIZE << order) before logging so that the
+printed log always matches the actual reserved size.  No functional change
+to the actual reservation size, as the following case analysis shows
+
+1. remaining (hugetlb_cma_size - reserved) >= rounded per_node
+ - AS-IS: min() picks unrounded per_node;
+    round_up() returns rounded per_node
+ - TO-BE: min() picks rounded per_node;
+    round_up() returns rounded per_node (no-op)
+2. remaining < unrounded per_node
+ - AS-IS: min() picks remaining;
+    round_up() returns round_up(remaining)
+ - TO-BE: min() picks remaining;
+    round_up() returns round_up(remaining)
+3. unrounded per_node <= remaining < rounded per_node
+ - AS-IS: min() picks unrounded per_node;
+    round_up() returns rounded per_node
+ - TO-BE: min() picks remaining;
+    round_up() returns round_up(remaining) equals rounded per_node
+
+Link: https://lore.kernel.org/20260422143353.852257-1-ekffu200098@gmail.com
+Fixes: cf11e85fc08c ("mm: hugetlb: optionally allocate gigantic hugepages using cma") # 5.7
+Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
+Reviewed-by: Muchun Song <muchun.song@linux.dev>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ applied the single-line addition to mm/hugetlb.c since mm/hugetlb_cma.c didn't exist yet in 6.12 ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/hugetlb.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -7705,6 +7705,7 @@ void __init hugetlb_cma_reserve(int orde
+                * let's allocate 1 GB on first three nodes and ignore the last one.
+                */
+               per_node = DIV_ROUND_UP(hugetlb_cma_size, nr_online_nodes);
++              per_node = round_up(per_node, PAGE_SIZE << order);
+               pr_info("hugetlb_cma: reserve %lu MiB, up to %lu MiB per node\n",
+                       hugetlb_cma_size / SZ_1M, per_node / SZ_1M);
+       }
diff --git a/queue-6.1/mm-memory-failure-fix-hugetlb_lock-aa-deadlock-in-get_huge_page_for_hwpoison.patch b/queue-6.1/mm-memory-failure-fix-hugetlb_lock-aa-deadlock-in-get_huge_page_for_hwpoison.patch
new file mode 100644 (file)
index 0000000..fec3082
--- /dev/null
@@ -0,0 +1,184 @@
+From stable+bounces-263447-greg=kroah.com@vger.kernel.org Tue Jun 16 01:12:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 15:42:37 -0400
+Subject: mm/memory-failure: fix hugetlb_lock AA deadlock in get_huge_page_for_hwpoison
+To: stable@vger.kernel.org
+Cc: Wupeng Ma <mawupeng1@huawei.com>, "Oscar Salvador (SUSE)" <osalvador@kernel.org>, Muchun Song <muchun.song@linux.dev>, Kefeng Wang <wangkefeng.wang@huawei.com>, Miaohe Lin <linmiaohe@huawei.com>, David Hildenbrand <david@kernel.org>, Liam Howlett <liam.howlett@oracle.com>, Lorenzo Stoakes <ljs@kernel.org>, Michal Hocko <mhocko@suse.com>, Mike Rapoport <rppt@kernel.org>, Naoya Horiguchi <nao.horiguchi@gmail.com>, Suren Baghdasaryan <surenb@google.com>, Vlastimil Babka <vbabka@kernel.org>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260615194237.2391157-5-sashal@kernel.org>
+
+From: Wupeng Ma <mawupeng1@huawei.com>
+
+[ Upstream commit 3c2d42b8ee345b17a4ba56b0f6492d1ff4c1178e ]
+
+Two concurrent madvise(MADV_HWPOISON) calls on the same hugetlb page can
+trigger a recursive spinlock self-deadlock (AA deadlock) on hugetlb_lock
+when racing with a concurrent unmap:
+
+  thread#0                              thread#1
+  --------                              --------
+  madvise(folio, MADV_HWPOISON)
+    -> poisons the folio successfully
+  madvise(folio, MADV_HWPOISON)         unmap(folio)
+    try_memory_failure_hugetlb
+      get_huge_page_for_hwpoison
+        spin_lock_irq(&hugetlb_lock)    <- held
+        __get_huge_page_for_hwpoison
+          hugetlb_update_hwpoison()
+            -> MF_HUGETLB_FOLIO_PRE_POISONED
+          goto out:
+            folio_put()
+              refcount: 1 -> 0
+              free_huge_folio()
+                spin_lock_irqsave(&hugetlb_lock)
+                  -> AA DEADLOCK!
+
+The out: path in __get_huge_page_for_hwpoison() calls folio_put() to drop
+the GUP reference while the hugetlb_lock is still held by the hugetlb.c
+wrapper get_huge_page_for_hwpoison().  If concurrent unmap has released
+the page table mapping reference, folio_put() drops the folio refcount to
+zero, triggering free_huge_folio() which attempts to re-acquire the
+non-recursive hugetlb_lock.
+
+Fix this by moving hugetlb_lock acquisition from the hugetlb.c wrapper
+into get_huge_page_for_hwpoison().  Place spin_unlock_irq() before the
+folio_put() at the out: label so the folio is always released outside the
+lock.
+
+[akpm@linux-foundation.org: fix race, rename label per Miaohe]
+  Link: https://sashiko.dev/#/patchset/20260522010305.4099834-1-mawupeng1@huawei.com
+  Link: https://lore.kernel.org/f39f405e-4b4b-8f79-70fe-a2b5b62114eb@huawei.com
+Link: https://lore.kernel.org/20260522010305.4099834-1-mawupeng1@huawei.com
+Fixes: 405ce051236c ("mm/hwpoison: fix race between hugetlb free/demotion and memory_failure_hugetlb()")
+Signed-off-by: Wupeng Ma <mawupeng1@huawei.com>
+Acked-by: Oscar Salvador (SUSE) <osalvador@kernel.org>
+Acked-by: Muchun Song <muchun.song@linux.dev>
+Reviewed-by: Kefeng Wang <wangkefeng.wang@huawei.com>
+Acked-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/hugetlb.h |    6 ------
+ include/linux/mm.h      |    5 -----
+ mm/hugetlb.c            |   10 ----------
+ mm/memory-failure.c     |   19 ++++++++++---------
+ 4 files changed, 10 insertions(+), 30 deletions(-)
+
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -184,7 +184,6 @@ long hugetlb_unreserve_pages(struct inod
+                                               long freed);
+ int folio_isolate_hugetlb(struct page *page, struct list_head *list);
+ int get_hwpoison_huge_page(struct page *page, bool *hugetlb);
+-int get_huge_page_for_hwpoison(unsigned long pfn, int flags);
+ void folio_putback_hugetlb(struct page *page);
+ void move_hugetlb_state(struct page *oldpage, struct page *newpage, int reason);
+ void free_huge_page(struct page *page);
+@@ -437,11 +436,6 @@ static inline int get_hwpoison_huge_page
+ {
+       return 0;
+ }
+-
+-static inline int get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+-{
+-      return 0;
+-}
+ static inline void folio_putback_hugetlb(struct page *page)
+ {
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -3429,15 +3429,10 @@ extern atomic_long_t num_poisoned_pages
+ extern int soft_offline_page(unsigned long pfn, int flags);
+ #ifdef CONFIG_MEMORY_FAILURE
+ extern void memory_failure_queue(unsigned long pfn, int flags);
+-extern int __get_huge_page_for_hwpoison(unsigned long pfn, int flags);
+ #else
+ static inline void memory_failure_queue(unsigned long pfn, int flags)
+ {
+ }
+-static inline int __get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+-{
+-      return 0;
+-}
+ #endif
+ #ifndef arch_memory_failure
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -7499,16 +7499,6 @@ int get_hwpoison_huge_page(struct page *
+       return ret;
+ }
+-int get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+-{
+-      int ret;
+-
+-      spin_lock_irq(&hugetlb_lock);
+-      ret = __get_huge_page_for_hwpoison(pfn, flags);
+-      spin_unlock_irq(&hugetlb_lock);
+-      return ret;
+-}
+-
+ /**
+  * folio_putback_hugetlb - unisolate a hugetlb page
+  * @page: the isolated hugetlb page
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1812,19 +1812,18 @@ void hugetlb_clear_page_hwpoison(struct
+       free_raw_hwp_pages(hpage, true);
+ }
+-/*
+- * Called from hugetlb code with hugetlb_lock held.
+- */
+-int __get_huge_page_for_hwpoison(unsigned long pfn, int flags)
++static int get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+ {
+       struct page *page = pfn_to_page(pfn);
+-      struct page *head = compound_head(page);
++      struct page *head;
+       bool count_increased = false;
+       int ret, rc;
++      spin_lock_irq(&hugetlb_lock);
++      head = compound_head(page);
+       if (!PageHeadHuge(head)) {
+               ret = MF_HUGETLB_NON_HUGEPAGE;
+-              goto out;
++              goto out_unlock;
+       } else if (flags & MF_COUNT_INCREASED) {
+               ret = MF_HUGETLB_IN_USED;
+               count_increased = true;
+@@ -1840,17 +1839,19 @@ int __get_huge_page_for_hwpoison(unsigne
+       } else {
+               ret = MF_HUGETLB_RETRY;
+               if (!(flags & MF_NO_RETRY))
+-                      goto out;
++                      goto out_unlock;
+       }
+       rc = hugetlb_update_hwpoison(head, page);
+       if (rc >= MF_HUGETLB_FOLIO_PRE_POISONED) {
+               ret = rc;
+-              goto out;
++              goto out_unlock;
+       }
++      spin_unlock_irq(&hugetlb_lock);
+       return ret;
+-out:
++out_unlock:
++      spin_unlock_irq(&hugetlb_lock);
+       if (count_increased)
+               put_page(head);
+       return ret;
diff --git a/queue-6.1/mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch b/queue-6.1/mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch
new file mode 100644 (file)
index 0000000..e9c3edc
--- /dev/null
@@ -0,0 +1,211 @@
+From stable+bounces-263446-greg=kroah.com@vger.kernel.org Tue Jun 16 01:12:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 15:42:36 -0400
+Subject: mm/memory-failure: fix missing ->mf_stats count in hugetlb poison
+To: stable@vger.kernel.org
+Cc: Jane Chu <jane.chu@oracle.com>, Miaohe Lin <linmiaohe@huawei.com>, Chris Mason <clm@meta.com>, David Hildenbrand <david@kernel.org>, David Rientjes <rientjes@google.com>, Jiaqi Yan <jiaqiyan@google.com>, "Liam R. Howlett" <Liam.Howlett@oracle.com>, Lorenzo Stoakes <lorenzo.stoakes@oracle.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org>, Michal Hocko <mhocko@suse.com>, Mike Rapoport <rppt@kernel.org>, Muchun Song <muchun.song@linux.dev>, Naoya Horiguchi <nao.horiguchi@gmail.com>, Oscar Salvador <osalvador@suse.de>, Suren Baghdasaryan <surenb@google.com>, William Roche <william.roche@oracle.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260615194237.2391157-4-sashal@kernel.org>
+
+From: Jane Chu <jane.chu@oracle.com>
+
+[ Upstream commit a148a2040191b12b45b82cb29c281cb3036baf90 ]
+
+When a newly poisoned subpage ends up in an already poisoned hugetlb
+folio, 'num_poisoned_pages' is incremented, but the per node ->mf_stats is
+not.  Fix the inconsistency by designating action_result() to update them
+both.
+
+While at it, define __get_huge_page_for_hwpoison() return values in terms
+of symbol names for better readibility.  Also rename
+folio_set_hugetlb_hwpoison() to hugetlb_update_hwpoison() since the
+function does more than the conventional bit setting and the fact three
+possible return values are expected.
+
+Link: https://lkml.kernel.org/r/20260120232234.3462258-1-jane.chu@oracle.com
+Fixes: 18f41fa616ee ("mm: memory-failure: bump memory failure stats to pglist_data")
+Signed-off-by: Jane Chu <jane.chu@oracle.com>
+Acked-by: Miaohe Lin <linmiaohe@huawei.com>
+Cc: Chris Mason <clm@meta.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: David Rientjes <rientjes@google.com>
+Cc: Jiaqi Yan <jiaqiyan@google.com>
+Cc: Liam R. Howlett <Liam.Howlett@oracle.com>
+Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Naoya Horiguchi <nao.horiguchi@gmail.com>
+Cc: Oscar Salvador <osalvador@suse.de>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: William Roche <william.roche@oracle.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 3c2d42b8ee34 ("mm/memory-failure: fix hugetlb_lock AA deadlock in get_huge_page_for_hwpoison")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory-failure.c |   71 +++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 43 insertions(+), 28 deletions(-)
+
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1730,12 +1730,22 @@ static unsigned long __free_raw_hwp_page
+       return count;
+ }
+-static int hugetlb_set_page_hwpoison(struct page *hpage, struct page *page)
++#define       MF_HUGETLB_FREED                0       /* freed hugepage */
++#define       MF_HUGETLB_IN_USED              1       /* in-use hugepage */
++#define       MF_HUGETLB_NON_HUGEPAGE         2       /* not a hugepage */
++#define       MF_HUGETLB_FOLIO_PRE_POISONED   3       /* folio already poisoned */
++#define       MF_HUGETLB_PAGE_PRE_POISONED    4       /* exact page already poisoned */
++#define       MF_HUGETLB_RETRY                5       /* hugepage is busy, retry */
++/*
++ * Set hugetlb page as hwpoisoned, update page private raw hwpoison list
++ * to keep track of the poisoned pages.
++ */
++static int hugetlb_update_hwpoison(struct page *hpage, struct page *page)
+ {
+       struct llist_head *head;
+       struct raw_hwp_page *raw_hwp;
+       struct llist_node *t, *tnode;
+-      int ret = TestSetPageHWPoison(hpage) ? -EHWPOISON : 0;
++      int ret = TestSetPageHWPoison(hpage) ? MF_HUGETLB_FOLIO_PRE_POISONED : 0;
+       /*
+        * Once the hwpoison hugepage has lost reliable raw error info,
+@@ -1743,13 +1753,13 @@ static int hugetlb_set_page_hwpoison(str
+        * so skip to add additional raw error info.
+        */
+       if (HPageRawHwpUnreliable(hpage))
+-              return -EHWPOISON;
++              return MF_HUGETLB_FOLIO_PRE_POISONED;
+       head = raw_hwp_list_head(hpage);
+       llist_for_each_safe(tnode, t, head->first) {
+               struct raw_hwp_page *p = container_of(tnode, struct raw_hwp_page, node);
+               if (p->page == page)
+-                      return -EHWPOISON;
++                      return MF_HUGETLB_PAGE_PRE_POISONED;
+       }
+       raw_hwp = kmalloc(sizeof(struct raw_hwp_page), GFP_ATOMIC);
+@@ -1804,41 +1814,38 @@ void hugetlb_clear_page_hwpoison(struct
+ /*
+  * Called from hugetlb code with hugetlb_lock held.
+- *
+- * Return values:
+- *   0             - free hugepage
+- *   1             - in-use hugepage
+- *   2             - not a hugepage
+- *   -EBUSY        - the hugepage is busy (try to retry)
+- *   -EHWPOISON    - the hugepage is already hwpoisoned
+  */
+ int __get_huge_page_for_hwpoison(unsigned long pfn, int flags)
+ {
+       struct page *page = pfn_to_page(pfn);
+       struct page *head = compound_head(page);
+-      int ret = 2;    /* fallback to normal page handling */
+       bool count_increased = false;
++      int ret, rc;
+-      if (!PageHeadHuge(head))
++      if (!PageHeadHuge(head)) {
++              ret = MF_HUGETLB_NON_HUGEPAGE;
+               goto out;
+-
+-      if (flags & MF_COUNT_INCREASED) {
+-              ret = 1;
++      } else if (flags & MF_COUNT_INCREASED) {
++              ret = MF_HUGETLB_IN_USED;
+               count_increased = true;
+       } else if (HPageFreed(head)) {
+-              ret = 0;
++              ret = MF_HUGETLB_FREED;
+       } else if (HPageMigratable(head)) {
+-              ret = get_page_unless_zero(head);
+-              if (ret)
++              if (get_page_unless_zero(head)) {
++                      ret = MF_HUGETLB_IN_USED;
+                       count_increased = true;
++              } else {
++                      ret = MF_HUGETLB_FREED;
++              }
+       } else {
+-              ret = -EBUSY;
++              ret = MF_HUGETLB_RETRY;
+               if (!(flags & MF_NO_RETRY))
+                       goto out;
+       }
+-      if (hugetlb_set_page_hwpoison(head, page)) {
+-              ret = -EHWPOISON;
++      rc = hugetlb_update_hwpoison(head, page);
++      if (rc >= MF_HUGETLB_FOLIO_PRE_POISONED) {
++              ret = rc;
+               goto out;
+       }
+@@ -1854,6 +1861,12 @@ out:
+  * with basic operations like hugepage allocation/free/demotion.
+  * So some of prechecks for hwpoison (pinning, and testing/setting
+  * PageHWPoison) should be done in single hugetlb_lock range.
++ * Returns:
++ *    0               - not hugetlb, or recovered
++ *    -EBUSY          - not recovered
++ *    -EOPNOTSUPP     - hwpoison_filter'ed
++ *    -EHWPOISON      - folio or exact page already poisoned
++ *    -EFAULT         - kill_accessing_process finds current->mm null
+  */
+ static int try_memory_failure_hugetlb(unsigned long pfn, int flags, int *hugetlb)
+ {
+@@ -1865,23 +1878,25 @@ static int try_memory_failure_hugetlb(un
+       *hugetlb = 1;
+ retry:
+       res = get_huge_page_for_hwpoison(pfn, flags);
+-      if (res == 2) { /* fallback to normal page handling */
++      if (res == MF_HUGETLB_NON_HUGEPAGE) { /* fallback to normal page handling */
+               *hugetlb = 0;
+               return 0;
+-      } else if (res == -EHWPOISON) {
++      } else if (res == MF_HUGETLB_FOLIO_PRE_POISONED ||
++                 res == MF_HUGETLB_PAGE_PRE_POISONED) {
+               pr_err("%#lx: already hardware poisoned\n", pfn);
++              res = -EHWPOISON;
+               if (flags & MF_ACTION_REQUIRED) {
+                       head = compound_head(p);
+                       res = kill_accessing_process(current, page_to_pfn(head), flags);
+               }
+               return res;
+-      } else if (res == -EBUSY) {
++      } else if (res == MF_HUGETLB_RETRY) {
+               if (!(flags & MF_NO_RETRY)) {
+                       flags |= MF_NO_RETRY;
+                       goto retry;
+               }
+               action_result(pfn, MF_MSG_UNKNOWN, MF_IGNORED);
+-              return res;
++              return -EBUSY;
+       }
+       head = compound_head(p);
+@@ -1890,7 +1905,7 @@ retry:
+       if (hwpoison_filter(p)) {
+               hugetlb_clear_page_hwpoison(head);
+               unlock_page(head);
+-              if (res == 1)
++              if (res == MF_HUGETLB_IN_USED)
+                       put_page(head);
+               return -EOPNOTSUPP;
+       }
+@@ -1899,7 +1914,7 @@ retry:
+        * Handling free hugepage.  The possible race with hugepage allocation
+        * or demotion can be prevented by PageHWPoison flag.
+        */
+-      if (res == 0) {
++      if (res == MF_HUGETLB_FREED) {
+               unlock_page(head);
+               if (__page_handle_poison(p) > 0) {
+                       page_ref_inc(p);
diff --git a/queue-6.1/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch b/queue-6.1/mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
new file mode 100644 (file)
index 0000000..bcf7eaa
--- /dev/null
@@ -0,0 +1,192 @@
+From stable+bounces-256792-greg=kroah.com@vger.kernel.org Sat May 30 03:18:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 17:48:42 -0400
+Subject: mm/memory: fix spurious warning when unmapping device-private/exclusive pages
+To: stable@vger.kernel.org
+Cc: "Alistair Popple" <apopple@nvidia.com>, "Arsen Arsenović" <aarsenovic@baylibre.com>, "Balbir Singh" <balbirs@nvidia.com>, "David Hildenbrand" <david@kernel.org>, "Jason Gunthorpe" <jgg@ziepe.ca>, "John Hubbard" <jhubbard@nvidia.com>, "Leon Romanovsky" <leon@kernel.org>, "Liam R. Howlett" <liam@infradead.org>, "Lorenzo Stoakes" <ljs@kernel.org>, "Peter Xu" <peterx@redhat.com>, "Matthew Brost" <matthew.brost@intel.com>, "Michal Hocko" <mhocko@suse.com>, "Mike Rapoport" <rppt@kernel.org>, "Shuah Khan" <shuah@kernel.org>, "Suren Baghdasaryan" <surenb@google.com>, "Thomas Hellström" <thomas.hellstrom@linux.intel.com>, "Vlastimil Babka" <vbabka@kernel.org>, "Andrew Morton" <akpm@linux-foundation.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260529214842.1804656-1-sashal@kernel.org>
+
+From: Alistair Popple <apopple@nvidia.com>
+
+[ Upstream commit be3f38d05cc5a7c3f13e51994c5dd043ab604d28 ]
+
+Device private and exclusive entries are only supported for anonymous
+folios.  This condition is tested in __migrate_device_pages() and
+make_device_exclusive() using folio_test_anon().  However the unmap path
+tests this assumption using vma_is_anonymous().
+
+This is wrong because whilst anonymous VMAs can only contain folios where
+folio_test_anon() is true the opposite relation does not hold.  A folio
+for which folio_test_anon() is true does not imply vma_is_anonymous() is
+true.  Such a condition can occur if for example a folio is part of a
+private filebacked mapping.
+
+In this case vma_is_anonymous() is false as the mapping is filebacked, but
+folio_test_anon() may be true, thus permitting devices to migrate the
+folio to device private memory.  This can lead to the following spurious
+warnings during process teardown:
+
+[  772.737706] ------------[ cut here ]------------
+[  772.739201] WARNING: mm/memory.c:1754 at unmap_page_range.cold+0x26/0x18a, CPU#17: hmm-tests/2041
+[  772.742050] Modules linked in: test_hmm nvidia_uvm(O) nvidia(O)
+[  772.743959] CPU: 17 UID: 0 PID: 2041 Comm: hmm-tests Tainted: G        W  O        7.0.0+ #387 PREEMPT(full)
+[  772.747104] Tainted: [W]=WARN, [O]=OOT_MODULE
+[  772.748509] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
+[  772.752117] RIP: 0010:unmap_page_range.cold+0x26/0x18a
+[  772.753780] Code: 7e fe ff ff 48 89 4c 24 78 4c 89 44 24 38 e8 f2 ff b1 00 48 8b 4c 24 78 4c 8b 44 24 38 48 8b 44 24 18 48 83 78 48 00 74 04 90 <0f> 0b 90 48 89 ca b8 ff ff 37 00 48 c1 ea 03 48 c1 e0 2a 80 3c 02
+[  772.759602] RSP: 0018:ffff888112607550 EFLAGS: 00010286
+[  772.761310] RAX: ffff88811bbf4dc0 RBX: dffffc0000000000 RCX: ffffea03e9bfffd8
+[  772.763583] RDX: 1ffff1102377e9c1 RSI: 0000000000000008 RDI: ffff88811bbf4e08
+[  772.765914] RBP: 0000000000000006 R08: ffff8881059f7448 R09: ffffed10224c0e68
+[  772.768184] R10: ffff888112607347 R11: 0000000000000001 R12: 0000000000000001
+[  772.770461] R13: ffffea03e9bfffc0 R14: ffff888112607908 R15: ffffea03e9bfffc0
+[  772.772782] FS:  00007f327caa2780(0000) GS:ffff888427b7d000(0000) knlGS:0000000000000000
+[  772.775328] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  772.777187] CR2: 00007f327ca89000 CR3: 00000001994d5000 CR4: 00000000000006f0
+[  772.779135] Call Trace:
+[  772.779792]  <TASK>
+[  772.780317]  ? dmirror_interval_invalidate+0x1a3/0x290 [test_hmm]
+[  772.781873]  ? vm_normal_page_pud+0x2b0/0x2b0
+[  772.782992]  ? __rwlock_init+0x150/0x150
+[  772.784006]  ? lock_release+0x216/0x2b0
+[  772.785008]  ? __mmu_notifier_invalidate_range_start+0x505/0x6e0
+[  772.786522]  ? lock_release+0x216/0x2b0
+[  772.787498]  ? unmap_single_vma+0xb6/0x210
+[  772.788573]  unmap_vmas+0x27d/0x520
+[  772.789506]  ? unmap_single_vma+0x210/0x210
+[  772.790607]  ? mas_update_gap.part.0+0x620/0x620
+[  772.791834]  unmap_region+0x19e/0x350
+[  772.792769]  ? remove_vma+0x130/0x130
+[  772.793684]  ? mas_alloc_nodes+0x1f2/0x300
+[  772.794730]  vms_complete_munmap_vmas+0x8c1/0xe20
+[  772.795926]  ? unmap_region+0x350/0x350
+[  772.796917]  do_vmi_align_munmap+0x36a/0x4e0
+[  772.798018]  ? lock_release+0x216/0x2b0
+[  772.799024]  ? vma_shrink+0x620/0x620
+[  772.799983]  do_vmi_munmap+0x150/0x2c0
+[  772.800939]  __vm_munmap+0x161/0x2c0
+[  772.801872]  ? expand_downwards+0xd60/0xd60
+[  772.802948]  ? clockevents_program_event+0x1ef/0x540
+[  772.804217]  ? lock_release+0x216/0x2b0
+[  772.805158]  __x64_sys_munmap+0x59/0x80
+[  772.805776]  do_syscall_64+0xfc/0x670
+[  772.806336]  ? irqentry_exit+0xda/0x580
+[  772.806976]  entry_SYSCALL_64_after_hwframe+0x4b/0x53
+[  772.807772] RIP: 0033:0x7f327cbb2717
+[  772.808323] Code: 73 01 c3 48 8b 0d f9 76 0d 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 b8 0b 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d c9 76 0d 00 f7 d8 64 89 01 48
+[  772.811337] RSP: 002b:00007ffde7f57d38 EFLAGS: 00000202 ORIG_RAX: 000000000000000b
+[  772.812564] RAX: ffffffffffffffda RBX: 00007f327cc9c000 RCX: 00007f327cbb2717
+[  772.813733] RDX: 0000000000000000 RSI: 0000000000400000 RDI: 00007f327c289000
+[  772.814867] RBP: 0000000000421360 R08: 000000000000001a R09: 0000000000000000
+[  772.815991] R10: 0000000000000003 R11: 0000000000000202 R12: 00007ffde7f57d74
+[  772.817121] R13: 00007f327c689010 R14: 0000000000100000 R15: 00007f327c289000
+[  772.818272]  </TASK>
+[  772.818614] irq event stamp: 0
+[  772.819159] hardirqs last  enabled at (0): [<0000000000000000>] 0x0
+[  772.820174] hardirqs last disabled at (0): [<ffffffff82a57ab3>] copy_process+0x19f3/0x6440
+[  772.821511] softirqs last  enabled at (0): [<ffffffff82a57b00>] copy_process+0x1a40/0x6440
+[  772.822869] softirqs last disabled at (0): [<0000000000000000>] 0x0
+[  772.823871] ---[ end trace 0000000000000000 ]---
+
+Fix this by using the same check for folio_test_anon() in
+zap_nonpresent_ptes(). Also add a hmm-test case for this.
+
+Link: https://lore.kernel.org/20260501065116.2057242-1-apopple@nvidia.com
+Fixes: 999dad824c39 ("mm/shmem: persist uffd-wp bit across zapping for file-backed")
+Signed-off-by: Alistair Popple <apopple@nvidia.com>
+Reported-by: Arsen Arsenović <aarsenovic@baylibre.com>
+Reviewed-by: Balbir Singh <balbirs@nvidia.com>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Jason Gunthorpe <jgg@ziepe.ca>
+Cc: John Hubbard <jhubbard@nvidia.com>
+Cc: Leon Romanovsky <leon@kernel.org>
+Cc: Liam R. Howlett <liam@infradead.org>
+Cc: Lorenzo Stoakes <ljs@kernel.org>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Matthew Brost <matthew.brost@intel.com>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Shuah Khan <shuah@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
+Cc: Vlastimil Babka <vbabka@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+[ adapted `folio_test_anon(folio)` to `PageAnon(page)` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/memory.c                            |    2 -
+ tools/testing/selftests/vm/hmm-tests.c |   50 +++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+), 1 deletion(-)
+
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -1471,7 +1471,7 @@ again:
+                        * consider uffd-wp bit when zap. For more information,
+                        * see zap_install_uffd_wp_if_needed().
+                        */
+-                      WARN_ON_ONCE(!vma_is_anonymous(vma));
++                      WARN_ON_ONCE(!PageAnon(page));
+                       rss[mm_counter(page)]--;
+                       if (is_device_private_entry(entry))
+                               page_remove_rmap(page, vma, false);
+--- a/tools/testing/selftests/vm/hmm-tests.c
++++ b/tools/testing/selftests/vm/hmm-tests.c
+@@ -994,6 +994,56 @@ TEST_F(hmm, migrate)
+ }
+ /*
++ * Migrate private file memory to device private memory.
++ */
++TEST_F(hmm, migrate_file_private)
++{
++      struct hmm_buffer *buffer;
++      unsigned long npages;
++      unsigned long size;
++      unsigned long i;
++      int *ptr;
++      int ret;
++      int fd;
++
++      npages = ALIGN(HMM_BUFFER_SIZE, self->page_size) >> self->page_shift;
++      ASSERT_NE(npages, 0);
++      size = npages << self->page_shift;
++
++      fd = hmm_create_file(size);
++      ASSERT_GE(fd, 0);
++
++      buffer = malloc(sizeof(*buffer));
++      ASSERT_NE(buffer, NULL);
++
++      buffer->fd = fd;
++      buffer->size = size;
++      buffer->mirror = malloc(size);
++      ASSERT_NE(buffer->mirror, NULL);
++
++      buffer->ptr = mmap(NULL, size,
++                         PROT_READ | PROT_WRITE,
++                         MAP_PRIVATE,
++                         buffer->fd, 0);
++      ASSERT_NE(buffer->ptr, MAP_FAILED);
++
++      /* Initialize buffer in system memory. */
++      for (i = 0, ptr = buffer->ptr; i < size / sizeof(*ptr); ++i)
++              ptr[i] = i;
++
++      /* Migrate memory to device. */
++      ret = hmm_migrate_sys_to_dev(self->fd, buffer, npages);
++      ASSERT_EQ(ret, 0);
++      ASSERT_EQ(buffer->cpages, npages);
++
++      /* Check what the device read. */
++      for (i = 0, ptr = buffer->mirror; i < size / sizeof(*ptr); ++i)
++              ASSERT_EQ(ptr[i], i);
++
++      hmm_buffer_free(buffer);
++}
++
++/*
+  * Migrate anonymous memory to device private memory and fault some of it back
+  * to system memory, then try migrating the resulting mix of system and device
+  * private memory to the device.
diff --git a/queue-6.1/mm-migrate-don-t-call-folio_putback_active_hugetlb-on-dst-hugetlb-folio.patch b/queue-6.1/mm-migrate-don-t-call-folio_putback_active_hugetlb-on-dst-hugetlb-folio.patch
new file mode 100644 (file)
index 0000000..3ce9738
--- /dev/null
@@ -0,0 +1,83 @@
+From stable+bounces-263444-greg=kroah.com@vger.kernel.org Tue Jun 16 01:12:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 15:42:34 -0400
+Subject: mm/migrate: don't call folio_putback_active_hugetlb() on dst hugetlb folio
+To: stable@vger.kernel.org
+Cc: David Hildenbrand <david@redhat.com>, Baolin Wang <baolin.wang@linux.alibaba.com>, "Matthew Wilcox (Oracle)" <willy@infradead.org>, Muchun Song <muchun.song@linux.dev>, Sidhartha Kumar <sidhartha.kumar@oracle.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260615194237.2391157-2-sashal@kernel.org>
+
+From: David Hildenbrand <david@redhat.com>
+
+[ Upstream commit ba23f58de896842028b4b33b95530f08288396fe ]
+
+We replaced a simple put_page() by a putback_active_hugepage() call in
+commit 3aaa76e125c1 ("mm: migrate: hugetlb: putback destination hugepage
+to active list"), to set the "active" flag on the dst hugetlb folio.
+
+Nowadays, we decoupled the "active" list from the flag, by calling the
+flag "migratable".
+
+Calling "putback" on something that wasn't allocated is weird and not
+future proof, especially if we might reach that path when migration failed
+and we just want to free the freshly allocated hugetlb folio.
+
+Let's simply handle the migratable flag and the active list flag in
+move_hugetlb_state(), where we know that allocation succeeded and already
+handle the temporary flag; use a simple folio_put() to return our
+reference.
+
+Link: https://lkml.kernel.org/r/20250113131611.2554758-4-david@redhat.com
+Signed-off-by: David Hildenbrand <david@redhat.com>
+Reviewed-by: Baolin Wang <baolin.wang@linux.alibaba.com>
+Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
+Cc: Muchun Song <muchun.song@linux.dev>
+Cc: Sidhartha Kumar <sidhartha.kumar@oracle.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 3c2d42b8ee34 ("mm/memory-failure: fix hugetlb_lock AA deadlock in get_huge_page_for_hwpoison")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/hugetlb.c |   10 ++++++++++
+ mm/migrate.c |    8 ++++----
+ 2 files changed, 14 insertions(+), 4 deletions(-)
+
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -7555,6 +7555,16 @@ void move_hugetlb_state(struct page *old
+               }
+               spin_unlock_irq(&hugetlb_lock);
+       }
++
++      /*
++       * Our old page is isolated and has "migratable" cleared until it
++       * is putback. As migration succeeded, set the new page "migratable"
++       * and add it to the active list.
++       */
++      spin_lock_irq(&hugetlb_lock);
++      SetHPageMigratable(newpage);
++      list_move_tail(&newpage->lru, &(page_hstate(newpage))->hugepage_activelist);
++      spin_unlock_irq(&hugetlb_lock);
+ }
+ /*
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -1460,14 +1460,14 @@ out:
+               list_move_tail(&src->lru, ret);
+       /*
+-       * If migration was not successful and there's a freeing callback, use
+-       * it.  Otherwise, put_page() will drop the reference grabbed during
+-       * isolation.
++       * If migration was not successful and there's a freeing callback,
++       * return the folio to that special allocator. Otherwise, simply drop
++       * our additional reference.
+        */
+       if (put_new_page)
+               put_new_page(new_hpage, private);
+       else
+-              putback_active_hugepage(new_hpage);
++              folio_put(dst);
+       return rc;
+ }
diff --git a/queue-6.1/mptcp-do-not-drop-partial-packets.patch b/queue-6.1/mptcp-do-not-drop-partial-packets.patch
new file mode 100644 (file)
index 0000000..2bec1ff
--- /dev/null
@@ -0,0 +1,76 @@
+From stable+bounces-257079-greg=kroah.com@vger.kernel.org Sat May 30 22:22:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 12:48:34 -0400
+Subject: mptcp: do not drop partial packets
+To: stable@vger.kernel.org
+Cc: Shardul Bankar <shardul.b@mpiricsoftware.com>, Paolo Abeni <pabeni@redhat.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530164834.2992487-1-sashal@kernel.org>
+
+From: Shardul Bankar <shardul.b@mpiricsoftware.com>
+
+[ Upstream commit 50c2d91c5dfa0e465826ec1f8dbad9cdc254bd85 ]
+
+When a packet arrives with map_seq < ack_seq < end_seq, the beginning
+of the packet has already been acknowledged but the end contains new
+data. Currently the entire packet is dropped as "old data," forcing
+the sender to retransmit.
+
+Instead, skip the already-acked bytes by adjusting the skb offset and
+enqueue only the new portion. Update bytes_received and ack_seq to
+reflect the new data consumed.
+
+A previous attempt at this fix has been sent by Paolo Abeni [1], but had
+issues [2]: it also added a zero-window check and changed rcv_wnd_sent
+initialization, which caused test regressions. This version addresses
+only the partial packet handling without modifying receive window
+accounting.
+
+Fixes: ab174ad8ef76 ("mptcp: move ooo skbs into msk out of order queue.")
+Cc: stable@vger.kernel.org
+Link: https://lore.kernel.org/c9b426a4e163aa3c4fe8b80c79f1a610f47ae7d8.1763075056.git.pabeni@redhat.com [1]
+Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/600 [2]
+Signed-off-by: Shardul Bankar <shardul.b@mpiricsoftware.com>
+[pabeni@redhat.com: update map]
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-1-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+[ changed `skb_set_owner_r()` to `mptcp_set_owner_r()` and dropped the absent `msk->bytes_received` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |   21 ++++++++++++++++++---
+ 1 file changed, 18 insertions(+), 3 deletions(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -400,10 +400,25 @@ static bool __mptcp_move_skb(struct mptc
+               return false;
+       }
+-      /* old data, keep it simple and drop the whole pkt, sender
+-       * will retransmit as needed, if needed.
++      /* Completely old data? */
++      if (!after64(MPTCP_SKB_CB(skb)->end_seq, msk->ack_seq)) {
++              MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
++              mptcp_drop(sk, skb);
++              return false;
++      }
++
++      /* Partial packet: map_seq < ack_seq < end_seq.
++       * Skip the already-acked bytes and enqueue the new data.
+        */
+-      MPTCP_INC_STATS(sock_net(sk), MPTCP_MIB_DUPDATA);
++      copy_len = MPTCP_SKB_CB(skb)->end_seq - msk->ack_seq;
++      MPTCP_SKB_CB(skb)->offset += msk->ack_seq - MPTCP_SKB_CB(skb)->map_seq;
++      MPTCP_SKB_CB(skb)->map_seq += msk->ack_seq -
++                                    MPTCP_SKB_CB(skb)->map_seq;
++      WRITE_ONCE(msk->ack_seq, msk->ack_seq + copy_len);
++
++      mptcp_set_owner_r(skb, sk);
++      __skb_queue_tail(&sk->sk_receive_queue, skb);
++      return true;
+ drop:
+       mptcp_drop(sk, skb);
+       return false;
diff --git a/queue-6.1/mptcp-fastclose-msk-when-linger-time-is-0.patch b/queue-6.1/mptcp-fastclose-msk-when-linger-time-is-0.patch
new file mode 100644 (file)
index 0000000..b854ade
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-249177-greg=kroah.com@vger.kernel.org Mon May 18 08:58:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 23:28:15 -0400
+Subject: mptcp: fastclose msk when linger time is 0
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Lance Tuller <lance@lance0.com>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518032815.587921-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit f14d6e9c3678a067f304abba561e0c5446c7e845 ]
+
+The SO_LINGER socket option has been supported for a while with MPTCP
+sockets [1], but it didn't cause the equivalent of a TCP reset as
+expected when enabled and its time was set to 0. This was causing some
+behavioural differences with TCP where some connections were not
+promptly stopped as expected.
+
+To fix that, an extra condition is checked at close() time before
+sending an MP_FASTCLOSE, the MPTCP equivalent of a TCP reset.
+
+Note that backporting up to [1] will be difficult as more changes are
+needed to be able to send MP_FASTCLOSE. It seems better to stop at [2],
+which was supposed to already imitate TCP.
+
+Validated with MPTCP packetdrill tests [3].
+
+Fixes: 268b12387460 ("mptcp: setsockopt: support SO_LINGER") [1]
+Fixes: d21f83485518 ("mptcp: use fastclose on more edge scenarios") [2]
+Cc: stable@vger.kernel.org
+Reported-by: Lance Tuller <lance@lance0.com>
+Closes: https://github.com/lance0/xfr/pull/67
+Link: https://github.com/multipath-tcp/packetdrill/pull/196 [3]
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260427-net-mptcp-misc-fixes-7-1-rc2-v1-3-7432b7f279fa@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ kept `mptcp_check_readable()` name and explicit `inet_sk_state_store(sk, TCP_CLOSE)` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -3158,7 +3158,8 @@ bool __mptcp_close(struct sock *sk, long
+               goto cleanup;
+       }
+-      if (mptcp_check_readable(msk)) {
++      if (mptcp_check_readable(msk) ||
++          (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) {
+               /* the msk has read data, do the MPTCP equivalent of TCP reset */
+               inet_sk_state_store(sk, TCP_CLOSE);
+               mptcp_do_fastclose(sk);
diff --git a/queue-6.1/mptcp-pm-add_addr-rtx-allow-id-0.patch b/queue-6.1/mptcp-pm-add_addr-rtx-allow-id-0.patch
new file mode 100644 (file)
index 0000000..78df45e
--- /dev/null
@@ -0,0 +1,44 @@
+From stable+bounces-249310-greg=kroah.com@vger.kernel.org Mon May 18 20:15:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 10:33:51 -0400
+Subject: mptcp: pm: ADD_ADDR rtx: allow ID 0
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518143351.1340874-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 03f324f3f1f7619a47b9c91282cb12775ab0a2f1 ]
+
+ADD_ADDR can be sent for the ID 0, which corresponds to the local
+address and port linked to the initial subflow.
+
+Indeed, this address could be removed, and re-added later on, e.g. what
+is done in the "delete re-add signal" MPTCP Join selftests. So no reason
+to ignore it.
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-2-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ relocated the 3-line deletion from net/mptcp/pm.c to net/mptcp/pm_netlink.c ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |    3 ---
+ 1 file changed, 3 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -315,9 +315,6 @@ static void mptcp_pm_add_timer(struct ti
+       if (inet_sk_state_load(sk) == TCP_CLOSE)
+               return;
+-      if (!entry->addr.id)
+-              return;
+-
+       if (mptcp_pm_should_add_signal_addr(msk)) {
+               sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
+               goto out;
diff --git a/queue-6.1/mptcp-pm-add_addr-rtx-fix-potential-data-race.patch b/queue-6.1/mptcp-pm-add_addr-rtx-fix-potential-data-race.patch
new file mode 100644 (file)
index 0000000..5f5267b
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-249311-greg=kroah.com@vger.kernel.org Mon May 18 20:20:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 10:33:55 -0400
+Subject: mptcp: pm: ADD_ADDR rtx: fix potential data-race
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518143355.1341039-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 5cd6e0ad79d2615264f63929f8b457ad97ae550d ]
+
+This mptcp_pm_add_timer() helper is executed as a timer callback in
+softirq context. To avoid any data races, the socket lock needs to be
+held with bh_lock_sock().
+
+If the socket is in use, retry again soon after, similar to what is done
+with the keepalive timer.
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-3-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -315,6 +315,13 @@ static void mptcp_pm_add_timer(struct ti
+       if (inet_sk_state_load(sk) == TCP_CLOSE)
+               return;
++      bh_lock_sock(sk);
++      if (sock_owned_by_user(sk)) {
++              /* Try again later. */
++              sk_reset_timer(sk, timer, jiffies + HZ / 20);
++              goto out;
++      }
++
+       if (mptcp_pm_should_add_signal_addr(msk)) {
+               sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
+               goto out;
+@@ -343,6 +350,7 @@ static void mptcp_pm_add_timer(struct ti
+               mptcp_pm_subflow_established(msk);
+ out:
++      bh_unlock_sock(sk);
+       __sock_put(sk);
+ }
diff --git a/queue-6.1/mptcp-pm-add_addr-rtx-resched-blocked-add_addr-quicker.patch b/queue-6.1/mptcp-pm-add_addr-rtx-resched-blocked-add_addr-quicker.patch
new file mode 100644 (file)
index 0000000..3840a6d
--- /dev/null
@@ -0,0 +1,53 @@
+From stable+bounces-249577-greg=kroah.com@vger.kernel.org Tue May 19 18:18:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 19 May 2026 08:41:06 -0400
+Subject: mptcp: pm: ADD_ADDR rtx: resched blocked ADD_ADDR quicker
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260519124106.2431795-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 3cf12492891c4b5ff54dda404a2de4ec54c9e1b5 ]
+
+When an ADD_ADDR needs to be retransmitted and another one has already
+been prepared -- e.g. multiple ADD_ADDRs have been sent in a row and
+need to be retransmitted later -- this additional retransmission will
+need to wait.
+
+In this case, the timer was reset to TCP_RTO_MAX / 8, which is ~15
+seconds. This delay is unnecessary long: it should just be rescheduled
+at the next opportunity, e.g. after the retransmission timeout.
+
+Without this modification, some issues can be seen from time to time in
+the selftests when multiple ADD_ADDRs are sent, and the host takes time
+to process them, e.g. the "signal addresses, ADD_ADDR timeout" MPTCP
+Join selftest, especially with a debug kernel config.
+
+Note that on older kernels, 'timeout' is not available. It should be
+enough to replace it by one second (HZ).
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-6-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ replaced `TCP_RTO_MAX / 8` with `HZ` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -323,7 +323,7 @@ static void mptcp_pm_add_timer(struct ti
+       }
+       if (mptcp_pm_should_add_signal_addr(msk)) {
+-              sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
++              sk_reset_timer(sk, timer, jiffies + HZ);
+               goto out;
+       }
diff --git a/queue-6.1/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch b/queue-6.1/mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch
new file mode 100644 (file)
index 0000000..aff7528
--- /dev/null
@@ -0,0 +1,144 @@
+From stable+bounces-256871-greg=kroah.com@vger.kernel.org Sat May 30 17:09:18 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 07:39:11 -0400
+Subject: mptcp: pm: fix ADD_ADDR timer infinite retry on option space insufficient
+To: stable@vger.kernel.org
+Cc: Li Xiasong <lixiasong1@huawei.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530113911.1938311-1-sashal@kernel.org>
+
+From: Li Xiasong <lixiasong1@huawei.com>
+
+[ Upstream commit 51e398a3b8961b26a8c0a4ba9a777c5339791707 ]
+
+When TCP option space is insufficient (e.g., when sending ADD_ADDR with an
+IPv6 address and port while tcp_timestamps is enabled), the original code
+jumped to out_unlock without clearing the addr_signal flag. This caused
+mptcp_pm_add_timer to keep rescheduling indefinitely, not sending ADD_ADDR,
+preventing subsequent addresses in the endpoint list from being announced.
+
+Handle this case by clearing the ADD_ADDR signal and skipping the matching
+ADD_ADDR retransmission entry. The skip path cancels the matching timer
+(with id check) and advances PM state progression, preserving forward
+progress to subsequent PM work.
+
+This cancellation is inherently best-effort. A concurrent add_timer
+callback may already be running and may acquire pm.lock before the
+cancel path updates entry state. In that case, one final ADD_ADDR
+transmit attempt can still be executed.
+
+Once the cancel path sets entry->retrans_times to ADD_ADDR_RETRANS_MAX,
+the callback-side retrans_times check suppresses further ADD_ADDR
+retransmissions.
+
+Note that when an ADD_ADDR is being prepared, a pure-ACK is queued. On
+the output side, it means that it is fine to skip non-pure-ACK packets,
+when drop_other_suboptions is set: a pure-ACK will be processed soon
+after.
+
+Fixes: 00cfd77b9063 ("mptcp: retransmit ADD_ADDR when timeout")
+Cc: stable@vger.kernel.org
+Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-2-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm.c         |   34 +++++++++++++++++++++++++++-------
+ net/mptcp/pm_netlink.c |   16 +++++++++++++---
+ 2 files changed, 40 insertions(+), 10 deletions(-)
+
+--- a/net/mptcp/pm.c
++++ b/net/mptcp/pm.c
+@@ -340,6 +340,7 @@ bool mptcp_pm_add_addr_signal(struct mpt
+                             struct mptcp_addr_info *addr, bool *echo,
+                             bool *drop_other_suboptions)
+ {
++      bool skip_add_addr = false;
+       int ret = false;
+       u8 add_addr;
+       u8 family;
+@@ -361,24 +362,43 @@ bool mptcp_pm_add_addr_signal(struct mpt
+       }
+       *echo = mptcp_pm_should_add_signal_echo(msk);
+-      port = !!(*echo ? msk->pm.remote.port : msk->pm.local.port);
+-
+-      family = *echo ? msk->pm.remote.family : msk->pm.local.family;
+-      if (remaining < mptcp_add_addr_len(family, *echo, port))
+-              goto out_unlock;
+-
+       if (*echo) {
+               *addr = msk->pm.remote;
+               add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_ECHO);
++              port = !!msk->pm.remote.port;
++              family = msk->pm.remote.family;
+       } else {
+               *addr = msk->pm.local;
+               add_addr = msk->pm.addr_signal & ~BIT(MPTCP_ADD_ADDR_SIGNAL);
++              port = !!msk->pm.local.port;
++              family = msk->pm.local.family;
+       }
+-      WRITE_ONCE(msk->pm.addr_signal, add_addr);
++
++      if (remaining < mptcp_add_addr_len(family, *echo, port)) {
++              if (!*drop_other_suboptions)
++                      goto out_unlock;
++
++              if (!*echo)
++                      skip_add_addr = true;
++              goto drop_signal_mark;
++      }
++
+       ret = true;
++drop_signal_mark:
++      WRITE_ONCE(msk->pm.addr_signal, add_addr);
++
+ out_unlock:
+       spin_unlock_bh(&msk->pm.lock);
++
++      /* On pure-ACK option-space exhaustion, stop retrying this ADD_ADDR:
++       * clear the signal bit, cancel the matching retransmission timer, and
++       * let the PM state machine progress.
++       */
++      if (skip_add_addr) {
++              mptcp_pm_del_add_timer(msk, addr, true);
++              mptcp_pm_subflow_established(msk);
++      }
+       return ret;
+ }
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -333,7 +333,13 @@ static void mptcp_pm_add_timer(struct ti
+       spin_lock_bh(&msk->pm.lock);
+-      if (!mptcp_pm_should_add_signal_addr(msk)) {
++      /* The cancel path (mptcp_pm_del_add_timer()) can race with this
++       * callback. Once cancel updates retrans_times to MAX, suppress further
++       * retransmissions here. If this callback acquires pm.lock first, one
++       * final transmit attempt is still possible.
++       */
++      if (entry->retrans_times < ADD_ADDR_RETRANS_MAX &&
++          !mptcp_pm_should_add_signal_addr(msk)) {
+               pr_debug("retransmit ADD_ADDR id=%d\n", entry->addr.id);
+               mptcp_pm_announce_addr(msk, &entry->addr, false);
+               mptcp_pm_add_addr_send_ack(msk);
+@@ -377,8 +383,12 @@ mptcp_pm_del_add_timer(struct mptcp_sock
+       /* Note: entry might have been removed by another thread.
+        * We hold rcu_read_lock() to ensure it is not freed under us.
+        */
+-      if (stop_timer)
+-              sk_stop_timer_sync(sk, &entry->add_timer);
++      if (stop_timer) {
++              if (check_id)
++                      sk_stop_timer(sk, &entry->add_timer);
++              else
++                      sk_stop_timer_sync(sk, &entry->add_timer);
++      }
+       rcu_read_unlock();
+       return entry;
diff --git a/queue-6.1/mptcp-pm-kernel-correctly-retransmit-add_addr-id-0.patch b/queue-6.1/mptcp-pm-kernel-correctly-retransmit-add_addr-id-0.patch
new file mode 100644 (file)
index 0000000..74c2e77
--- /dev/null
@@ -0,0 +1,71 @@
+From stable+bounces-249306-greg=kroah.com@vger.kernel.org Mon May 18 20:02:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 10:23:40 -0400
+Subject: mptcp: pm: kernel: correctly retransmit ADD_ADDR ID 0
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518142340.1308453-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit b12014d2d36eaed4e4bec5f1ac7e91110eeb100d ]
+
+When adding the ADD_ADDR to the list, the address including the IP, port
+and ID are copied. On the other hand, when the endpoint corresponds to
+the one from the initial subflow, the ID is set to 0, as specified by
+the MPTCP protocol.
+
+The issue is that the ID was reset after having copied the ID in the
+ADD_ADDR entry. So the retransmission was done, but using a different ID
+than the initial one.
+
+Fixes: 8b8ed1b429f8 ("mptcp: pm: reuse ID 0 after delete and re-add")
+Cc: stable@vger.kernel.org
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-1-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied to net/mptcp/pm_netlink.c instead of upstream's pm_kernel.c ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |   13 ++++++++-----
+ 1 file changed, 8 insertions(+), 5 deletions(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -595,6 +595,8 @@ static void mptcp_pm_create_subflow_or_s
+       /* check first for announce */
+       if (msk->pm.add_addr_signaled < add_addr_signal_max) {
++              u8 endp_id;
++
+               /* due to racing events on both ends we can reach here while
+                * previous add address is still running: if we invoke now
+                * mptcp_pm_announce_addr(), that will fail and the
+@@ -608,19 +610,20 @@ static void mptcp_pm_create_subflow_or_s
+               if (!select_signal_address(pernet, msk, &local))
+                       goto subflow;
++              /* Special case for ID0: set the correct ID */
++              endp_id = local.addr.id;
++              if (endp_id == msk->mpc_endpoint_id)
++                      local.addr.id = 0;
++
+               /* If the alloc fails, we are on memory pressure, not worth
+                * continuing, and trying to create subflows.
+                */
+               if (!mptcp_pm_alloc_anno_list(msk, &local.addr))
+                       return;
+-              __clear_bit(local.addr.id, msk->pm.id_avail_bitmap);
++              __clear_bit(endp_id, msk->pm.id_avail_bitmap);
+               msk->pm.add_addr_signaled++;
+-              /* Special case for ID0: set the correct ID */
+-              if (local.addr.id == msk->mpc_endpoint_id)
+-                      local.addr.id = 0;
+-
+               mptcp_pm_announce_addr(msk, &local.addr, false);
+               mptcp_pm_nl_addr_send_ack(msk);
diff --git a/queue-6.1/mptcp-pm-prio-skip-closed-subflows.patch b/queue-6.1/mptcp-pm-prio-skip-closed-subflows.patch
new file mode 100644 (file)
index 0000000..ad724c4
--- /dev/null
@@ -0,0 +1,46 @@
+From stable+bounces-249292-greg=kroah.com@vger.kernel.org Mon May 18 19:22:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 May 2026 09:45:31 -0400
+Subject: mptcp: pm: prio: skip closed subflows
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260518134531.1135631-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 166b78344031bf7ac9f55cb5282776cfd85f220e ]
+
+When sending an MP_PRIO, closed subflows need to be skipped.
+
+This fixes the case where the initial subflow got closed, re-opened
+later, then an MP_PRIO is needed for the same local address.
+
+Note that explicit MP_PRIO cannot be sent during the 3WHS, so it is fine
+to use __mptcp_subflow_active().
+
+Fixes: 067065422fcd ("mptcp: add the outgoing MP_PRIO support")
+Cc: stable@vger.kernel.org
+Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
+Reviewed-by: Mat Martineau <martineau@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260505-net-mptcp-pm-fixes-7-1-rc3-v1-9-fca8091060a4@kernel.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ applied to renamed function `mptcp_pm_nl_mp_prio_send_ack()` in `pm_netlink.c` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -924,6 +924,9 @@ int mptcp_pm_nl_mp_prio_send_ack(struct
+               struct sock *ssk = mptcp_subflow_tcp_sock(subflow);
+               struct mptcp_addr_info local, remote;
++              if (!__mptcp_subflow_active(subflow))
++                      continue;
++
+               mptcp_local_address((struct sock_common *)ssk, &local);
+               if (!mptcp_addresses_equal(&local, addr, addr->port))
+                       continue;
diff --git a/queue-6.1/mptcp-reset-rcv-wnd-on-disconnect.patch b/queue-6.1/mptcp-reset-rcv-wnd-on-disconnect.patch
new file mode 100644 (file)
index 0000000..724d02d
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-257008-greg=kroah.com@vger.kernel.org Sat May 30 22:01:25 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 12:31:14 -0400
+Subject: mptcp: reset rcv wnd on disconnect
+To: stable@vger.kernel.org
+Cc: Paolo Abeni <pabeni@redhat.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530163114.2911574-1-sashal@kernel.org>
+
+From: Paolo Abeni <pabeni@redhat.com>
+
+[ Upstream commit 0981f90e1a05773a4c29c6e720f5ea1e3c8f1876 ]
+
+If the MPTCP socket fallback to TCP before the MP handshake completion,
+the IASN remain 0, and the rcv_wnd_sent field is not explicitly
+initialized, just incremented over time with the data transfer.
+
+At disconnect time such value is not cleared. If the next connection falls
+back to TCP before the MP handshake completion, the data transfer will
+keep incrementing the receive window end sequence starting from the last
+value used in the previous connection: the announced window will be
+unrelated from the actual receiver buffer size and likely too big.
+
+Address the issue zeroing the field at disconnect time.
+
+Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
+Cc: stable@vger.kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-4-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/protocol.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/mptcp/protocol.c
++++ b/net/mptcp/protocol.c
+@@ -3298,6 +3298,7 @@ static int mptcp_disconnect(struct sock
+       mptcp_pm_data_reset(msk);
+       mptcp_ca_reset(sk);
+       msk->fastclosing = 0;
++      atomic64_set(&msk->rcv_wnd_sent, 0);
+       WRITE_ONCE(sk->sk_shutdown, 0);
+       sk_error_report(sk);
diff --git a/queue-6.1/mtd-spi-nor-core-fix-implicit-declaration-warning.patch b/queue-6.1/mtd-spi-nor-core-fix-implicit-declaration-warning.patch
new file mode 100644 (file)
index 0000000..9c8b75d
--- /dev/null
@@ -0,0 +1,41 @@
+From stable+bounces-247170-greg=kroah.com@vger.kernel.org Thu May 14 17:15:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 07:45:39 -0400
+Subject: mtd: spi-nor: core: fix implicit declaration warning
+To: stable@vger.kernel.org
+Cc: Zeng Heng <zengheng4@huawei.com>, Tudor Ambarus <tudor.ambarus@linaro.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514114540.178942-1-sashal@kernel.org>
+
+From: Zeng Heng <zengheng4@huawei.com>
+
+[ Upstream commit 25e3f30601a368642678744fc8a9b1dce183c7bc ]
+
+spi-nor/core.c needs to include linux/delay.h,
+or it would raise below compile warning:
+
+drivers/mtd/spi-nor/core.c: In function â€˜spi_nor_soft_reset’:
+drivers/mtd/spi-nor/core.c:2779:2: error: implicit declaration of function â€˜usleep_range’ [-Werror=implicit-function-declaration]
+ 2779 |  usleep_range(SPI_NOR_SRST_SLEEP_MIN, SPI_NOR_SRST_SLEEP_MAX);
+      |  ^~~~~~~~~~~~
+
+Fixes: d73ee7534cc5 ("mtd: spi-nor: core: perform a Soft Reset on shutdown")
+Signed-off-by: Zeng Heng <zengheng4@huawei.com>
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://lore.kernel.org/r/20220923031457.56103-1-zengheng4@huawei.com
+Stable-dep-of: e47029b977e7 ("mtd: spi-nor: debugfs: fix out-of-bounds read in spi_nor_params_show()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/spi-nor/core.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/mtd/spi-nor/core.c
++++ b/drivers/mtd/spi-nor/core.c
+@@ -16,6 +16,7 @@
+ #include <linux/math64.h>
+ #include <linux/sizes.h>
+ #include <linux/slab.h>
++#include <linux/delay.h>
+ #include <linux/mtd/mtd.h>
+ #include <linux/of_platform.h>
diff --git a/queue-6.1/mtd-spi-nor-debugfs-fix-out-of-bounds-read-in-spi_nor_params_show.patch b/queue-6.1/mtd-spi-nor-debugfs-fix-out-of-bounds-read-in-spi_nor_params_show.patch
new file mode 100644 (file)
index 0000000..b0af2b1
--- /dev/null
@@ -0,0 +1,65 @@
+From stable+bounces-247172-greg=kroah.com@vger.kernel.org Thu May 14 17:19:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 07:45:40 -0400
+Subject: mtd: spi-nor: debugfs: fix out-of-bounds read in spi_nor_params_show()
+To: stable@vger.kernel.org
+Cc: Tudor Ambarus <tudor.ambarus@linaro.org>, Takahiro Kuwano <takahiro.kuwano@infineon.com>, Michael Walle <mwalle@kernel.org>, Pratyush Yadav <pratyush@kernel.org>, Miquel Raynal <miquel.raynal@bootlin.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514114540.178942-2-sashal@kernel.org>
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit e47029b977e747cb3a9174308fd55762cce70147 ]
+
+Sashiko noticed an out-of-bounds read [1].
+
+In spi_nor_params_show(), the snor_f_names array is passed to
+spi_nor_print_flags() using sizeof(snor_f_names).
+
+Since snor_f_names is an array of pointers, sizeof() returns the total
+number of bytes occupied by the pointers
+       (element_count * sizeof(void *))
+rather than the element count itself. On 64-bit systems, this makes the
+passed length 8x larger than intended.
+
+Inside spi_nor_print_flags(), the 'names_len' argument is used to
+bounds-check the 'names' array access. An out-of-bounds read occurs
+if a flag bit is set that exceeds the array's actual element count
+but is within the inflated byte-size count.
+
+Correct this by using ARRAY_SIZE() to pass the actual number of
+string pointers in the array.
+
+Cc: stable@vger.kernel.org
+Fixes: 0257be79fc4a ("mtd: spi-nor: expose internal parameters via debugfs")
+Closes: https://sashiko.dev/#/patchset/20260417-die-erase-fix-v2-1-73bb7004ebad%40infineon.com [1]
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Reviewed-by: Takahiro Kuwano <takahiro.kuwano@infineon.com>
+Reviewed-by: Michael Walle <mwalle@kernel.org>
+Reviewed-by: Pratyush Yadav <pratyush@kernel.org>
+Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
+[ adjusted include-block context to keep 6.1.y's existing non-alphabetical header order while still adding `#include <linux/array_size.h>` at the top ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/spi-nor/debugfs.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/mtd/spi-nor/debugfs.c
++++ b/drivers/mtd/spi-nor/debugfs.c
+@@ -1,5 +1,6 @@
+ // SPDX-License-Identifier: GPL-2.0
++#include <linux/array_size.h>
+ #include <linux/mtd/spi-nor.h>
+ #include <linux/spi/spi.h>
+ #include <linux/spi/spi-mem.h>
+@@ -91,7 +92,8 @@ static int spi_nor_params_show(struct se
+       seq_printf(s, "address nbytes\t%u\n", nor->addr_nbytes);
+       seq_puts(s, "flags\t\t");
+-      spi_nor_print_flags(s, nor->flags, snor_f_names, sizeof(snor_f_names));
++      spi_nor_print_flags(s, nor->flags, snor_f_names,
++                          ARRAY_SIZE(snor_f_names));
+       seq_puts(s, "\n");
+       seq_puts(s, "\nopcodes\n");
diff --git a/queue-6.1/net-hsr-defer-node-table-free-until-after-rcu-readers.patch b/queue-6.1/net-hsr-defer-node-table-free-until-after-rcu-readers.patch
new file mode 100644 (file)
index 0000000..f5885a8
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-256836-greg=kroah.com@vger.kernel.org Sat May 30 05:25:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 19:55:12 -0400
+Subject: net: hsr: defer node table free until after RCU readers
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529235512.1985956-1-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit aaec7096f9961eb223b5b149abe9495525c205d9 ]
+
+HSR node-list and node-status generic-netlink operations run under
+rcu_read_lock(). They walk hsr->node_db through hsr_get_next_node() and
+hsr_get_node_data(), but RTM_DELLINK teardown removes the same node table
+with plain list_del() and frees each node immediately.
+
+That lets a generic-netlink reader hold a struct hsr_node pointer across
+hsr_dellink(). In a KASAN build, widening the reader window after
+hsr_get_next_node() obtains the node reproduces a slab-use-after-free
+when the reader copies node->macaddress_A; the freeing stack is
+hsr_del_nodes() from hsr_dellink().
+
+Use list_del_rcu() and defer the free through the existing
+hsr_free_node_rcu() callback. This matches the lifetime rule used by the
+HSR prune paths, which already delete nodes with list_del_rcu() and
+call_rcu().
+
+Fixes: b9a1e627405d ("hsr: implement dellink to clean up resources")
+Cc: stable@vger.kernel.org # v5.3+
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Link: https://patch.msgid.link/20260513233838.3064715-2-michael.bommarito@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ replaced `list_del`+`call_rcu(hsr_free_node_rcu)` with `list_del_rcu`+`kfree_rcu(node, rcu_head)` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/hsr/hsr_framereg.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/hsr/hsr_framereg.c
++++ b/net/hsr/hsr_framereg.c
+@@ -121,8 +121,10 @@ void hsr_del_nodes(struct list_head *nod
+       struct hsr_node *node;
+       struct hsr_node *tmp;
+-      list_for_each_entry_safe(node, tmp, node_db, mac_list)
+-              kfree(node);
++      list_for_each_entry_safe(node, tmp, node_db, mac_list) {
++              list_del_rcu(&node->mac_list);
++              kfree_rcu(node, rcu_head);
++      }
+ }
+ void prp_handle_san_frame(bool san, enum hsr_port_type port,
diff --git a/queue-6.1/net-ipv4-stop-checking-crypto_ahash_alignmask.patch b/queue-6.1/net-ipv4-stop-checking-crypto_ahash_alignmask.patch
new file mode 100644 (file)
index 0000000..c875aa6
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-246946-greg=kroah.com@vger.kernel.org Wed May 13 22:34:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 12:52:53 -0400
+Subject: net: ipv4: stop checking crypto_ahash_alignmask
+To: stable@vger.kernel.org
+Cc: Eric Biggers <ebiggers@google.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513165255.3822003-1-sashal@kernel.org>
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit e77f5dd701381cef35b9ea8b6dea6e62c8a7f9f3 ]
+
+Now that the alignmask for ahash and shash algorithms is always 0,
+crypto_ahash_alignmask() always returns 0 and will be removed.  In
+preparation for this, stop checking crypto_ahash_alignmask() in ah4.c.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ec54093e6a8f ("xfrm: ah: account for ESN high bits in async callbacks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ah4.c |   17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+--- a/net/ipv4/ah4.c
++++ b/net/ipv4/ah4.c
+@@ -27,9 +27,7 @@ static void *ah_alloc_tmp(struct crypto_
+ {
+       unsigned int len;
+-      len = size + crypto_ahash_digestsize(ahash) +
+-            (crypto_ahash_alignmask(ahash) &
+-             ~(crypto_tfm_ctx_alignment() - 1));
++      len = size + crypto_ahash_digestsize(ahash);
+       len = ALIGN(len, crypto_tfm_ctx_alignment());
+@@ -46,10 +44,9 @@ static inline u8 *ah_tmp_auth(void *tmp,
+       return tmp + offset;
+ }
+-static inline u8 *ah_tmp_icv(struct crypto_ahash *ahash, void *tmp,
+-                           unsigned int offset)
++static inline u8 *ah_tmp_icv(void *tmp, unsigned int offset)
+ {
+-      return PTR_ALIGN((u8 *)tmp + offset, crypto_ahash_alignmask(ahash) + 1);
++      return tmp + offset;
+ }
+ static inline struct ahash_request *ah_tmp_req(struct crypto_ahash *ahash,
+@@ -129,7 +126,7 @@ static void ah_output_done(struct crypto
+       int ihl = ip_hdrlen(skb);
+       iph = AH_SKB_CB(skb)->tmp;
+-      icv = ah_tmp_icv(ahp->ahash, iph, ihl);
++      icv = ah_tmp_icv(iph, ihl);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       top_iph->tos = iph->tos;
+@@ -182,7 +179,7 @@ static int ah_output(struct xfrm_state *
+       if (!iph)
+               goto out;
+       seqhi = (__be32 *)((char *)iph + ihl);
+-      icv = ah_tmp_icv(ahash, seqhi, seqhi_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
+@@ -279,7 +276,7 @@ static void ah_input_done(struct crypto_
+       work_iph = AH_SKB_CB(skb)->tmp;
+       auth_data = ah_tmp_auth(work_iph, ihl);
+-      icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
++      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+       if (err)
+@@ -374,7 +371,7 @@ static int ah_input(struct xfrm_state *x
+       seqhi = (__be32 *)((char *)work_iph + ihl);
+       auth_data = ah_tmp_auth(seqhi, seqhi_len);
+-      icv = ah_tmp_icv(ahash, auth_data, ahp->icv_trunc_len);
++      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
diff --git a/queue-6.1/net-ipv6-stop-checking-crypto_ahash_alignmask.patch b/queue-6.1/net-ipv6-stop-checking-crypto_ahash_alignmask.patch
new file mode 100644 (file)
index 0000000..e935ba5
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-246947-greg=kroah.com@vger.kernel.org Wed May 13 22:54:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 12:52:54 -0400
+Subject: net: ipv6: stop checking crypto_ahash_alignmask
+To: stable@vger.kernel.org
+Cc: Eric Biggers <ebiggers@google.com>, Herbert Xu <herbert@gondor.apana.org.au>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513165255.3822003-2-sashal@kernel.org>
+
+From: Eric Biggers <ebiggers@google.com>
+
+[ Upstream commit 0a6bfaa0e695facb072f2fedfb55df37c4483b50 ]
+
+Now that the alignmask for ahash and shash algorithms is always 0,
+crypto_ahash_alignmask() always returns 0 and will be removed.  In
+preparation for this, stop checking crypto_ahash_alignmask() in ah6.c.
+
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: ec54093e6a8f ("xfrm: ah: account for ESN high bits in async callbacks")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/ah6.c |   17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+--- a/net/ipv6/ah6.c
++++ b/net/ipv6/ah6.c
+@@ -79,9 +79,7 @@ static void *ah_alloc_tmp(struct crypto_
+ {
+       unsigned int len;
+-      len = size + crypto_ahash_digestsize(ahash) +
+-            (crypto_ahash_alignmask(ahash) &
+-             ~(crypto_tfm_ctx_alignment() - 1));
++      len = size + crypto_ahash_digestsize(ahash);
+       len = ALIGN(len, crypto_tfm_ctx_alignment());
+@@ -103,10 +101,9 @@ static inline u8 *ah_tmp_auth(u8 *tmp, u
+       return tmp + offset;
+ }
+-static inline u8 *ah_tmp_icv(struct crypto_ahash *ahash, void *tmp,
+-                           unsigned int offset)
++static inline u8 *ah_tmp_icv(void *tmp, unsigned int offset)
+ {
+-      return PTR_ALIGN((u8 *)tmp + offset, crypto_ahash_alignmask(ahash) + 1);
++      return tmp + offset;
+ }
+ static inline struct ahash_request *ah_tmp_req(struct crypto_ahash *ahash,
+@@ -327,7 +324,7 @@ static void ah6_output_done(struct crypt
+       iph_base = AH_SKB_CB(skb)->tmp;
+       iph_ext = ah_tmp_ext(iph_base);
+-      icv = ah_tmp_icv(ahp->ahash, iph_ext, extlen);
++      icv = ah_tmp_icv(iph_ext, extlen);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
+@@ -384,7 +381,7 @@ static int ah6_output(struct xfrm_state
+       iph_ext = ah_tmp_ext(iph_base);
+       seqhi = (__be32 *)((char *)iph_ext + extlen);
+-      icv = ah_tmp_icv(ahash, seqhi, seqhi_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
+@@ -480,7 +477,7 @@ static void ah6_input_done(struct crypto
+       work_iph = AH_SKB_CB(skb)->tmp;
+       auth_data = ah_tmp_auth(work_iph, hdr_len);
+-      icv = ah_tmp_icv(ahp->ahash, auth_data, ahp->icv_trunc_len);
++      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+       if (err)
+@@ -588,7 +585,7 @@ static int ah6_input(struct xfrm_state *
+       auth_data = ah_tmp_auth((u8 *)work_iph, hdr_len);
+       seqhi = (__be32 *)(auth_data + ahp->icv_trunc_len);
+-      icv = ah_tmp_icv(ahash, seqhi, seqhi_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       req = ah_tmp_req(ahash, icv);
+       sg = ah_req_sg(ahash, req);
+       seqhisg = sg + nfrags;
diff --git a/queue-6.1/net-stmmac-avoid-shadowing-global-buf_sz.patch b/queue-6.1/net-stmmac-avoid-shadowing-global-buf_sz.patch
new file mode 100644 (file)
index 0000000..f2aa364
--- /dev/null
@@ -0,0 +1,51 @@
+From stable+bounces-245040-greg=kroah.com@vger.kernel.org Sun May 10 21:16:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 11:46:30 -0400
+Subject: net: stmmac: avoid shadowing global buf_sz
+To: stable@vger.kernel.org
+Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>, Furong Xu <0x1207@gmail.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510154632.158995-1-sashal@kernel.org>
+
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit 876cfb20e8892143c0c967b3657074f9131f9b5f ]
+
+stmmac_rx() declares a local variable named "buf_sz" but there is also
+a global variable for a module parameter which is called the same. To
+avoid confusion, rename the local variable.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Furong Xu <0x1207@gmail.com>
+Link: https://patch.msgid.link/E1tpswi-005U6C-Py@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0bb05e6adfa9 ("net: stmmac: Prevent NULL deref when RX memory exhausted")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5235,10 +5235,10 @@ static int stmmac_rx(struct stmmac_priv
+       struct stmmac_xdp_buff ctx;
+       unsigned long flags;
+       int xdp_status = 0;
+-      int buf_sz;
++      int bufsz;
+       dma_dir = page_pool_get_dma_dir(rx_q->page_pool);
+-      buf_sz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
++      bufsz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
+       limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit);
+       if (netif_msg_rx_status(priv)) {
+@@ -5353,7 +5353,7 @@ read_again:
+                       dma_sync_single_for_cpu(priv->device, buf->addr,
+                                               buf1_len, dma_dir);
+-                      xdp_init_buff(&ctx.xdp, buf_sz, &rx_q->xdp_rxq);
++                      xdp_init_buff(&ctx.xdp, bufsz, &rx_q->xdp_rxq);
+                       xdp_prepare_buff(&ctx.xdp, page_address(buf->page),
+                                        buf->page_offset, buf1_len, false);
diff --git a/queue-6.1/net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch b/queue-6.1/net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch
new file mode 100644 (file)
index 0000000..21e64b3
--- /dev/null
@@ -0,0 +1,120 @@
+From stable+bounces-245042-greg=kroah.com@vger.kernel.org Sun May 10 21:16:45 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 11:46:32 -0400
+Subject: net: stmmac: Prevent NULL deref when RX memory exhausted
+To: stable@vger.kernel.org
+Cc: Sam Edwards <cfsworks@gmail.com>, Russell King <linux@armlinux.org.uk>, Sam Edwards <CFSworks@gmail.com>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510154632.158995-3-sashal@kernel.org>
+
+From: Sam Edwards <cfsworks@gmail.com>
+
+[ Upstream commit 0bb05e6adfa99a2ea1fee1125cc0953409f83ed8 ]
+
+The CPU receives frames from the MAC through conventional DMA: the CPU
+allocates buffers for the MAC, then the MAC fills them and returns
+ownership to the CPU. For each hardware RX queue, the CPU and MAC
+coordinate through a shared ring array of DMA descriptors: one
+descriptor per DMA buffer. Each descriptor includes the buffer's
+physical address and a status flag ("OWN") indicating which side owns
+the buffer: OWN=0 for CPU, OWN=1 for MAC. The CPU is only allowed to set
+the flag and the MAC is only allowed to clear it, and both must move
+through the ring in sequence: thus the ring is used for both
+"submissions" and "completions."
+
+In the stmmac driver, stmmac_rx() bookmarks its position in the ring
+with the `cur_rx` index. The main receive loop in that function checks
+for rx_descs[cur_rx].own=0, gives the corresponding buffer to the
+network stack (NULLing the pointer), and increments `cur_rx` modulo the
+ring size. After the loop exits, stmmac_rx_refill(), which bookmarks its
+position with `dirty_rx`, allocates fresh buffers and rearms the
+descriptors (setting OWN=1). If it fails any allocation, it simply stops
+early (leaving OWN=0) and will retry where it left off when next called.
+
+This means descriptors have a three-stage lifecycle (terms my own):
+- `empty` (OWN=1, buffer valid)
+- `full` (OWN=0, buffer valid and populated)
+- `dirty` (OWN=0, buffer NULL)
+
+But because stmmac_rx() only checks OWN, it confuses `full`/`dirty`. In
+the past (see 'Fixes:'), there was a bug where the loop could cycle
+`cur_rx` all the way back to the first descriptor it dirtied, resulting
+in a NULL dereference when mistaken for `full`. The aforementioned
+commit resolved that *specific* failure by capping the loop's iteration
+limit at `dma_rx_size - 1`, but this is only a partial fix: if the
+previous stmmac_rx_refill() didn't complete, then there are leftover
+`dirty` descriptors that the loop might encounter without needing to
+cycle fully around. The current code therefore panics (see 'Closes:')
+when stmmac_rx_refill() is memory-starved long enough for `cur_rx` to
+catch up to `dirty_rx`.
+
+Fix this by explicitly checking, before advancing `cur_rx`, if the next
+entry is dirty; exit the loop if so. This prevents processing of the
+final, used descriptor until stmmac_rx_refill() succeeds, but
+fully prevents the `cur_rx == dirty_rx` ambiguity as the previous bugfix
+intended: so remove the clamp as well. Since stmmac_rx_zc() is a
+copy-paste-and-tweak of stmmac_rx() and the code structure is identical,
+any fix to stmmac_rx() will also need a corresponding fix for
+stmmac_rx_zc(). Therefore, apply the same check there.
+
+In stmmac_rx() (not stmmac_rx_zc()), a related bug remains: after the
+MAC sets OWN=0 on the final descriptor, it will be unable to send any
+further DMA-complete IRQs until it's given more `empty` descriptors.
+Currently, the driver simply *hopes* that the next stmmac_rx_refill()
+succeeds, risking an indefinite stall of the receive process if not. But
+this is not a regression, so it can be addressed in a future change.
+
+Fixes: b6cb4541853c7 ("net: stmmac: avoid rx queue overrun")
+Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221010
+Cc: stable@vger.kernel.org
+Suggested-by: Russell King <linux@armlinux.org.uk>
+Signed-off-by: Sam Edwards <CFSworks@gmail.com>
+Link: https://patch.msgid.link/20260422044503.5349-1-CFSworks@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -5103,9 +5103,12 @@ read_again:
+                       break;
+               /* Prefetch the next RX descriptor */
+-              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+-                                              priv->dma_conf.dma_rx_size);
+-              next_entry = rx_q->cur_rx;
++              next_entry = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
++                                             priv->dma_conf.dma_rx_size);
++              if (unlikely(next_entry == rx_q->dirty_rx))
++                      break;
++
++              rx_q->cur_rx = next_entry;
+               if (priv->extend_desc)
+                       np = (struct dma_desc *)(rx_q->dma_erx + next_entry);
+@@ -5239,7 +5242,6 @@ static int stmmac_rx(struct stmmac_priv
+       dma_dir = page_pool_get_dma_dir(rx_q->page_pool);
+       bufsz = DIV_ROUND_UP(priv->dma_conf.dma_buf_sz, PAGE_SIZE) * PAGE_SIZE;
+-      limit = min(priv->dma_conf.dma_rx_size - 1, (unsigned int)limit);
+       if (netif_msg_rx_status(priv)) {
+               void *rx_head;
+@@ -5295,9 +5297,12 @@ read_again:
+               if (unlikely(status & dma_own))
+                       break;
+-              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+-                                              priv->dma_conf.dma_rx_size);
+-              next_entry = rx_q->cur_rx;
++              next_entry = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
++                                             priv->dma_conf.dma_rx_size);
++              if (unlikely(next_entry == rx_q->dirty_rx))
++                      break;
++
++              rx_q->cur_rx = next_entry;
+               if (priv->extend_desc)
+                       np = (struct dma_desc *)(rx_q->dma_erx + next_entry);
diff --git a/queue-6.1/net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch b/queue-6.1/net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch
new file mode 100644 (file)
index 0000000..7453989
--- /dev/null
@@ -0,0 +1,181 @@
+From stable+bounces-245041-greg=kroah.com@vger.kernel.org Sun May 10 21:16:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 11:46:31 -0400
+Subject: net: stmmac: rename STMMAC_GET_ENTRY() -> STMMAC_NEXT_ENTRY()
+To: stable@vger.kernel.org
+Cc: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510154632.158995-2-sashal@kernel.org>
+
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+
+[ Upstream commit 6b4286e0550814cdc4b897f881ec1fa8b0313227 ]
+
+STMMAC_GET_ENTRY() doesn't describe what this macro is doing - it is
+incrementing the provided index for the circular array of descriptors.
+Replace "GET" with "NEXT" as this better describes the action here.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Link: https://patch.msgid.link/E1w2vba-0000000DbWo-1oL5@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 0bb05e6adfa9 ("net: stmmac: Prevent NULL deref when RX memory exhausted")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/chain_mode.c  |    2 -
+ drivers/net/ethernet/stmicro/stmmac/common.h      |    2 -
+ drivers/net/ethernet/stmicro/stmmac/ring_mode.c   |    2 -
+ drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |   26 +++++++++++-----------
+ 4 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
++++ b/drivers/net/ethernet/stmicro/stmmac/chain_mode.c
+@@ -47,7 +47,7 @@ static int jumbo_frm(struct stmmac_tx_qu
+       while (len != 0) {
+               tx_q->tx_skbuff[entry] = NULL;
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+               desc = tx_q->dma_tx + entry;
+               if (len > bmax) {
+--- a/drivers/net/ethernet/stmicro/stmmac/common.h
++++ b/drivers/net/ethernet/stmicro/stmmac/common.h
+@@ -53,7 +53,7 @@
+ #define DMA_MIN_RX_SIZE               64
+ #define DMA_MAX_RX_SIZE               1024
+ #define DMA_DEFAULT_RX_SIZE   512
+-#define STMMAC_GET_ENTRY(x, size)     ((x + 1) & (size - 1))
++#define STMMAC_NEXT_ENTRY(x, size)    ((x + 1) & (size - 1))
+ #undef FRAME_FILTER_DEBUG
+ /* #define FRAME_FILTER_DEBUG */
+--- a/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
++++ b/drivers/net/ethernet/stmicro/stmmac/ring_mode.c
+@@ -51,7 +51,7 @@ static int jumbo_frm(struct stmmac_tx_qu
+               stmmac_prepare_tx_desc(priv, desc, 1, bmax, csum,
+                               STMMAC_RING_MODE, 0, false, skb->len);
+               tx_q->tx_skbuff[entry] = NULL;
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+               if (priv->extend_desc)
+                       desc = (struct dma_desc *)(tx_q->dma_etx + entry);
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -2503,7 +2503,7 @@ static bool stmmac_xdp_xmit_zc(struct st
+               stmmac_enable_dma_transmission(priv, priv->ioaddr);
+-              tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
++              tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+               entry = tx_q->cur_tx;
+       }
+       flags = u64_stats_update_begin_irqsave(&txq_stats->syncp);
+@@ -2660,7 +2660,7 @@ static int stmmac_tx_clean(struct stmmac
+               stmmac_release_tx_desc(priv, p, priv->mode);
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+       }
+       tx_q->dirty_tx = entry;
+@@ -3976,7 +3976,7 @@ static bool stmmac_vlan_insert(struct st
+               return false;
+       stmmac_set_tx_owner(priv, p);
+-      tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
++      tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+       return true;
+ }
+@@ -4004,7 +4004,7 @@ static void stmmac_tso_allocator(struct
+       while (tmp_len > 0) {
+               dma_addr_t curr_addr;
+-              tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx,
++              tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx,
+                                               priv->dma_conf.dma_tx_size);
+               WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
+@@ -4137,7 +4137,7 @@ static netdev_tx_t stmmac_tso_xmit(struc
+               stmmac_set_mss(priv, mss_desc, mss);
+               tx_q->mss = mss;
+-              tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx,
++              tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx,
+                                               priv->dma_conf.dma_tx_size);
+               WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
+       }
+@@ -4262,7 +4262,7 @@ static netdev_tx_t stmmac_tso_xmit(struc
+        * ndo_start_xmit will fill this descriptor the next time it's
+        * called and stmmac_tx_clean may clean up to this descriptor.
+        */
+-      tx_q->cur_tx = STMMAC_GET_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
++      tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx, priv->dma_conf.dma_tx_size);
+       if (unlikely(stmmac_tx_avail(priv, queue) <= (MAX_SKB_FRAGS + 1))) {
+               netif_dbg(priv, hw, priv->dev, "%s: stop transmitted packets\n",
+@@ -4420,7 +4420,7 @@ static netdev_tx_t stmmac_xmit(struct sk
+               int len = skb_frag_size(frag);
+               bool last_segment = (i == (nfrags - 1));
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+               WARN_ON(tx_q->tx_skbuff[entry]);
+               if (likely(priv->extend_desc))
+@@ -4490,7 +4490,7 @@ static netdev_tx_t stmmac_xmit(struct sk
+        * ndo_start_xmit will fill this descriptor the next time it's
+        * called and stmmac_tx_clean may clean up to this descriptor.
+        */
+-      entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++      entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+       tx_q->cur_tx = entry;
+       if (netif_msg_pktdata(priv)) {
+@@ -4660,7 +4660,7 @@ static inline void stmmac_rx_refill(stru
+               dma_wmb();
+               stmmac_set_rx_owner(priv, p, use_rx_wd);
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_rx_size);
+       }
+       rx_q->dirty_rx = entry;
+       rx_q->rx_tail_addr = rx_q->dma_rx_phy +
+@@ -4787,7 +4787,7 @@ static int stmmac_xdp_xmit_xdpf(struct s
+       stmmac_enable_dma_transmission(priv, priv->ioaddr);
+-      entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_tx_size);
++      entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_tx_size);
+       tx_q->cur_tx = entry;
+       return STMMAC_XDP_TX;
+@@ -5018,7 +5018,7 @@ static bool stmmac_rx_refill_zc(struct s
+               dma_wmb();
+               stmmac_set_rx_owner(priv, rx_desc, use_rx_wd);
+-              entry = STMMAC_GET_ENTRY(entry, priv->dma_conf.dma_rx_size);
++              entry = STMMAC_NEXT_ENTRY(entry, priv->dma_conf.dma_rx_size);
+       }
+       if (rx_desc) {
+@@ -5103,7 +5103,7 @@ read_again:
+                       break;
+               /* Prefetch the next RX descriptor */
+-              rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx,
++              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+                                               priv->dma_conf.dma_rx_size);
+               next_entry = rx_q->cur_rx;
+@@ -5295,7 +5295,7 @@ read_again:
+               if (unlikely(status & dma_own))
+                       break;
+-              rx_q->cur_rx = STMMAC_GET_ENTRY(rx_q->cur_rx,
++              rx_q->cur_rx = STMMAC_NEXT_ENTRY(rx_q->cur_rx,
+                                               priv->dma_conf.dma_rx_size);
+               next_entry = rx_q->cur_rx;
diff --git a/queue-6.1/net-wwan-t7xx-validate-port_count-against-message-length-in-t7xx_port_enum_msg_handler.patch b/queue-6.1/net-wwan-t7xx-validate-port_count-against-message-length-in-t7xx_port_enum_msg_handler.patch
new file mode 100644 (file)
index 0000000..d521566
--- /dev/null
@@ -0,0 +1,141 @@
+From stable+bounces-247262-greg=kroah.com@vger.kernel.org Thu May 14 23:28:20 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 13:58:13 -0400
+Subject: net: wwan: t7xx: validate port_count against message length in t7xx_port_enum_msg_handler
+To: stable@vger.kernel.org
+Cc: Pavitra Jha <jhapavitra98@gmail.com>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514175813.518419-1-sashal@kernel.org>
+
+From: Pavitra Jha <jhapavitra98@gmail.com>
+
+[ Upstream commit 0e7c074cfcd9bd93765505f9eb8b42f03ed2a744 ]
+
+t7xx_port_enum_msg_handler() uses the modem-supplied port_count field as
+a loop bound over port_msg->data[] without checking that the message buffer
+contains sufficient data. A modem sending port_count=65535 in a 12-byte
+buffer triggers a slab-out-of-bounds read of up to 262140 bytes.
+
+Add a sizeof(*port_msg) check before accessing the port message header
+fields to guard against undersized messages.
+
+Add a struct_size() check after extracting port_count and before the loop.
+
+In t7xx_parse_host_rt_data(), guard the rt_feature header read with a
+remaining-buffer check before accessing data_len, validate feat_data_len
+against the actual remaining buffer to prevent OOB reads and signed
+integer overflow on offset.
+
+Pass msg_len from both call sites: skb->len at the DPMAIF path after
+skb_pull(), and the validated feat_data_len at the handshake path.
+
+Fixes: da45d2566a1d ("net: wwan: t7xx: Add control port")
+Cc: stable@vger.kernel.org
+Signed-off-by: Pavitra Jha <jhapavitra98@gmail.com>
+Link: https://patch.msgid.link/20260501110713.145563-1-jhapavitra98@gmail.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wwan/t7xx/t7xx_modem_ops.c     |   17 +++++++++++++++--
+ drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c |   18 ++++++++++++++++--
+ drivers/net/wwan/t7xx/t7xx_port_proxy.h    |    2 +-
+ 3 files changed, 32 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wwan/t7xx/t7xx_modem_ops.c
++++ b/drivers/net/wwan/t7xx/t7xx_modem_ops.c
+@@ -415,8 +415,20 @@ static int t7xx_parse_host_rt_data(struc
+       offset = sizeof(struct feature_query);
+       for (i = 0; i < FEATURE_COUNT && offset < data_length; i++) {
++              size_t remaining = data_length - offset;
++              size_t feat_data_len, feat_total;
++
++              if (remaining < sizeof(*rt_feature))
++                      break;
++
+               rt_feature = data + offset;
+-              offset += sizeof(*rt_feature) + le32_to_cpu(rt_feature->data_len);
++              feat_data_len = le32_to_cpu(rt_feature->data_len);
++
++              if (feat_data_len > remaining - sizeof(*rt_feature))
++                      break;
++
++              feat_total = sizeof(*rt_feature) + feat_data_len;
++              offset += feat_total;
+               ft_spt_cfg = FIELD_GET(FEATURE_MSK, core->feature_set[i]);
+               if (ft_spt_cfg != MTK_FEATURE_MUST_BE_SUPPORTED)
+@@ -427,7 +439,8 @@ static int t7xx_parse_host_rt_data(struc
+                       return -EINVAL;
+               if (i == RT_ID_MD_PORT_ENUM)
+-                      t7xx_port_enum_msg_handler(ctl->md, rt_feature->data);
++                      t7xx_port_enum_msg_handler(ctl->md, rt_feature->data,
++                                                 feat_data_len);
+       }
+       return 0;
+--- a/drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c
++++ b/drivers/net/wwan/t7xx/t7xx_port_ctrl_msg.c
+@@ -117,6 +117,7 @@ static int fsm_ee_message_handler(struct
+  * t7xx_port_enum_msg_handler() - Parse the port enumeration message to create/remove nodes.
+  * @md: Modem context.
+  * @msg: Message.
++ * @msg_len:  Length of @msg in bytes.
+  *
+  * Used to control create/remove device node.
+  *
+@@ -124,12 +125,18 @@ static int fsm_ee_message_handler(struct
+  * * 0                - Success.
+  * * -EFAULT  - Message check failure.
+  */
+-int t7xx_port_enum_msg_handler(struct t7xx_modem *md, void *msg)
++int t7xx_port_enum_msg_handler(struct t7xx_modem *md, void *msg, size_t msg_len)
+ {
+       struct device *dev = &md->t7xx_dev->pdev->dev;
+       unsigned int version, port_count, i;
+       struct port_msg *port_msg = msg;
++      if (msg_len < sizeof(*port_msg)) {
++              dev_err(dev, "Port enum msg too short for header: need %zu, have %zu\n",
++                      sizeof(*port_msg), msg_len);
++              return -EINVAL;
++      }
++
+       version = FIELD_GET(PORT_MSG_VERSION, le32_to_cpu(port_msg->info));
+       if (version != PORT_ENUM_VER ||
+           le32_to_cpu(port_msg->head_pattern) != PORT_ENUM_HEAD_PATTERN ||
+@@ -141,6 +148,13 @@ int t7xx_port_enum_msg_handler(struct t7
+       }
+       port_count = FIELD_GET(PORT_MSG_PRT_CNT, le32_to_cpu(port_msg->info));
++
++      if (msg_len < struct_size(port_msg, data, port_count)) {
++              dev_err(dev, "Port enum msg too short: need %zu, have %zu\n",
++                      struct_size(port_msg, data, port_count), msg_len);
++              return -EINVAL;
++      }
++
+       for (i = 0; i < port_count; i++) {
+               u32 port_info = le32_to_cpu(port_msg->data[i]);
+               unsigned int ch_id;
+@@ -187,7 +201,7 @@ static int control_msg_handler(struct t7
+       case CTL_ID_PORT_ENUM:
+               skb_pull(skb, sizeof(*ctrl_msg_h));
+-              ret = t7xx_port_enum_msg_handler(ctl->md, (struct port_msg *)skb->data);
++              ret = t7xx_port_enum_msg_handler(ctl->md, (struct port_msg *)skb->data, skb->len);
+               if (!ret)
+                       ret = port_ctl_send_msg_to_md(port, CTL_ID_PORT_ENUM, 0);
+               else
+--- a/drivers/net/wwan/t7xx/t7xx_port_proxy.h
++++ b/drivers/net/wwan/t7xx/t7xx_port_proxy.h
+@@ -91,7 +91,7 @@ void t7xx_port_proxy_reset(struct port_p
+ void t7xx_port_proxy_uninit(struct port_proxy *port_prox);
+ int t7xx_port_proxy_init(struct t7xx_modem *md);
+ void t7xx_port_proxy_md_status_notify(struct port_proxy *port_prox, unsigned int state);
+-int t7xx_port_enum_msg_handler(struct t7xx_modem *md, void *msg);
++int t7xx_port_enum_msg_handler(struct t7xx_modem *md, void *msg, size_t msg_len);
+ int t7xx_port_proxy_chl_enable_disable(struct port_proxy *port_prox, unsigned int ch_id,
+                                      bool en_flag);
diff --git a/queue-6.1/netfilter-nft_fib-fix-stale-stack-leak-via-the-oifname-register.patch b/queue-6.1/netfilter-nft_fib-fix-stale-stack-leak-via-the-oifname-register.patch
new file mode 100644 (file)
index 0000000..0fb95a3
--- /dev/null
@@ -0,0 +1,86 @@
+From stable+bounces-263390-greg=kroah.com@vger.kernel.org Mon Jun 15 21:57:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 12:17:29 -0400
+Subject: netfilter: nft_fib: fix stale stack leak via the OIFNAME register
+To: stable@vger.kernel.org
+Cc: Davide Ornaghi <d.ornaghi97@gmail.com>, Florian Westphal <fw@strlen.de>, Pablo Neira Ayuso <pablo@netfilter.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260615161729.2239291-1-sashal@kernel.org>
+
+From: Davide Ornaghi <d.ornaghi97@gmail.com>
+
+[ Upstream commit ab185e0c4fb82dfba6fb86f8271e06f931d9c64c ]
+
+For NFT_FIB_RESULT_OIFNAME the destination register is declared with
+len = IFNAMSIZ (four 32-bit registers), but on the lookup-fail,
+RTN_LOCAL and oif-mismatch paths nft_fib{4,6}_eval() only writes one
+register via "*dest = 0". The remaining three registers are left as
+whatever was on the stack in nft_do_chain()'s struct nft_regs, and a
+downstream expression that loads the register span can leak that
+uninitialised kernel stack to userspace.
+
+The NFTA_FIB_F_PRESENT existence check has the same shape: it is only
+meaningful for NFT_FIB_RESULT_OIF, yet it was accepted for any result type
+while the eval stores a single byte via nft_reg_store8(), leaving the rest
+of the declared span stale.
+
+Fix both:
+
+ - replace the bare "*dest = 0" in the eval with nft_fib_store_result(),
+   which strscpy_pad()s the whole IFNAMSIZ for OIFNAME (and is already
+   used on the other early-return path), and
+
+ - restrict NFTA_FIB_F_PRESENT to NFT_FIB_RESULT_OIF and declare its
+   destination as a single u8, so the marked span matches the one byte
+   the eval writes.
+
+Fixes: f6d0cbcf09c5 ("netfilter: nf_tables: add fib expression")
+Suggested-by: Florian Westphal <fw@strlen.de>
+Cc: stable@vger.kernel.org
+Signed-off-by: Davide Ornaghi <d.ornaghi97@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+[ kept the tree's existing `ip6_route_lookup`/`rt6_info` machinery (missing `fib6_lookup` refactor) and changed only `*dest = 0;` to `nft_fib_store_result(dest, priv, NULL)` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/netfilter/nft_fib_ipv4.c |    2 +-
+ net/ipv6/netfilter/nft_fib_ipv6.c |    2 +-
+ net/netfilter/nft_fib.c           |    6 ++++++
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+
+--- a/net/ipv4/netfilter/nft_fib_ipv4.c
++++ b/net/ipv4/netfilter/nft_fib_ipv4.c
+@@ -122,7 +122,7 @@ void nft_fib4_eval(const struct nft_expr
+               fl4.saddr = get_saddr(iph->daddr);
+       }
+-      *dest = 0;
++      nft_fib_store_result(dest, priv, NULL);
+       if (fib_lookup(nft_net(pkt), &fl4, &res, FIB_LOOKUP_IGNORE_LINKSTATE))
+               return;
+--- a/net/ipv6/netfilter/nft_fib_ipv6.c
++++ b/net/ipv6/netfilter/nft_fib_ipv6.c
+@@ -193,7 +193,7 @@ void nft_fib6_eval(const struct nft_expr
+               }
+       }
+-      *dest = 0;
++      nft_fib_store_result(dest, priv, NULL);
+       rt = (void *)ip6_route_lookup(nft_net(pkt), &fl6, pkt->skb,
+                                     lookup_flags);
+       if (rt->dst.error)
+--- a/net/netfilter/nft_fib.c
++++ b/net/netfilter/nft_fib.c
+@@ -107,6 +107,12 @@ int nft_fib_init(const struct nft_ctx *c
+               return -EINVAL;
+       }
++      if (priv->flags & NFTA_FIB_F_PRESENT) {
++              if (priv->result != NFT_FIB_RESULT_OIF)
++                      return -EINVAL;
++              len = sizeof(u8);
++      }
++
+       err = nft_parse_register_store(ctx, tb[NFTA_FIB_DREG], &priv->dreg,
+                                      NULL, NFT_DATA_VALUE, len);
+       if (err < 0)
diff --git a/queue-6.1/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch b/queue-6.1/octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch
new file mode 100644 (file)
index 0000000..afaa7c2
--- /dev/null
@@ -0,0 +1,57 @@
+From sashal@kernel.org Sat May 30 20:07:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 10:37:38 -0400
+Subject: octeontx2-af: CGX: add bounds check to cgx_speed_mbps index
+To: stable@vger.kernel.org
+Cc: Sam Daly <sam@samdaly.ie>, Sunil Goutham <sgoutham@marvell.com>, Linu Cherian <lcherian@marvell.com>, Geetha sowjanya <gakula@marvell.com>, hariprasad <hkelam@marvell.com>, Subbaraya Sundeep <sbhatta@marvell.com>, Andrew Lunn <andrew+netdev@lunn.ch>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530143738.2474980-2-sashal@kernel.org>
+
+From: Sam Daly <sam@samdaly.ie>
+
+[ Upstream commit c0bf0a4f3f1f5f57aa83e1400ba4f56f0abfd542 ]
+
+cgx_speed_mbps has 13 elements but RESP_LINKSTAT_SPEED can yield values
+0-15. If it returns a value >= 13, this causes an out-of-bounds array
+access. Add a bounds check and default to speed 0 if the index is out of
+range.
+
+Fixes: 61071a871ea6 ("octeontx2-af: Forward CGX link notifications to PFs")
+Cc: Sunil Goutham <sgoutham@marvell.com>
+Cc: Linu Cherian <lcherian@marvell.com>
+Cc: Geetha sowjanya <gakula@marvell.com>
+Cc: hariprasad <hkelam@marvell.com>
+Cc: Subbaraya Sundeep <sbhatta@marvell.com>
+Cc: Andrew Lunn <andrew+netdev@lunn.ch>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Sam Daly <sam@samdaly.ie>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Link: https://patch.msgid.link/2026051352-refined-demise-e88d@gregkh
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/cgx.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+@@ -1228,13 +1228,18 @@ static inline void link_status_user_form
+                                          struct cgx_link_user_info *linfo,
+                                          struct cgx *cgx, u8 lmac_id)
+ {
++      unsigned int speed;
++
+       linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
+       linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
+-      linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)];
+       linfo->an = FIELD_GET(RESP_LINKSTAT_AN, lstat);
+       linfo->fec = FIELD_GET(RESP_LINKSTAT_FEC, lstat);
+       linfo->lmac_type_id = cgx_get_lmac_type(cgx, lmac_id);
++      speed = FIELD_GET(RESP_LINKSTAT_SPEED, lstat);
++      linfo->speed = speed < ARRAY_SIZE(cgx_speed_mbps) ?
++                     cgx_speed_mbps[speed] : 0;
++
+       if (linfo->lmac_type_id >= LMAC_MODE_MAX) {
+               dev_err(&cgx->pdev->dev, "Unknown lmac_type_id %d reported by firmware on cgx port%d:%d",
+                       linfo->lmac_type_id, cgx->cgx_id, lmac_id);
diff --git a/queue-6.1/octeontx2-af-replace-deprecated-strncpy-with-strscpy.patch b/queue-6.1/octeontx2-af-replace-deprecated-strncpy-with-strscpy.patch
new file mode 100644 (file)
index 0000000..b09dca9
--- /dev/null
@@ -0,0 +1,68 @@
+From stable+bounces-256913-greg=kroah.com@vger.kernel.org Sat May 30 20:11:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 10:37:37 -0400
+Subject: octeontx2-af: replace deprecated strncpy with strscpy
+To: stable@vger.kernel.org
+Cc: Justin Stitt <justinstitt@google.com>, Kees Cook <keescook@chromium.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530143738.2474980-1-sashal@kernel.org>
+
+From: Justin Stitt <justinstitt@google.com>
+
+[ Upstream commit 473f8f2d1bfe1103f20140fdc80cad406b4d68c0 ]
+
+`strncpy` is deprecated for use on NUL-terminated destination strings
+[1] and as such we should prefer more robust and less ambiguous string
+interfaces.
+
+We can see that linfo->lmac_type is expected to be NUL-terminated based
+on the `... - 1`'s present in the current code. Presumably making room
+for a NUL-byte at the end of the buffer.
+
+Considering the above, a suitable replacement is `strscpy` [2] due to
+the fact that it guarantees NUL-termination on the destination buffer
+without unnecessarily NUL-padding.
+
+Let's also prefer the more idiomatic strscpy usage of (dest, src,
+sizeof(dest)) rather than (dest, src, SOME_LEN).
+
+Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1]
+Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2]
+Link: https://github.com/KSPP/linux/issues/90
+Signed-off-by: Justin Stitt <justinstitt@google.com>
+Reviewed-by: Kees Cook <keescook@chromium.org>
+Link: https://lore.kernel.org/r/20231010-strncpy-drivers-net-ethernet-marvell-octeontx2-af-cgx-c-v1-1-a443e18f9de8@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: c0bf0a4f3f1f ("octeontx2-af: CGX: add bounds check to cgx_speed_mbps index")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/af/cgx.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c
+@@ -1228,8 +1228,6 @@ static inline void link_status_user_form
+                                          struct cgx_link_user_info *linfo,
+                                          struct cgx *cgx, u8 lmac_id)
+ {
+-      const char *lmac_string;
+-
+       linfo->link_up = FIELD_GET(RESP_LINKSTAT_UP, lstat);
+       linfo->full_duplex = FIELD_GET(RESP_LINKSTAT_FDUPLEX, lstat);
+       linfo->speed = cgx_speed_mbps[FIELD_GET(RESP_LINKSTAT_SPEED, lstat)];
+@@ -1240,12 +1238,12 @@ static inline void link_status_user_form
+       if (linfo->lmac_type_id >= LMAC_MODE_MAX) {
+               dev_err(&cgx->pdev->dev, "Unknown lmac_type_id %d reported by firmware on cgx port%d:%d",
+                       linfo->lmac_type_id, cgx->cgx_id, lmac_id);
+-              strncpy(linfo->lmac_type, "Unknown", LMACTYPE_STR_LEN - 1);
++              strscpy(linfo->lmac_type, "Unknown", sizeof(linfo->lmac_type));
+               return;
+       }
+-      lmac_string = cgx_lmactype_string[linfo->lmac_type_id];
+-      strncpy(linfo->lmac_type, lmac_string, LMACTYPE_STR_LEN - 1);
++      strscpy(linfo->lmac_type, cgx_lmactype_string[linfo->lmac_type_id],
++              sizeof(linfo->lmac_type));
+ }
+ /* Hardware event handlers */
diff --git a/queue-6.1/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch b/queue-6.1/octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch
new file mode 100644 (file)
index 0000000..9752161
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-259294-greg=kroah.com@vger.kernel.org Sun May 31 01:37:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 16:07:07 -0400
+Subject: octeontx2-pf: avoid double free of pool->stack on AQ init failure
+To: stable@vger.kernel.org
+Cc: Dawei Feng <dawei.feng@seu.edu.cn>, Zilin Guan <zilin@seu.edu.cn>, Simon Horman <horms@kernel.org>, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530200707.3281847-1-sashal@kernel.org>
+
+From: Dawei Feng <dawei.feng@seu.edu.cn>
+
+[ Upstream commit 9b244c242bec48b37e82b89787afd6a4c43457e1 ]
+
+otx2_pool_aq_init() frees pool->stack when mailbox sync or retry
+allocation fails, but leaves the pointer unchanged. Later,
+otx2_sq_aura_pool_init() unwinds the partial setup through
+otx2_aura_pool_free(), which frees pool->stack again. The CN20K-specific
+cn20k_pool_aq_init() implementation has the same bug in
+its corresponding error path.
+
+Set pool->stack to NULL immediately after the local free so the shared
+cleanup path does not free the same stack again while cleaning up
+partially initialized pool state.
+
+The bug was first flagged by an experimental analysis tool we are
+developing for kernel memory-management bugs while analyzing
+v6.13-rc1. The tool is still under development and is not yet publicly
+available. Manual inspection confirms that the bug is still present in
+v7.1-rc3.
+
+Runtime validation was not performed because reproducing this path
+requires OcteonTX2/CN20K hardware.
+
+Fixes: caa2da34fd25 ("octeontx2-pf: Initialize and config queues")
+Fixes: d322fbd17203 ("octeontx2-pf: Initialize cn20k specific aura and pool contexts")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zilin Guan <zilin@seu.edu.cn>
+Signed-off-by: Dawei Feng <dawei.feng@seu.edu.cn>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Link: https://patch.msgid.link/20260515151826.1005397-1-dawei.feng@seu.edu.cn
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
++++ b/drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
+@@ -1374,11 +1374,13 @@ int otx2_pool_init(struct otx2_nic *pfvf
+               err = otx2_sync_mbox_msg(&pfvf->mbox);
+               if (err) {
+                       qmem_free(pfvf->dev, pool->stack);
++                      pool->stack = NULL;
+                       return err;
+               }
+               aq = otx2_mbox_alloc_msg_npa_aq_enq(&pfvf->mbox);
+               if (!aq) {
+                       qmem_free(pfvf->dev, pool->stack);
++                      pool->stack = NULL;
+                       return -ENOMEM;
+               }
+       }
diff --git a/queue-6.1/phy-tegra-xusb-disable-trk-clk-when-not-in-use.patch b/queue-6.1/phy-tegra-xusb-disable-trk-clk-when-not-in-use.patch
new file mode 100644 (file)
index 0000000..bf7b001
--- /dev/null
@@ -0,0 +1,51 @@
+From sashal@kernel.org Mon Jun  1 16:21:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon,  1 Jun 2026 06:51:02 -0400
+Subject: phy: tegra: xusb: Disable trk clk when not in use
+To: stable@vger.kernel.org
+Cc: Wayne Chang <waynec@nvidia.com>, Jon Hunter <jonathanh@nvidia.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601105103.376449-1-sashal@kernel.org>
+
+From: Wayne Chang <waynec@nvidia.com>
+
+[ Upstream commit 71d9e899584e11bbd7eaf9934a619c69a15060d8 ]
+
+Pad tracking is a one-time calibration for Tegra186 and Tegra194.
+Clk should be disabled after calibration.
+
+Disable clk after calibration.
+While at it add 100us delay for HW recording the calibration value.
+
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Signed-off-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://lore.kernel.org/r/20230111110450.24617-5-jonathanh@nvidia.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: da110228b54f ("phy: tegra: xusb: Fix per-pad high-speed termination calibration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/tegra/xusb-tegra186.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/phy/tegra/xusb-tegra186.c
++++ b/drivers/phy/tegra/xusb-tegra186.c
+@@ -612,6 +612,10 @@ static void tegra186_utmi_bias_pad_power
+       value &= ~USB2_PD_TRK;
+       padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
++      udelay(100);
++
++      clk_disable_unprepare(priv->usb2_trk_clk);
++
+       mutex_unlock(&padctl->lock);
+ }
+@@ -636,8 +640,6 @@ static void tegra186_utmi_bias_pad_power
+       value |= USB2_PD_TRK;
+       padctl_writel(padctl, value, XUSB_PADCTL_USB2_BIAS_PAD_CTL1);
+-      clk_disable_unprepare(priv->usb2_trk_clk);
+-
+       mutex_unlock(&padctl->lock);
+ }
diff --git a/queue-6.1/phy-tegra-xusb-fix-per-pad-high-speed-termination-calibration.patch b/queue-6.1/phy-tegra-xusb-fix-per-pad-high-speed-termination-calibration.patch
new file mode 100644 (file)
index 0000000..a8b7c15
--- /dev/null
@@ -0,0 +1,144 @@
+From stable+bounces-259519-greg=kroah.com@vger.kernel.org Mon Jun  1 16:28:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon,  1 Jun 2026 06:51:03 -0400
+Subject: phy: tegra: xusb: Fix per-pad high-speed termination calibration
+To: stable@vger.kernel.org
+Cc: Wayne Chang <waynec@nvidia.com>, Wei-Cheng Chen <weichengc@nvidia.com>, Jon Hunter <jonathanh@nvidia.com>, Vinod Koul <vkoul@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601105103.376449-2-sashal@kernel.org>
+
+From: Wayne Chang <waynec@nvidia.com>
+
+[ Upstream commit da110228b54f2e2143d97ea7151e0dc22e539d67 ]
+
+The existing code reads a single hs_term_range_adj value from bit field
+[10:7] of FUSE_SKU_CALIB_0 and applies it to all USB2 pads uniformly.
+However, on SoCs that support per-pad termination, each pad has its own
+hs_term_range_adj field: pad 0 in FUSE_SKU_CALIB_0[10:7], and pads 1-3
+in FUSE_USB_CALIB_EXT_0 at bit offsets [8:5], [12:9], and [16:13]
+respectively.
+
+Fix the calibration by reading per-pad values from the appropriate fuse
+registers. For SoCs that do not support per-pad termination, replicate
+pad 0's value to all pads to maintain existing behavior.
+
+Add a has_per_pad_term flag to the SoC data to indicate whether per-pad
+termination values are available in FUSE_USB_CALIB_EXT_0.
+
+Fixes: 1ef535c6ba8e ("phy: tegra: xusb: Add Tegra194 support")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wayne Chang <waynec@nvidia.com>
+Signed-off-by: Wei-Cheng Chen <weichengc@nvidia.com>
+Reviewed-by: Jon Hunter <jonathanh@nvidia.com>
+Tested-by: Jon Hunter <jonathanh@nvidia.com>
+Link: https://patch.msgid.link/20260504033305.2283145-1-weichengc@nvidia.com
+Signed-off-by: Vinod Koul <vkoul@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/phy/tegra/xusb-tegra186.c |   32 +++++++++++++++++++++++++-------
+ drivers/phy/tegra/xusb.h          |    1 +
+ 2 files changed, 26 insertions(+), 7 deletions(-)
+
+--- a/drivers/phy/tegra/xusb-tegra186.c
++++ b/drivers/phy/tegra/xusb-tegra186.c
+@@ -20,8 +20,8 @@
+ /* FUSE USB_CALIB registers */
+ #define HS_CURR_LEVEL_PADX_SHIFT(x)   ((x) ? (11 + (x - 1) * 6) : 0)
+ #define HS_CURR_LEVEL_PAD_MASK                0x3f
+-#define HS_TERM_RANGE_ADJ_SHIFT               7
+-#define HS_TERM_RANGE_ADJ_MASK                0xf
++#define HS_TERM_RANGE_ADJ_PADX_SHIFT(x)       ((x) ? (5 + (x - 1) * 4) : 7)
++#define HS_TERM_RANGE_ADJ_PAD_MASK    0xf
+ #define HS_SQUELCH_SHIFT              29
+ #define HS_SQUELCH_MASK                       0x7
+@@ -238,7 +238,7 @@
+ struct tegra_xusb_fuse_calibration {
+       u32 *hs_curr_level;
+       u32 hs_squelch;
+-      u32 hs_term_range_adj;
++      u32 *hs_term_range_adj;
+       u32 rpd_ctrl;
+ };
+@@ -868,7 +868,7 @@ static int tegra186_utmi_phy_power_on(st
+       value = padctl_readl(padctl, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
+       value &= ~TERM_RANGE_ADJ(~0);
+-      value |= TERM_RANGE_ADJ(priv->calib.hs_term_range_adj);
++      value |= TERM_RANGE_ADJ(priv->calib.hs_term_range_adj[index]);
+       value &= ~RPD_CTRL(~0);
+       value |= RPD_CTRL(priv->calib.rpd_ctrl);
+       padctl_writel(padctl, value, XUSB_PADCTL_USB2_OTG_PADX_CTL1(index));
+@@ -1403,17 +1403,23 @@ static const char * const tegra186_usb3_
+ static int
+ tegra186_xusb_read_fuse_calibration(struct tegra186_xusb_padctl *padctl)
+ {
++      const struct tegra_xusb_padctl_soc *soc = padctl->base.soc;
+       struct device *dev = padctl->base.dev;
+       unsigned int i, count;
+       u32 value, *level;
++      u32 *hs_term_range_adj;
+       int err;
+-      count = padctl->base.soc->ports.usb2.count;
++      count = soc->ports.usb2.count;
+       level = devm_kcalloc(dev, count, sizeof(u32), GFP_KERNEL);
+       if (!level)
+               return -ENOMEM;
++      hs_term_range_adj = devm_kcalloc(dev, count, sizeof(u32), GFP_KERNEL);
++      if (!hs_term_range_adj)
++              return -ENOMEM;
++
+       err = tegra_fuse_readl(TEGRA_FUSE_SKU_CALIB_0, &value);
+       if (err)
+               return dev_err_probe(dev, err,
+@@ -1429,8 +1435,8 @@ tegra186_xusb_read_fuse_calibration(stru
+       padctl->calib.hs_squelch = (value >> HS_SQUELCH_SHIFT) &
+                                       HS_SQUELCH_MASK;
+-      padctl->calib.hs_term_range_adj = (value >> HS_TERM_RANGE_ADJ_SHIFT) &
+-                                              HS_TERM_RANGE_ADJ_MASK;
++      hs_term_range_adj[0] = (value >> HS_TERM_RANGE_ADJ_PADX_SHIFT(0)) &
++                              HS_TERM_RANGE_ADJ_PAD_MASK;
+       err = tegra_fuse_readl(TEGRA_FUSE_USB_CALIB_EXT_0, &value);
+       if (err) {
+@@ -1442,6 +1448,17 @@ tegra186_xusb_read_fuse_calibration(stru
+       padctl->calib.rpd_ctrl = (value >> RPD_CTRL_SHIFT) & RPD_CTRL_MASK;
++      for (i = 1; i < count; i++) {
++              if (soc->has_per_pad_term)
++                      hs_term_range_adj[i] =
++                              (value >> HS_TERM_RANGE_ADJ_PADX_SHIFT(i)) &
++                              HS_TERM_RANGE_ADJ_PAD_MASK;
++              else
++                      hs_term_range_adj[i] = hs_term_range_adj[0];
++      }
++
++      padctl->calib.hs_term_range_adj = hs_term_range_adj;
++
+       return 0;
+ }
+@@ -1645,6 +1662,7 @@ const struct tegra_xusb_padctl_soc tegra
+       .supply_names = tegra194_xusb_padctl_supply_names,
+       .num_supplies = ARRAY_SIZE(tegra194_xusb_padctl_supply_names),
+       .supports_gen2 = true,
++      .has_per_pad_term = true,
+ };
+ EXPORT_SYMBOL_GPL(tegra194_xusb_padctl_soc);
+ #endif
+--- a/drivers/phy/tegra/xusb.h
++++ b/drivers/phy/tegra/xusb.h
+@@ -433,6 +433,7 @@ struct tegra_xusb_padctl_soc {
+       unsigned int num_supplies;
+       bool supports_gen2;
+       bool need_fake_usb3_port;
++      bool has_per_pad_term;
+ };
+ struct tegra_xusb_padctl {
diff --git a/queue-6.1/platform-x86-intel-vsec-add-private-data-for-per-device-data.patch b/queue-6.1/platform-x86-intel-vsec-add-private-data-for-per-device-data.patch
new file mode 100644 (file)
index 0000000..6a77727
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-257325-greg=kroah.com@vger.kernel.org Sat May 30 22:34:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 13:03:28 -0400
+Subject: platform/x86/intel/vsec: Add private data for per-device data
+To: stable@vger.kernel.org
+Cc: "David E. Box" <david.e.box@linux.intel.com>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260530170331.3037528-1-sashal@kernel.org>
+
+From: "David E. Box" <david.e.box@linux.intel.com>
+
+[ Upstream commit dc957ab6aa05c118c3da0542428a4d6602aa2d2d ]
+
+Introduce a new private structure, struct vsec_priv, to hold a pointer to
+the platform-specific information. Although the driver didn’t previously
+require this per-device data, adding it now lays the groundwork for
+upcoming patches that will manage such data. No functional changes.
+
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Link: https://lore.kernel.org/r/20250703022832.1302928-3-david.e.box@linux.intel.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Stable-dep-of: 348ccc754d89 ("platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -73,6 +73,10 @@ static enum intel_vsec_id intel_vsec_all
+       VSEC_ID_SDSI,
+ };
++struct vsec_priv {
++      struct intel_vsec_platform_info *info;
++};
++
+ static const char *intel_vsec_name(enum intel_vsec_id id)
+ {
+       switch (id) {
+@@ -375,6 +379,7 @@ static bool intel_vsec_walk_vsec(struct
+ static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+       struct intel_vsec_platform_info *info;
++      struct vsec_priv *priv;
+       bool have_devices = false;
+       int ret;
+@@ -387,6 +392,13 @@ static int intel_vsec_pci_probe(struct p
+       if (!info)
+               return -EINVAL;
++      priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
++      if (!priv)
++              return -ENOMEM;
++
++      priv->info = info;
++      pci_set_drvdata(pdev, priv);
++
+       if (intel_vsec_walk_dvsec(pdev, info))
+               have_devices = true;
diff --git a/queue-6.1/platform-x86-intel-vsec-create-wrapper-to-walk-pci-config-space.patch b/queue-6.1/platform-x86-intel-vsec-create-wrapper-to-walk-pci-config-space.patch
new file mode 100644 (file)
index 0000000..781c2f2
--- /dev/null
@@ -0,0 +1,87 @@
+From stable+bounces-257327-greg=kroah.com@vger.kernel.org Sat May 30 22:38:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 13:03:29 -0400
+Subject: platform/x86/intel/vsec: Create wrapper to walk PCI config space
+To: stable@vger.kernel.org
+Cc: "David E. Box" <david.e.box@linux.intel.com>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260530170331.3037528-2-sashal@kernel.org>
+
+From: "David E. Box" <david.e.box@linux.intel.com>
+
+[ Upstream commit b0631f8a5740c55b52d02174cc4c9c84cc7a16a1 ]
+
+Combine three PCI config space walkers â€” intel_vsec_walk_dvsec(),
+intel_vsec_walk_vsec(), and intel_vsec_walk_header() â€” into a new wrapper
+function, intel_vsec_feature_walk().  This refactoring simplifies the probe
+logic and lays the groundwork for future patches that will loop over these
+calls. No functional changes.
+
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Link: https://lore.kernel.org/r/20250703022832.1302928-4-david.e.box@linux.intel.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Stable-dep-of: 348ccc754d89 ("platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c |   38 ++++++++++++++++++++++++++------------
+ 1 file changed, 26 insertions(+), 12 deletions(-)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -376,11 +376,35 @@ static bool intel_vsec_walk_vsec(struct
+       return have_devices;
+ }
++static bool intel_vsec_get_features(struct pci_dev *pdev,
++                                  struct intel_vsec_platform_info *info)
++{
++      bool found = false;
++
++      /*
++       * Both DVSEC and VSEC capabilities can exist on the same device,
++       * so both intel_vsec_walk_dvsec() and intel_vsec_walk_vsec() must be
++       * called independently. Additionally, intel_vsec_walk_header() is
++       * needed for devices that do not have VSEC/DVSEC but provide the
++       * information via device_data.
++       */
++      if (intel_vsec_walk_dvsec(pdev, info))
++              found = true;
++
++      if (intel_vsec_walk_vsec(pdev, info))
++              found = true;
++
++      if (info && (info->quirks & VSEC_QUIRK_NO_DVSEC) &&
++          intel_vsec_walk_header(pdev, info))
++              found = true;
++
++      return found;
++}
++
+ static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+       struct intel_vsec_platform_info *info;
+       struct vsec_priv *priv;
+-      bool have_devices = false;
+       int ret;
+       ret = pcim_enable_device(pdev);
+@@ -399,17 +423,7 @@ static int intel_vsec_pci_probe(struct p
+       priv->info = info;
+       pci_set_drvdata(pdev, priv);
+-      if (intel_vsec_walk_dvsec(pdev, info))
+-              have_devices = true;
+-
+-      if (intel_vsec_walk_vsec(pdev, info))
+-              have_devices = true;
+-
+-      if (info && (info->quirks & VSEC_QUIRK_NO_DVSEC) &&
+-          intel_vsec_walk_header(pdev, info))
+-              have_devices = true;
+-
+-      if (!have_devices)
++      if (!intel_vsec_get_features(pdev, info))
+               return -ENODEV;
+       return 0;
diff --git a/queue-6.1/platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch b/queue-6.1/platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch
new file mode 100644 (file)
index 0000000..7313c7c
--- /dev/null
@@ -0,0 +1,95 @@
+From stable+bounces-257329-greg=kroah.com@vger.kernel.org Sat May 30 22:43:22 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 13:03:31 -0400
+Subject: platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery
+To: stable@vger.kernel.org
+Cc: "Lukas Wunner" <lukas@wunner.de>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260530170331.3037528-4-sashal@kernel.org>
+
+From: Lukas Wunner <lukas@wunner.de>
+
+[ Upstream commit 348ccc754d8939e21ca5956ff45720b81d6e407f ]
+
+After a PCIe Uncorrectable Error has been reported by a device with
+Intel Vendor Specific Extended Capabilities and has been recovered
+through a Secondary Bus Reset, its driver calls intel_vsec_pci_probe()
+to rescan and reinitialize VSECs.
+
+intel_vsec_pci_probe() invokes pcim_enable_device() and thereby adds
+another devm action which calls pcim_disable_device() on driver unbind.
+
+So once the driver unbinds, pcim_disable_device() will be called as many
+times as an Uncorrectable Error occurred, plus one.  This will lead to
+an enable_cnt imbalance on driver unbind.
+
+Additionally, since commit dc957ab6aa05 ("platform/x86/intel/vsec: Add
+private data for per-device data"), a devm_kzalloc() allocation is
+leaked on every Uncorrectable Error.
+
+Avoid by splitting the VSEC rescan out of intel_vsec_pci_probe() into a
+separate helper and calling that on PCIe error recovery.
+
+Fixes: 936874b77dd0 ("platform/x86/intel/vsec: Add PCI error recovery support to Intel PMT")
+Signed-off-by: Lukas Wunner <lukas@wunner.de>
+Cc: stable@vger.kernel.org  # v6.0+
+Link: https://patch.msgid.link/bd594d09fa866dc51dddc9a447c3b23f9b1402cc.1778736835.git.lukas@wunner.de
+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>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -401,6 +401,17 @@ static bool intel_vsec_get_features(stru
+       return found;
+ }
++static int intel_vsec_pci_init(struct pci_dev *pdev)
++{
++      struct vsec_priv *priv = pci_get_drvdata(pdev);
++      const struct intel_vsec_platform_info *info = priv->info;
++
++      if (!intel_vsec_get_features(pdev, info))
++              return -ENODEV;
++
++      return 0;
++}
++
+ static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+       const struct intel_vsec_platform_info *info;
+@@ -423,10 +434,7 @@ static int intel_vsec_pci_probe(struct p
+       priv->info = info;
+       pci_set_drvdata(pdev, priv);
+-      if (!intel_vsec_get_features(pdev, info))
+-              return -ENODEV;
+-
+-      return 0;
++      return intel_vsec_pci_init(pdev);
+ }
+ /* TGL info */
+@@ -489,7 +497,6 @@ static pci_ers_result_t intel_vsec_pci_s
+ {
+       struct intel_vsec_device *intel_vsec_dev;
+       pci_ers_result_t status = PCI_ERS_RESULT_DISCONNECT;
+-      const struct pci_device_id *pci_dev_id;
+       unsigned long index;
+       dev_info(&pdev->dev, "Resetting PCI slot\n");
+@@ -510,10 +517,8 @@ static pci_ers_result_t intel_vsec_pci_s
+               devm_release_action(&pdev->dev, intel_vsec_remove_aux,
+                                   &intel_vsec_dev->auxdev);
+       }
+-      pci_disable_device(pdev);
+       pci_restore_state(pdev);
+-      pci_dev_id = pci_match_id(intel_vsec_pci_ids, pdev);
+-      intel_vsec_pci_probe(pdev, pci_dev_id);
++      intel_vsec_pci_init(pdev);
+ out:
+       return status;
diff --git a/queue-6.1/platform-x86-intel-vsec-make-driver_data-info-const.patch b/queue-6.1/platform-x86-intel-vsec-make-driver_data-info-const.patch
new file mode 100644 (file)
index 0000000..1d5196c
--- /dev/null
@@ -0,0 +1,119 @@
+From stable+bounces-257328-greg=kroah.com@vger.kernel.org Sat May 30 22:38:34 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 13:03:30 -0400
+Subject: platform/x86/intel/vsec: Make driver_data info const
+To: stable@vger.kernel.org
+Cc: "David E. Box" <david.e.box@linux.intel.com>, "Michael J. Ruhl" <michael.j.ruhl@intel.com>, "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260530170331.3037528-3-sashal@kernel.org>
+
+From: "David E. Box" <david.e.box@linux.intel.com>
+
+[ Upstream commit 9577c74c96f88d807d1ba005adbf5952e7127e55 ]
+
+Treat PCI id->driver_data (intel_vsec_platform_info) as read-only by making
+vsec_priv->info a const pointer and updating all function signatures to
+accept const intel_vsec_platform_info *.
+
+This improves const-correctness and clarifies that the platform info data
+from the driver_data table is not meant to be modified at runtime.
+
+No functional changes intended.
+
+Signed-off-by: David E. Box <david.e.box@linux.intel.com>
+Reviewed-by: Michael J. Ruhl <michael.j.ruhl@intel.com>
+Link: https://patch.msgid.link/20260313015202.3660072-3-david.e.box@linux.intel.com
+Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
+Stable-dep-of: 348ccc754d89 ("platform/x86/intel/vsec: Fix enable_cnt imbalance on PCIe error recovery")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/platform/x86/intel/vsec.c |   16 ++++++++--------
+ drivers/platform/x86/intel/vsec.h |    2 +-
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/platform/x86/intel/vsec.c
++++ b/drivers/platform/x86/intel/vsec.c
+@@ -74,7 +74,7 @@ static enum intel_vsec_id intel_vsec_all
+ };
+ struct vsec_priv {
+-      struct intel_vsec_platform_info *info;
++      const struct intel_vsec_platform_info *info;
+ };
+ static const char *intel_vsec_name(enum intel_vsec_id id)
+@@ -203,7 +203,7 @@ int intel_vsec_add_aux(struct pci_dev *p
+ EXPORT_SYMBOL_NS_GPL(intel_vsec_add_aux, INTEL_VSEC);
+ static int intel_vsec_add_dev(struct pci_dev *pdev, struct intel_vsec_header *header,
+-                            struct intel_vsec_platform_info *info)
++                            const struct intel_vsec_platform_info *info)
+ {
+       struct intel_vsec_device *intel_vsec_dev;
+       struct resource *res, *tmp;
+@@ -263,7 +263,7 @@ static int intel_vsec_add_dev(struct pci
+ }
+ static bool intel_vsec_walk_header(struct pci_dev *pdev,
+-                                 struct intel_vsec_platform_info *info)
++                                 const struct intel_vsec_platform_info *info)
+ {
+       struct intel_vsec_header **header = info->capabilities;
+       bool have_devices = false;
+@@ -282,7 +282,7 @@ static bool intel_vsec_walk_header(struc
+ }
+ static bool intel_vsec_walk_dvsec(struct pci_dev *pdev,
+-                                struct intel_vsec_platform_info *info)
++                                const struct intel_vsec_platform_info *info)
+ {
+       bool have_devices = false;
+       int pos = 0;
+@@ -332,7 +332,7 @@ static bool intel_vsec_walk_dvsec(struct
+ }
+ static bool intel_vsec_walk_vsec(struct pci_dev *pdev,
+-                               struct intel_vsec_platform_info *info)
++                               const struct intel_vsec_platform_info *info)
+ {
+       bool have_devices = false;
+       int pos = 0;
+@@ -377,7 +377,7 @@ static bool intel_vsec_walk_vsec(struct
+ }
+ static bool intel_vsec_get_features(struct pci_dev *pdev,
+-                                  struct intel_vsec_platform_info *info)
++                                  const struct intel_vsec_platform_info *info)
+ {
+       bool found = false;
+@@ -403,7 +403,7 @@ static bool intel_vsec_get_features(stru
+ static int intel_vsec_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+-      struct intel_vsec_platform_info *info;
++      const struct intel_vsec_platform_info *info;
+       struct vsec_priv *priv;
+       int ret;
+@@ -412,7 +412,7 @@ static int intel_vsec_pci_probe(struct p
+               return ret;
+       pci_save_state(pdev);
+-      info = (struct intel_vsec_platform_info *)id->driver_data;
++      info = (const struct intel_vsec_platform_info *)id->driver_data;
+       if (!info)
+               return -EINVAL;
+--- a/drivers/platform/x86/intel/vsec.h
++++ b/drivers/platform/x86/intel/vsec.h
+@@ -36,7 +36,7 @@ struct intel_vsec_device {
+       struct pci_dev *pcidev;
+       struct resource *resource;
+       struct ida *ida;
+-      struct intel_vsec_platform_info *info;
++      const struct intel_vsec_platform_info *info;
+       int num_resources;
+       int id; /* xa */
+       void *priv_data;
diff --git a/queue-6.1/pmdomain-core-fix-detach-procedure-for-virtual-devices-in-genpd.patch b/queue-6.1/pmdomain-core-fix-detach-procedure-for-virtual-devices-in-genpd.patch
new file mode 100644 (file)
index 0000000..5b17bca
--- /dev/null
@@ -0,0 +1,72 @@
+From stable+bounces-247837-greg=kroah.com@vger.kernel.org Fri May 15 21:16:11 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 11:35:51 -0400
+Subject: pmdomain: core: Fix detach procedure for virtual devices in genpd
+To: stable@vger.kernel.org
+Cc: Ulf Hansson <ulf.hansson@linaro.org>, Geert Uytterhoeven <geert@linux-m68k.org>, Geert Uytterhoeven <geert+renesas@glider.be>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515153551.3299759-1-sashal@kernel.org>
+
+From: Ulf Hansson <ulf.hansson@linaro.org>
+
+[ Upstream commit 26735dfdd8930d9ef1fa92e590a9bf77726efdf6 ]
+
+If a device is attached to a PM domain through genpd_dev_pm_attach_by_id(),
+genpd calls pm_runtime_enable() for the corresponding virtual device that
+it registers. While this avoids boilerplate code in drivers, there is no
+corresponding call to pm_runtime_disable() in genpd_dev_pm_detach().
+
+This means these virtual devices are typically detached from its genpd,
+while runtime PM remains enabled for them, which is not how things are
+designed to work. In worst cases it may lead to critical errors, like a
+NULL pointer dereference bug in genpd_runtime_suspend(), which was recently
+reported. For another case, we may end up keeping an unnecessary vote for a
+performance state for the device.
+
+To fix these problems, let's add this missing call to pm_runtime_disable()
+in genpd_dev_pm_detach().
+
+Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
+Closes: https://lore.kernel.org/all/CAMuHMdWapT40hV3c+CSBqFOW05aWcV1a6v_NiJYgoYi0i9_PDQ@mail.gmail.com/
+Fixes: 3c095f32a92b ("PM / Domains: Add support for multi PM domains per device to genpd")
+Cc: stable@vger.kernel.org
+Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
+Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/base/power/domain.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/base/power/domain.c
++++ b/drivers/base/power/domain.c
+@@ -2667,6 +2667,7 @@ static struct bus_type genpd_bus_type =
+ static void genpd_dev_pm_detach(struct device *dev, bool power_off)
+ {
+       struct generic_pm_domain *pd;
++      bool is_virt_dev;
+       unsigned int i;
+       int ret = 0;
+@@ -2676,6 +2677,13 @@ static void genpd_dev_pm_detach(struct d
+       dev_dbg(dev, "removing from PM domain %s\n", pd->name);
++      /* Check if the device was created by genpd at attach. */
++      is_virt_dev = dev->bus == &genpd_bus_type;
++
++      /* Disable runtime PM if we enabled it at attach. */
++      if (is_virt_dev)
++              pm_runtime_disable(dev);
++
+       /* Drop the default performance state */
+       if (dev_gpd_data(dev)->default_pstate) {
+               dev_pm_genpd_set_performance_state(dev, 0);
+@@ -2701,7 +2709,7 @@ static void genpd_dev_pm_detach(struct d
+       genpd_queue_power_off_work(pd);
+       /* Unregister the device if it was created by genpd. */
+-      if (dev->bus == &genpd_bus_type)
++      if (is_virt_dev)
+               device_unregister(dev);
+ }
diff --git a/queue-6.1/printk-add-print_hex_dump_devel.patch b/queue-6.1/printk-add-print_hex_dump_devel.patch
new file mode 100644 (file)
index 0000000..1aadcf1
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-245028-greg=kroah.com@vger.kernel.org Sun May 10 19:53:03 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 10:22:49 -0400
+Subject: printk: add print_hex_dump_devel()
+To: stable@vger.kernel.org
+Cc: Thorsten Blum <thorsten.blum@linux.dev>, Herbert Xu <herbert@gondor.apana.org.au>, John Ogness <john.ogness@linutronix.de>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260510142250.4179491-1-sashal@kernel.org>
+
+From: Thorsten Blum <thorsten.blum@linux.dev>
+
+[ Upstream commit d134feeb5df33fbf77f482f52a366a44642dba09 ]
+
+Add print_hex_dump_devel() as the hex dump equivalent of pr_devel(),
+which emits output only when DEBUG is enabled, but keeps call sites
+compiled otherwise.
+
+Suggested-by: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
+Reviewed-by: John Ogness <john.ogness@linutronix.de>
+Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
+Stable-dep-of: 177730a273b1 ("crypto: caam - guard HMAC key hex dumps in hash_digest_key")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/printk.h |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/include/linux/printk.h
++++ b/include/linux/printk.h
+@@ -747,6 +747,19 @@ static inline void print_hex_dump_debug(
+ }
+ #endif
++#if defined(DEBUG)
++#define print_hex_dump_devel(prefix_str, prefix_type, rowsize,                \
++                           groupsize, buf, len, ascii)                \
++      print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, rowsize,    \
++                     groupsize, buf, len, ascii)
++#else
++static inline void print_hex_dump_devel(const char *prefix_str, int prefix_type,
++                                      int rowsize, int groupsize,
++                                      const void *buf, size_t len, bool ascii)
++{
++}
++#endif
++
+ /**
+  * print_hex_dump_bytes - shorthand form of print_hex_dump_debug() with default
+  *                        params
diff --git a/queue-6.1/rdma-move-dma-block-iterator-logic-into-dedicated-files.patch b/queue-6.1/rdma-move-dma-block-iterator-logic-into-dedicated-files.patch
new file mode 100644 (file)
index 0000000..3015b1c
--- /dev/null
@@ -0,0 +1,497 @@
+From stable+bounces-263494-greg=kroah.com@vger.kernel.org Tue Jun 16 05:50:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 20:19:49 -0400
+Subject: RDMA: Move DMA block iterator logic into dedicated files
+To: stable@vger.kernel.org
+Cc: Leon Romanovsky <leonro@nvidia.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260616001950.2587230-2-sashal@kernel.org>
+
+From: Leon Romanovsky <leonro@nvidia.com>
+
+[ Upstream commit 6094ea64c69520ed1e770e7c79c43412de202bfa ]
+
+The DMA iterator logic was mixed into verbs and umem-specific code,
+forcing all users to include rdma/ib_umem.h. Move the block iterator
+logic into iter.c and rdma/iter.h so that rdma/ib_umem.h and
+rdma/ib_verbs.h can be separated in a follow-up patch.
+
+Link: https://patch.msgid.link/20260213-refactor-umem-v1-1-f3be85847922@nvidia.com
+Signed-off-by: Leon Romanovsky <leonro@nvidia.com>
+Stable-dep-of: 15fe76e23615 ("RDMA/umem: Fix truncation for block sizes >= 4G")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/core/Makefile             |    2 
+ drivers/infiniband/core/iter.c               |   43 +++++++++++++
+ drivers/infiniband/core/verbs.c              |   38 -----------
+ drivers/infiniband/hw/bnxt_re/qplib_res.c    |    2 
+ drivers/infiniband/hw/cxgb4/mem.c            |    2 
+ drivers/infiniband/hw/efa/efa_verbs.c        |    2 
+ drivers/infiniband/hw/erdma/erdma_verbs.c    |    2 
+ drivers/infiniband/hw/hns/hns_roce_alloc.c   |    2 
+ drivers/infiniband/hw/irdma/main.h           |    2 
+ drivers/infiniband/hw/mlx4/mr.c              |    1 
+ drivers/infiniband/hw/mlx5/mem.c             |    1 
+ drivers/infiniband/hw/mlx5/umr.c             |    1 
+ drivers/infiniband/hw/mthca/mthca_provider.c |    2 
+ drivers/infiniband/hw/ocrdma/ocrdma_verbs.c  |    2 
+ drivers/infiniband/hw/qedr/verbs.c           |    2 
+ drivers/infiniband/hw/vmw_pvrdma/pvrdma.h    |    2 
+ include/rdma/ib_umem.h                       |   32 ---------
+ include/rdma/ib_verbs.h                      |   48 --------------
+ include/rdma/iter.h                          |   88 +++++++++++++++++++++++++++
+ 19 files changed, 145 insertions(+), 129 deletions(-)
+ create mode 100644 drivers/infiniband/core/iter.c
+ create mode 100644 include/rdma/iter.h
+
+--- a/drivers/infiniband/core/Makefile
++++ b/drivers/infiniband/core/Makefile
+@@ -12,7 +12,7 @@ ib_core-y :=                 packer.o ud_header.o verb
+                               roce_gid_mgmt.o mr_pool.o addr.o sa_query.o \
+                               multicast.o mad.o smi.o agent.o mad_rmpp.o \
+                               nldev.o restrack.o counters.o ib_core_uverbs.o \
+-                              trace.o lag.o
++                              trace.o lag.o iter.o
+ ib_core-$(CONFIG_SECURITY_INFINIBAND) += security.o
+ ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o
+--- /dev/null
++++ b/drivers/infiniband/core/iter.c
+@@ -0,0 +1,43 @@
++// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
++/* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. */
++
++#include <linux/export.h>
++#include <rdma/iter.h>
++
++void __rdma_block_iter_start(struct ib_block_iter *biter,
++                           struct scatterlist *sglist, unsigned int nents,
++                           unsigned long pgsz)
++{
++      memset(biter, 0, sizeof(struct ib_block_iter));
++      biter->__sg = sglist;
++      biter->__sg_nents = nents;
++
++      /* Driver provides best block size to use */
++      biter->__pg_bit = __fls(pgsz);
++}
++EXPORT_SYMBOL(__rdma_block_iter_start);
++
++bool __rdma_block_iter_next(struct ib_block_iter *biter)
++{
++      unsigned int block_offset;
++      unsigned int delta;
++
++      if (!biter->__sg_nents || !biter->__sg)
++              return false;
++
++      biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
++      block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
++      delta = BIT_ULL(biter->__pg_bit) - block_offset;
++
++      while (biter->__sg_nents && biter->__sg &&
++             sg_dma_len(biter->__sg) - biter->__sg_advance <= delta) {
++              delta -= sg_dma_len(biter->__sg) - biter->__sg_advance;
++              biter->__sg_advance = 0;
++              biter->__sg = sg_next(biter->__sg);
++              biter->__sg_nents--;
++      }
++      biter->__sg_advance += delta;
++
++      return true;
++}
++EXPORT_SYMBOL(__rdma_block_iter_next);
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -2943,44 +2943,6 @@ int rdma_init_netdev(struct ib_device *d
+ }
+ EXPORT_SYMBOL(rdma_init_netdev);
+-void __rdma_block_iter_start(struct ib_block_iter *biter,
+-                           struct scatterlist *sglist, unsigned int nents,
+-                           unsigned long pgsz)
+-{
+-      memset(biter, 0, sizeof(struct ib_block_iter));
+-      biter->__sg = sglist;
+-      biter->__sg_nents = nents;
+-
+-      /* Driver provides best block size to use */
+-      biter->__pg_bit = __fls(pgsz);
+-}
+-EXPORT_SYMBOL(__rdma_block_iter_start);
+-
+-bool __rdma_block_iter_next(struct ib_block_iter *biter)
+-{
+-      unsigned int block_offset;
+-      unsigned int delta;
+-
+-      if (!biter->__sg_nents || !biter->__sg)
+-              return false;
+-
+-      biter->__dma_addr = sg_dma_address(biter->__sg) + biter->__sg_advance;
+-      block_offset = biter->__dma_addr & (BIT_ULL(biter->__pg_bit) - 1);
+-      delta = BIT_ULL(biter->__pg_bit) - block_offset;
+-
+-      while (biter->__sg_nents && biter->__sg &&
+-             sg_dma_len(biter->__sg) - biter->__sg_advance <= delta) {
+-              delta -= sg_dma_len(biter->__sg) - biter->__sg_advance;
+-              biter->__sg_advance = 0;
+-              biter->__sg = sg_next(biter->__sg);
+-              biter->__sg_nents--;
+-      }
+-      biter->__sg_advance += delta;
+-
+-      return true;
+-}
+-EXPORT_SYMBOL(__rdma_block_iter_next);
+-
+ /**
+  * rdma_alloc_hw_stats_struct - Helper function to allocate dynamic struct
+  *   for the drivers.
+--- a/drivers/infiniband/hw/bnxt_re/qplib_res.c
++++ b/drivers/infiniband/hw/bnxt_re/qplib_res.c
+@@ -46,7 +46,7 @@
+ #include <linux/if_vlan.h>
+ #include <linux/vmalloc.h>
+ #include <rdma/ib_verbs.h>
+-#include <rdma/ib_umem.h>
++#include <rdma/iter.h>
+ #include "roce_hsi.h"
+ #include "qplib_res.h"
+--- a/drivers/infiniband/hw/cxgb4/mem.c
++++ b/drivers/infiniband/hw/cxgb4/mem.c
+@@ -32,9 +32,9 @@
+ #include <linux/module.h>
+ #include <linux/moduleparam.h>
+-#include <rdma/ib_umem.h>
+ #include <linux/atomic.h>
+ #include <rdma/ib_user_verbs.h>
++#include <rdma/iter.h>
+ #include "iw_cxgb4.h"
+--- a/drivers/infiniband/hw/efa/efa_verbs.c
++++ b/drivers/infiniband/hw/efa/efa_verbs.c
+@@ -9,9 +9,9 @@
+ #include <linux/log2.h>
+ #include <rdma/ib_addr.h>
+-#include <rdma/ib_umem.h>
+ #include <rdma/ib_user_verbs.h>
+ #include <rdma/ib_verbs.h>
++#include <rdma/iter.h>
+ #include <rdma/uverbs_ioctl.h>
+ #include "efa.h"
+--- a/drivers/infiniband/hw/erdma/erdma_verbs.c
++++ b/drivers/infiniband/hw/erdma/erdma_verbs.c
+@@ -12,7 +12,7 @@
+ #include <linux/vmalloc.h>
+ #include <net/addrconf.h>
+ #include <rdma/erdma-abi.h>
+-#include <rdma/ib_umem.h>
++#include <rdma/iter.h>
+ #include <rdma/uverbs_ioctl.h>
+ #include "erdma.h"
+--- a/drivers/infiniband/hw/hns/hns_roce_alloc.c
++++ b/drivers/infiniband/hw/hns/hns_roce_alloc.c
+@@ -32,7 +32,7 @@
+  */
+ #include <linux/vmalloc.h>
+-#include <rdma/ib_umem.h>
++#include <rdma/iter.h>
+ #include "hns_roce_device.h"
+ void hns_roce_buf_free(struct hns_roce_dev *hr_dev, struct hns_roce_buf *buf)
+--- a/drivers/infiniband/hw/irdma/main.h
++++ b/drivers/infiniband/hw/irdma/main.h
+@@ -37,8 +37,8 @@
+ #include <rdma/rdma_cm.h>
+ #include <rdma/iw_cm.h>
+ #include <rdma/ib_user_verbs.h>
+-#include <rdma/ib_umem.h>
+ #include <rdma/ib_cache.h>
++#include <rdma/iter.h>
+ #include <rdma/uverbs_ioctl.h>
+ #include "osdep.h"
+ #include "defs.h"
+--- a/drivers/infiniband/hw/mlx4/mr.c
++++ b/drivers/infiniband/hw/mlx4/mr.c
+@@ -33,6 +33,7 @@
+ #include <linux/slab.h>
+ #include <rdma/ib_user_verbs.h>
++#include <rdma/iter.h>
+ #include "mlx4_ib.h"
+--- a/drivers/infiniband/hw/mlx5/mem.c
++++ b/drivers/infiniband/hw/mlx5/mem.c
+@@ -32,6 +32,7 @@
+ #include <linux/io.h>
+ #include <rdma/ib_umem_odp.h>
++#include <rdma/iter.h>
+ #include "mlx5_ib.h"
+ #include <linux/jiffies.h>
+--- a/drivers/infiniband/hw/mlx5/umr.c
++++ b/drivers/infiniband/hw/mlx5/umr.c
+@@ -2,6 +2,7 @@
+ /* Copyright (c) 2022, NVIDIA CORPORATION & AFFILIATES. */
+ #include <rdma/ib_umem_odp.h>
++#include <rdma/iter.h>
+ #include "mlx5_ib.h"
+ #include "umr.h"
+ #include "wr.h"
+--- a/drivers/infiniband/hw/mthca/mthca_provider.c
++++ b/drivers/infiniband/hw/mthca/mthca_provider.c
+@@ -35,8 +35,8 @@
+  */
+ #include <rdma/ib_smi.h>
+-#include <rdma/ib_umem.h>
+ #include <rdma/ib_user_verbs.h>
++#include <rdma/iter.h>
+ #include <rdma/uverbs_ioctl.h>
+ #include <linux/sched.h>
+--- a/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
++++ b/drivers/infiniband/hw/ocrdma/ocrdma_verbs.c
+@@ -45,9 +45,9 @@
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_user_verbs.h>
+ #include <rdma/iw_cm.h>
+-#include <rdma/ib_umem.h>
+ #include <rdma/ib_addr.h>
+ #include <rdma/ib_cache.h>
++#include <rdma/iter.h>
+ #include <rdma/uverbs_ioctl.h>
+ #include "ocrdma.h"
+--- a/drivers/infiniband/hw/qedr/verbs.c
++++ b/drivers/infiniband/hw/qedr/verbs.c
+@@ -39,9 +39,9 @@
+ #include <rdma/ib_verbs.h>
+ #include <rdma/ib_user_verbs.h>
+ #include <rdma/iw_cm.h>
+-#include <rdma/ib_umem.h>
+ #include <rdma/ib_addr.h>
+ #include <rdma/ib_cache.h>
++#include <rdma/iter.h>
+ #include <rdma/uverbs_ioctl.h>
+ #include <linux/qed/common_hsi.h>
+--- a/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
++++ b/drivers/infiniband/hw/vmw_pvrdma/pvrdma.h
+@@ -53,8 +53,8 @@
+ #include <linux/pci.h>
+ #include <linux/semaphore.h>
+ #include <linux/workqueue.h>
+-#include <rdma/ib_umem.h>
+ #include <rdma/ib_verbs.h>
++#include <rdma/iter.h>
+ #include <rdma/vmw_pvrdma-abi.h>
+ #include "pvrdma_ring.h"
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -71,38 +71,6 @@ static inline size_t ib_umem_num_pages(s
+ {
+       return ib_umem_num_dma_blocks(umem, PAGE_SIZE);
+ }
+-
+-static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter,
+-                                              struct ib_umem *umem,
+-                                              unsigned long pgsz)
+-{
+-      __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl,
+-                              umem->sgt_append.sgt.nents, pgsz);
+-      biter->__sg_advance = ib_umem_offset(umem) & ~(pgsz - 1);
+-      biter->__sg_numblocks = ib_umem_num_dma_blocks(umem, pgsz);
+-}
+-
+-static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter)
+-{
+-      return __rdma_block_iter_next(biter) && biter->__sg_numblocks--;
+-}
+-
+-/**
+- * rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem
+- * @umem: umem to iterate over
+- * @biter: block iterator variable
+- * @pgsz: Page size to split the list into
+- *
+- * pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The
+- * returned DMA blocks will be aligned to pgsz and span the range:
+- * ALIGN_DOWN(umem->address, pgsz) to ALIGN(umem->address + umem->length, pgsz)
+- *
+- * Performs exactly ib_umem_num_dma_blocks() iterations.
+- */
+-#define rdma_umem_for_each_dma_block(umem, biter, pgsz)                        \
+-      for (__rdma_umem_block_iter_start(biter, umem, pgsz);                  \
+-           __rdma_umem_block_iter_next(biter);)
+-
+ #ifdef CONFIG_INFINIBAND_USER_MEM
+ struct ib_umem *ib_umem_get(struct ib_device *device, unsigned long addr,
+--- a/include/rdma/ib_verbs.h
++++ b/include/rdma/ib_verbs.h
+@@ -2826,22 +2826,6 @@ struct ib_client {
+       u8 no_kverbs_req:1;
+ };
+-/*
+- * IB block DMA iterator
+- *
+- * Iterates the DMA-mapped SGL in contiguous memory blocks aligned
+- * to a HW supported page size.
+- */
+-struct ib_block_iter {
+-      /* internal states */
+-      struct scatterlist *__sg;       /* sg holding the current aligned block */
+-      dma_addr_t __dma_addr;          /* unaligned DMA address of this block */
+-      size_t __sg_numblocks;          /* ib_umem_num_dma_blocks() */
+-      unsigned int __sg_nents;        /* number of SG entries */
+-      unsigned int __sg_advance;      /* number of bytes to advance in sg in next step */
+-      unsigned int __pg_bit;          /* alignment of current block */
+-};
+-
+ struct ib_device *_ib_alloc_device(size_t size);
+ #define ib_alloc_device(drv_struct, member)                                    \
+       container_of(_ib_alloc_device(sizeof(struct drv_struct) +              \
+@@ -2863,38 +2847,6 @@ void ib_unregister_device_queued(struct
+ int ib_register_client   (struct ib_client *client);
+ void ib_unregister_client(struct ib_client *client);
+-void __rdma_block_iter_start(struct ib_block_iter *biter,
+-                           struct scatterlist *sglist,
+-                           unsigned int nents,
+-                           unsigned long pgsz);
+-bool __rdma_block_iter_next(struct ib_block_iter *biter);
+-
+-/**
+- * rdma_block_iter_dma_address - get the aligned dma address of the current
+- * block held by the block iterator.
+- * @biter: block iterator holding the memory block
+- */
+-static inline dma_addr_t
+-rdma_block_iter_dma_address(struct ib_block_iter *biter)
+-{
+-      return biter->__dma_addr & ~(BIT_ULL(biter->__pg_bit) - 1);
+-}
+-
+-/**
+- * rdma_for_each_block - iterate over contiguous memory blocks of the sg list
+- * @sglist: sglist to iterate over
+- * @biter: block iterator holding the memory block
+- * @nents: maximum number of sg entries to iterate over
+- * @pgsz: best HW supported page size to use
+- *
+- * Callers may use rdma_block_iter_dma_address() to get each
+- * blocks aligned DMA address.
+- */
+-#define rdma_for_each_block(sglist, biter, nents, pgsz)               \
+-      for (__rdma_block_iter_start(biter, sglist, nents,      \
+-                                   pgsz);                     \
+-           __rdma_block_iter_next(biter);)
+-
+ /**
+  * ib_get_client_data - Get IB client context
+  * @device:Device to get context for
+--- /dev/null
++++ b/include/rdma/iter.h
+@@ -0,0 +1,88 @@
++/* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
++/* Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. */
++
++#ifndef _RDMA_ITER_H_
++#define _RDMA_ITER_H_
++
++#include <linux/scatterlist.h>
++#include <rdma/ib_umem.h>
++
++/**
++ * IB block DMA iterator
++ *
++ * Iterates the DMA-mapped SGL in contiguous memory blocks aligned
++ * to a HW supported page size.
++ */
++struct ib_block_iter {
++      /* internal states */
++      struct scatterlist *__sg;       /* sg holding the current aligned block */
++      dma_addr_t __dma_addr;          /* unaligned DMA address of this block */
++      size_t __sg_numblocks;          /* ib_umem_num_dma_blocks() */
++      unsigned int __sg_nents;        /* number of SG entries */
++      unsigned int __sg_advance;      /* number of bytes to advance in sg in next step */
++      unsigned int __pg_bit;          /* alignment of current block */
++};
++
++void __rdma_block_iter_start(struct ib_block_iter *biter,
++                           struct scatterlist *sglist,
++                           unsigned int nents,
++                           unsigned long pgsz);
++bool __rdma_block_iter_next(struct ib_block_iter *biter);
++
++/**
++ * rdma_block_iter_dma_address - get the aligned dma address of the current
++ * block held by the block iterator.
++ * @biter: block iterator holding the memory block
++ */
++static inline dma_addr_t
++rdma_block_iter_dma_address(struct ib_block_iter *biter)
++{
++      return biter->__dma_addr & ~(BIT_ULL(biter->__pg_bit) - 1);
++}
++
++/**
++ * rdma_for_each_block - iterate over contiguous memory blocks of the sg list
++ * @sglist: sglist to iterate over
++ * @biter: block iterator holding the memory block
++ * @nents: maximum number of sg entries to iterate over
++ * @pgsz: best HW supported page size to use
++ *
++ * Callers may use rdma_block_iter_dma_address() to get each
++ * blocks aligned DMA address.
++ */
++#define rdma_for_each_block(sglist, biter, nents, pgsz)               \
++      for (__rdma_block_iter_start(biter, sglist, nents,      \
++                                   pgsz);                     \
++           __rdma_block_iter_next(biter);)
++
++static inline void __rdma_umem_block_iter_start(struct ib_block_iter *biter,
++                                              struct ib_umem *umem,
++                                              unsigned long pgsz)
++{
++      __rdma_block_iter_start(biter, umem->sgt_append.sgt.sgl,
++                              umem->sgt_append.sgt.nents, pgsz);
++      biter->__sg_advance = ib_umem_offset(umem) & ~(pgsz - 1);
++      biter->__sg_numblocks = ib_umem_num_dma_blocks(umem, pgsz);
++}
++
++static inline bool __rdma_umem_block_iter_next(struct ib_block_iter *biter)
++{
++      return __rdma_block_iter_next(biter) && biter->__sg_numblocks--;
++}
++
++/**
++ * rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem
++ * @umem: umem to iterate over
++ * @pgsz: Page size to split the list into
++ *
++ * pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The
++ * returned DMA blocks will be aligned to pgsz and span the range:
++ * ALIGN_DOWN(umem->address, pgsz) to ALIGN(umem->address + umem->length, pgsz)
++ *
++ * Performs exactly ib_umem_num_dma_blocks() iterations.
++ */
++#define rdma_umem_for_each_dma_block(umem, biter, pgsz)                        \
++      for (__rdma_umem_block_iter_start(biter, umem, pgsz);                  \
++           __rdma_umem_block_iter_next(biter);)
++
++#endif /* _RDMA_ITER_H_ */
diff --git a/queue-6.1/rdma-umem-fix-kernel-doc-warnings.patch b/queue-6.1/rdma-umem-fix-kernel-doc-warnings.patch
new file mode 100644 (file)
index 0000000..53dee46
--- /dev/null
@@ -0,0 +1,60 @@
+From stable+bounces-263493-greg=kroah.com@vger.kernel.org Tue Jun 16 05:50:00 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 20:19:48 -0400
+Subject: RDMA/umem: fix kernel-doc warnings
+To: stable@vger.kernel.org
+Cc: Randy Dunlap <rdunlap@infradead.org>, Leon Romanovsky <leon@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260616001950.2587230-1-sashal@kernel.org>
+
+From: Randy Dunlap <rdunlap@infradead.org>
+
+[ Upstream commit ff46d1392750444fab5ae5a0194764ffdc4ac0d2 ]
+
+Add or correct kernel-doc comments to eliminate warnings:
+
+Warning: include/rdma/ib_umem.h:104 function parameter 'biter' not
+ described in 'rdma_umem_for_each_dma_block'
+Warning: include/rdma/ib_umem.h:140 function parameter 'pgsz_bitmap' not
+ described in 'ib_umem_find_best_pgoff'
+Warning: include/rdma/ib_umem.h:141 No description found for return
+ value of 'ib_umem_find_best_pgoff'
+
+Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
+Link: https://patch.msgid.link/20260224003120.3173892-1-rdunlap@infradead.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Stable-dep-of: 15fe76e23615 ("RDMA/umem: Fix truncation for block sizes >= 4G")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/rdma/ib_umem.h |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/include/rdma/ib_umem.h
++++ b/include/rdma/ib_umem.h
+@@ -90,6 +90,7 @@ static inline bool __rdma_umem_block_ite
+ /**
+  * rdma_umem_for_each_dma_block - iterate over contiguous DMA blocks of the umem
+  * @umem: umem to iterate over
++ * @biter: block iterator variable
+  * @pgsz: Page size to split the list into
+  *
+  * pgsz must be <= PAGE_SIZE or computed by ib_umem_find_best_pgsz(). The
+@@ -117,7 +118,7 @@ unsigned long ib_umem_find_best_pgsz(str
+  * ib_umem_find_best_pgoff - Find best HW page size
+  *
+  * @umem: umem struct
+- * @pgsz_bitmap bitmap of HW supported page sizes
++ * @pgsz_bitmap: bitmap of HW supported page sizes
+  * @pgoff_bitmask: Mask of bits that can be represented with an offset
+  *
+  * This is very similar to ib_umem_find_best_pgsz() except instead of accepting
+@@ -130,6 +131,9 @@ unsigned long ib_umem_find_best_pgsz(str
+  *
+  * If the pgoff_bitmask requires either alignment in the low bit or an
+  * unavailable page size for the high bits, this function returns 0.
++ *
++ * Returns: best HW page size for the parameters or 0 if none available
++ *   for the given parameters.
+  */
+ static inline unsigned long ib_umem_find_best_pgoff(struct ib_umem *umem,
+                                                   unsigned long pgsz_bitmap,
diff --git a/queue-6.1/rdma-umem-fix-truncation-for-block-sizes-4g.patch b/queue-6.1/rdma-umem-fix-truncation-for-block-sizes-4g.patch
new file mode 100644 (file)
index 0000000..e462bc4
--- /dev/null
@@ -0,0 +1,44 @@
+From stable+bounces-263495-greg=kroah.com@vger.kernel.org Tue Jun 16 05:50:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 15 Jun 2026 20:19:50 -0400
+Subject: RDMA/umem: Fix truncation for block sizes >= 4G
+To: stable@vger.kernel.org
+Cc: Jason Gunthorpe <jgg@nvidia.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260616001950.2587230-3-sashal@kernel.org>
+
+From: Jason Gunthorpe <jgg@nvidia.com>
+
+[ Upstream commit 15fe76e23615f502d051ef0768f86babaf08746c ]
+
+When the iommu is used the linearization of the mapping can give a single
+block that is very large split across multiple SG entries.
+
+When __rdma_block_iter_next() reassembles the split SG entries it is
+overflowing the 32 bit stack values and computed the wrong DMA addresses
+for blocks after the truncation.
+
+Use the right types to hold DMA addresses.
+
+Link: https://patch.msgid.link/r/1-v1-88303e9e509f+f7-ib_umem_types_jgg@nvidia.com
+Cc: stable@vger.kernel.org
+Fixes: a808273a495c ("RDMA/verbs: Add a DMA iterator to return aligned contiguous memory blocks")
+Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/core/iter.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/core/iter.c
++++ b/drivers/infiniband/core/iter.c
+@@ -19,8 +19,8 @@ EXPORT_SYMBOL(__rdma_block_iter_start);
+ bool __rdma_block_iter_next(struct ib_block_iter *biter)
+ {
+-      unsigned int block_offset;
+-      unsigned int delta;
++      dma_addr_t block_offset;
++      dma_addr_t delta;
+       if (!biter->__sg_nents || !biter->__sg)
+               return false;
diff --git a/queue-6.1/scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch b/queue-6.1/scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch
new file mode 100644 (file)
index 0000000..f01095c
--- /dev/null
@@ -0,0 +1,124 @@
+From stable+bounces-260877-greg=kroah.com@vger.kernel.org Sat Jun  6 18:03:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  6 Jun 2026 08:32:06 -0400
+Subject: scsi: target: iscsi: Fix CRC overread and double-free in iscsit_handle_text_cmd()
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, John Garry <john.g.garry@oracle.com>, "Martin K. Petersen" <martin.petersen@oracle.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606123206.2861187-1-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit 778c2ab142c625a8a8afa570e0f9b7873f445d99 ]
+
+Two latent bugs in the Text-phase handler, both present since the
+original LIO integration in commit e48354ce078c ("iscsi-target: Add
+iSCSI fabric support for target v4.1"):
+
+1) DataDigest CRC buffer overread (4 bytes past text_in).
+
+   text_in is kzalloc()'d at ALIGN(payload_length, 4).  rx_size is then
+   incremented by ISCSI_CRC_LEN to make room for the received DataDigest
+   in the iovec, but the same (now-bumped) rx_size is passed as the
+   buffer length to iscsit_crc_buf():
+
+       if (conn->conn_ops->DataDigest) {
+               ...
+               rx_size += ISCSI_CRC_LEN;
+       }
+       ...
+       if (conn->conn_ops->DataDigest) {
+               data_crc = iscsit_crc_buf(text_in, rx_size, 0, NULL);
+
+   iscsit_crc_buf() walks rx_size bytes of text_in with crc32c(), so
+   when DataDigest is negotiated it reads 4 bytes past the end of the
+   text_in allocation.  KASAN reproduces this directly on the unpatched
+   mainline tree as slab-out-of-bounds in crc32c() called from the Text
+   PDU path.  The OOB bytes feed crc32c() and are then compared against
+   the initiator-supplied checksum, so the value does not flow back to
+   the attacker, but the kernel does read past the buffer on every Text
+   PDU with DataDigest=CRC32C.
+
+   Fix by passing the actual padded payload length
+   (ALIGN(payload_length, 4)) that was used for the kzalloc().
+
+2) Stale cmd->text_in_ptr re-free (double-free) on ERL>0 bad DataDigest
+   drop.
+
+   On DataDigest mismatch with ErrorRecoveryLevel > 0 the handler
+   silently drops the PDU and lets the initiator plug the CmdSN gap:
+
+               kfree(text_in);
+               return 0;
+
+   cmd->text_in_ptr still points at the freed buffer.  The next Text
+   Request on the same ITT re-enters iscsit_setup_text_cmd(), which
+   unconditionally does
+
+       kfree(cmd->text_in_ptr);
+       cmd->text_in_ptr = NULL;
+
+   freeing the same pointer a second time.  Session teardown via
+   iscsit_release_cmd() has the same shape and hits the same double-free
+   if the connection is dropped before a second Text Request arrives.
+
+   On an unmodified mainline tree the bug-1 CRC overread fires first on
+   the initial valid Text Request and perturbs the subsequent state, so
+   #4 was isolated by building a kernel with only the bug-1 hunk of this
+   patch applied plus temporary printk() observability around the three
+   relevant kfree() sites.  The observability prints are not part of
+   this patch.  On that build, a three-PDU Text Request sequence after
+   login produces two back-to-back splats:
+
+       BUG: KASAN: double-free in iscsit_setup_text_cmd+0x??
+       BUG: KASAN: double-free in iscsit_release_cmd+0x??
+
+   showing the same pointer freed in the ERL>0 drop path and again in
+   iscsit_setup_text_cmd() (next Text Request on the same ITT) and once
+   more in iscsit_release_cmd() (session teardown).  On distro kernels
+   with CONFIG_SLAB_FREELIST_HARDENED=y (default) the double-free
+   becomes a remote kernel BUG(); on non-hardened kernels it corrupts
+   the slab freelist.
+
+   Fix by clearing cmd->text_in_ptr after the kfree() in the ERL>0 drop
+   path.  With both hunks applied #4 is directly observable on the stock
+   tree without observability printks; fixing bug-1 alone would mask #4
+   less, not more, so the hunks are submitted together.
+
+Both fixes are one-liners.  The Text PDU state machine is unchanged and
+the wire protocol is unaffected.
+
+Fixes: e48354ce078c ("iscsi-target: Add iSCSI fabric support for target v4.1")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Tested-by: John Garry <john.g.garry@oracle.com>
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/target/iscsi/iscsi_target.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -2336,8 +2336,9 @@ iscsit_handle_text_cmd(struct iscsit_con
+               if (conn->conn_ops->DataDigest) {
+                       iscsit_do_crypto_hash_buf(conn->conn_rx_hash,
+-                                                text_in, rx_size, 0, NULL,
+-                                                &data_crc);
++                                                text_in,
++                                                ALIGN(payload_length, 4),
++                                                0, NULL, &data_crc);
+                       if (checksum != data_crc) {
+                               pr_err("Text data CRC32C DataDigest"
+@@ -2357,6 +2358,7 @@ iscsit_handle_text_cmd(struct iscsit_con
+                                       " Command CmdSN: 0x%08x due to"
+                                       " DataCRC error.\n", hdr->cmdsn);
+                                       kfree(text_in);
++                                      cmd->text_in_ptr = NULL;
+                                       return 0;
+                               }
+                       } else {
diff --git a/queue-6.1/selftests-mptcp-drop-nanoseconds-width-specifier.patch b/queue-6.1/selftests-mptcp-drop-nanoseconds-width-specifier.patch
new file mode 100644 (file)
index 0000000..020e4ca
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-256911-greg=kroah.com@vger.kernel.org Sat May 30 19:58:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 30 May 2026 10:28:35 -0400
+Subject: selftests: mptcp: drop nanoseconds width specifier
+To: stable@vger.kernel.org
+Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260530142835.2434049-1-sashal@kernel.org>
+
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+
+[ Upstream commit 01ff78e4b3d98689184c52d97f9575dfbdc3b10f ]
+
+Using the format specifier +%s%3N with GNU date is honoured, and only
+prints 3 digits of the nanoseconds portion of the seconds since epoch,
+which corresponds to the milliseconds.
+
+The uutils implementation of date currently does not honour this, and
+always prints all 9 digits. This is a known issue [1], but can be worked
+around by adapting this test to use nanoseconds instead of microseconds,
+and then divide it by 1e6.
+
+This fix is similar to what has been done on systemd side [2], and it is
+needed to run the selftests on Ubuntu 26.04, containing uutils 0.8.0.
+
+Note that the Fixes tag is there even if this patch doesn't fix an issue
+in the kernel selftests, but it is useful for those using uutils 0.8.0.
+
+Fixes: 048d19d444be ("mptcp: add basic kselftest for mptcp")
+Cc: stable@vger.kernel.org
+Link: https://github.com/uutils/coreutils/issues/11658 [1]
+Link: https://github.com/systemd/systemd/pull/41627 [2]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260515-net-mptcp-misc-fixes-7-1-rc4-v2-6-701e96419f2f@kernel.org
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ tools/testing/selftests/net/mptcp/mptcp_connect.sh |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/tools/testing/selftests/net/mptcp/mptcp_connect.sh
++++ b/tools/testing/selftests/net/mptcp/mptcp_connect.sh
+@@ -450,7 +450,7 @@ do_transfer()
+       wait_local_port_listen "${listener_ns}" "${port}"
+       local start
+-      start=$(date +%s%3N)
++      start=$(date +%s%N)
+       timeout ${timeout_test} \
+               ip netns exec ${connector_ns} \
+                       ./mptcp_connect -t ${timeout_poll} -p $port -s ${cl_proto} \
+@@ -463,7 +463,7 @@ do_transfer()
+       local rets=$?
+       local stop
+-      stop=$(date +%s%3N)
++      stop=$(date +%s%N)
+       if $capture; then
+               sleep 1
+@@ -479,7 +479,7 @@ do_transfer()
+       fi
+       local duration
+-      duration=$((stop-start))
++      duration=$(((stop-start) / 1000000))
+       printf "(duration %05sms) " "${duration}"
+       if [ ${rets} -ne 0 ] || [ ${retc} -ne 0 ]; then
+               echo "[ FAIL ] client exit code $retc, server $rets" 1>&2
diff --git a/queue-6.1/serial-qcom-geni-fix-uart_rx_par_en-bit-position.patch b/queue-6.1/serial-qcom-geni-fix-uart_rx_par_en-bit-position.patch
new file mode 100644 (file)
index 0000000..1d4ca3a
--- /dev/null
@@ -0,0 +1,42 @@
+From stable+bounces-260847-greg=kroah.com@vger.kernel.org Sat Jun  6 08:17:19 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 22:47:09 -0400
+Subject: serial: qcom-geni: fix UART_RX_PAR_EN bit position
+To: stable@vger.kernel.org
+Cc: Prasanna S <prasanna.s@oss.qualcomm.com>, stable <stable@kernel.org>, Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606024709.2514691-3-sashal@kernel.org>
+
+From: Prasanna S <prasanna.s@oss.qualcomm.com>
+
+[ Upstream commit ca2584d841b69391ffc4144840563d2e1a0018df ]
+
+UART_RX_PAR_EN is incorrectly defined as bit 3, which triggers false
+framing errors (S_GP_IRQ_1_EN) and causes received data to be dropped
+when parity is enabled and the parity bit is 0.
+
+Define UART_RX_PAR_EN as bit 4 of the SE_UART_RX_TRANS_CFG register, as
+specified in the reference manual.
+
+Fixes: c4f528795d1a ("tty: serial: msm_geni_serial: Add serial driver support for GENI based QUP")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Prasanna S <prasanna.s@oss.qualcomm.com>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
+Link: https://patch.msgid.link/20260428-serial-bit-correct-v1-1-9131ad5b97d8@oss.qualcomm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -47,7 +47,7 @@
+ #define TX_STOP_BIT_LEN_2             2
+ /* SE_UART_RX_TRANS_CFG */
+-#define UART_RX_PAR_EN                        BIT(3)
++#define UART_RX_PAR_EN                        BIT(4)
+ /* SE_UART_RX_WORD_LEN */
+ #define RX_WORD_LEN_MASK              GENMASK(9, 0)
diff --git a/queue-6.1/serial-samsung_tty-use-port-lock-wrappers.patch b/queue-6.1/serial-samsung_tty-use-port-lock-wrappers.patch
new file mode 100644 (file)
index 0000000..23bfbb1
--- /dev/null
@@ -0,0 +1,254 @@
+From stable+bounces-260726-greg=kroah.com@vger.kernel.org Fri Jun  5 21:15:43 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 11:31:02 -0400
+Subject: serial: samsung_tty: Use port lock wrappers
+To: stable@vger.kernel.org
+Cc: Thomas Gleixner <tglx@linutronix.de>, John Ogness <john.ogness@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605153104.1929085-1-sashal@kernel.org>
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+[ Upstream commit 97d7a9aeba1d424c2359f1686d02c75d798ad184 ]
+
+When a serial port is used for kernel console output, then all
+modifications to the UART registers which are done from other contexts,
+e.g. getty, termios, are interference points for the kernel console.
+
+So far this has been ignored and the printk output is based on the
+principle of hope. The rework of the console infrastructure which aims to
+support threaded and atomic consoles, requires to mark sections which
+modify the UART registers as unsafe. This allows the atomic write function
+to make informed decisions and eventually to restore operational state. It
+also allows to prevent the regular UART code from modifying UART registers
+while printk output is in progress.
+
+All modifications of UART registers are guarded by the UART port lock,
+which provides an obvious synchronization point with the console
+infrastructure.
+
+To avoid adding this functionality to all UART drivers, wrap the
+spin_[un]lock*() invocations for uart_port::lock into helper functions
+which just contain the spin_[un]lock*() invocations for now. In a
+subsequent step these helpers will gain the console synchronization
+mechanisms.
+
+Converted with coccinelle. No functional change.
+
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: John Ogness <john.ogness@linutronix.de>
+Link: https://lore.kernel.org/r/20230914183831.587273-54-john.ogness@linutronix.de
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c |   50 +++++++++++++++++++--------------------
+ 1 file changed, 25 insertions(+), 25 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -251,7 +251,7 @@ static void s3c24xx_serial_rx_enable(str
+       unsigned int ucon, ufcon;
+       int count = 10000;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       while (--count && !s3c24xx_serial_txempty_nofifo(port))
+               udelay(100);
+@@ -265,7 +265,7 @@ static void s3c24xx_serial_rx_enable(str
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 1;
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_rx_disable(struct uart_port *port)
+@@ -274,14 +274,14 @@ static void s3c24xx_serial_rx_disable(st
+       unsigned long flags;
+       unsigned int ucon;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       ucon = rd_regl(port, S3C2410_UCON);
+       ucon &= ~S3C2410_UCON_RXIRQMODE;
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 0;
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_stop_tx(struct uart_port *port)
+@@ -349,7 +349,7 @@ static void s3c24xx_serial_tx_dma_comple
+                               dma->tx_transfer_addr, dma->tx_size,
+                               DMA_TO_DEVICE);
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1);
+       port->icount.tx += count;
+@@ -359,7 +359,7 @@ static void s3c24xx_serial_tx_dma_comple
+               uart_write_wakeup(port);
+       s3c24xx_serial_start_next_tx(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void enable_tx_dma(struct s3c24xx_uart_port *ourport)
+@@ -625,7 +625,7 @@ static void s3c24xx_serial_rx_dma_comple
+       received  = dma->rx_bytes_requested - state.residue;
+       async_tx_ack(dma->rx_desc);
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       if (received)
+               s3c24xx_uart_copy_rx_to_tty(ourport, t, received);
+@@ -637,7 +637,7 @@ static void s3c24xx_serial_rx_dma_comple
+       s3c64xx_start_rx_dma(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c64xx_start_rx_dma(struct s3c24xx_uart_port *ourport)
+@@ -728,7 +728,7 @@ static irqreturn_t s3c24xx_serial_rx_cha
+       utrstat = rd_regl(port, S3C2410_UTRSTAT);
+       rd_regl(port, S3C2410_UFSTAT);
+-      spin_lock(&port->lock);
++      uart_port_lock(port);
+       if (!(utrstat & S3C2410_UTRSTAT_TIMEOUT)) {
+               s3c64xx_start_rx_dma(ourport);
+@@ -757,7 +757,7 @@ static irqreturn_t s3c24xx_serial_rx_cha
+       wr_regl(port, S3C2410_UTRSTAT, S3C2410_UTRSTAT_TIMEOUT);
+ finish:
+-      spin_unlock(&port->lock);
++      uart_port_unlock(port);
+       return IRQ_HANDLED;
+ }
+@@ -854,9 +854,9 @@ static irqreturn_t s3c24xx_serial_rx_cha
+       struct s3c24xx_uart_port *ourport = dev_id;
+       struct uart_port *port = &ourport->port;
+-      spin_lock(&port->lock);
++      uart_port_lock(port);
+       s3c24xx_serial_rx_drain_fifo(ourport);
+-      spin_unlock(&port->lock);
++      uart_port_unlock(port);
+       return IRQ_HANDLED;
+ }
+@@ -938,11 +938,11 @@ static irqreturn_t s3c24xx_serial_tx_irq
+       struct s3c24xx_uart_port *ourport = id;
+       struct uart_port *port = &ourport->port;
+-      spin_lock(&port->lock);
++      uart_port_lock(port);
+       s3c24xx_serial_tx_chars(ourport);
+-      spin_unlock(&port->lock);
++      uart_port_unlock(port);
+       return IRQ_HANDLED;
+ }
+@@ -1038,7 +1038,7 @@ static void s3c24xx_serial_break_ctl(str
+       unsigned long flags;
+       unsigned int ucon;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       ucon = rd_regl(port, S3C2410_UCON);
+@@ -1049,7 +1049,7 @@ static void s3c24xx_serial_break_ctl(str
+       wr_regl(port, S3C2410_UCON, ucon);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static int s3c24xx_serial_request_dma(struct s3c24xx_uart_port *p)
+@@ -1308,7 +1308,7 @@ static int s3c64xx_serial_startup(struct
+       ourport->rx_enabled = 1;
+       ourport->tx_enabled = 0;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       ufcon = rd_regl(port, S3C2410_UFCON);
+       ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
+@@ -1318,7 +1318,7 @@ static int s3c64xx_serial_startup(struct
+       enable_rx_pio(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+       /* Enable Rx Interrupt */
+       s3c24xx_clear_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM);
+@@ -1346,7 +1346,7 @@ static int apple_s5l_serial_startup(stru
+       ourport->rx_enabled = 1;
+       ourport->tx_enabled = 0;
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       ufcon = rd_regl(port, S3C2410_UFCON);
+       ufcon |= S3C2410_UFCON_RESETRX | S5PV210_UFCON_RXTRIG8;
+@@ -1356,7 +1356,7 @@ static int apple_s5l_serial_startup(stru
+       enable_rx_pio(ourport);
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+       /* Enable Rx Interrupt */
+       s3c24xx_set_bit(port, APPLE_S5L_UCON_RXTHRESH_ENA, S3C2410_UCON);
+@@ -1633,7 +1633,7 @@ static void s3c24xx_serial_set_termios(s
+               ulcon |= S3C2410_LCON_PNONE;
+       }
+-      spin_lock_irqsave(&port->lock, flags);
++      uart_port_lock_irqsave(port, &flags);
+       dev_dbg(port->dev,
+               "setting ulcon to %08x, brddiv to %d, udivslot %08x\n",
+@@ -1691,7 +1691,7 @@ static void s3c24xx_serial_set_termios(s
+       if ((termios->c_cflag & CREAD) == 0)
+               port->ignore_status_mask |= RXSTAT_DUMMY_READ;
+-      spin_unlock_irqrestore(&port->lock, flags);
++      uart_port_unlock_irqrestore(port, flags);
+ }
+ static const char *s3c24xx_serial_type(struct uart_port *port)
+@@ -2476,14 +2476,14 @@ s3c24xx_serial_console_write(struct cons
+       if (cons_uart->sysrq)
+               locked = false;
+       else if (oops_in_progress)
+-              locked = spin_trylock_irqsave(&cons_uart->lock, flags);
++              locked = uart_port_trylock_irqsave(cons_uart, &flags);
+       else
+-              spin_lock_irqsave(&cons_uart->lock, flags);
++              uart_port_lock_irqsave(cons_uart, &flags);
+       uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
+       if (locked)
+-              spin_unlock_irqrestore(&cons_uart->lock, flags);
++              uart_port_unlock_irqrestore(cons_uart, flags);
+ }
+ /* Shouldn't be __init, as it can be instantiated from other module */
index 07c1839b595a8ea06865b0c4eb132883259a4313..b6d5ef99125bb1fcc9d64418869b3d7d54f1ab52 100644 (file)
@@ -354,3 +354,136 @@ net-qrtr-ns-limit-the-total-number-of-nodes.patch
 net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch
 spi-fix-resource-leaks-on-device-setup-failure.patch
 fbdev-defio-disconnect-deferred-i-o-from-the-lifetime-of-struct-fb_info.patch
+xfs-fix-a-resource-leak-in-xfs_alloc_buftarg.patch
+udf-fix-partition-descriptor-append-bookkeeping.patch
+hfsplus-fix-uninit-value-by-validating-catalog-record-size.patch
+hfsplus-fix-held-lock-freed-on-hfsplus_fill_super.patch
+crypto-nx-avoid-wflex-array-member-not-at-end-warning.patch
+crypto-nx-migrate-to-scomp-api.patch
+crypto-nx-fix-bounce-buffer-leaks-in-nx842_crypto_-alloc-free-_ctx.patch
+erofs-fix-unsigned-underflow-in-z_erofs_lz4_handle_overlap.patch
+ceph-only-d_add-negative-dentries-when-they-are-unhashed.patch
+printk-add-print_hex_dump_devel.patch
+crypto-caam-guard-hmac-key-hex-dumps-in-hash_digest_key.patch
+net-stmmac-avoid-shadowing-global-buf_sz.patch
+net-stmmac-rename-stmmac_get_entry-stmmac_next_entry.patch
+net-stmmac-prevent-null-deref-when-rx-memory-exhausted.patch
+tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
+wifi-mac80211-remove-station-if-connection-prep-fails.patch
+wifi-brcmfmac-fix-potential-use-after-free-issue-when-stopping-watchdog-task.patch
+usb-dwc3-move-guid-programming-after-phy-initialization.patch
+net-ipv4-stop-checking-crypto_ahash_alignmask.patch
+net-ipv6-stop-checking-crypto_ahash_alignmask.patch
+xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch
+xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch
+spi-synquacer-convert-to-platform-remove-callback-returning-void.patch
+spi-synquacer-switch-to-use-modern-name.patch
+spi-syncuacer-fix-controller-deregistration.patch
+spi-sun4i-convert-to-platform-remove-callback-returning-void.patch
+spi-sun4i-switch-to-use-modern-name.patch
+spi-sun4i-fix-controller-deregistration.patch
+spi-convert-to-spi_controller_half_duplex.patch
+spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch
+spi-spi-ti-qspi-switch-to-use-modern-name.patch
+spi-ti-qspi-fix-controller-deregistration.patch
+spi-zynq-qspi-convert-to-platform-remove-callback-returning-void.patch
+spi-spi-zynq-do-not-check-for-0-return-after-calling-platform_get_irq.patch
+spi-zynq-qspi-switch-to-use-modern-name.patch
+spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch
+spi-zynq-qspi-fix-controller-deregistration.patch
+spi-sun6i-fix-controller-deregistration.patch
+spi-s3c64xx-use-devm_clk_get_enabled.patch
+spi-s3c64xx-fix-null-deref-on-driver-unbind.patch
+mtd-spi-nor-core-fix-implicit-declaration-warning.patch
+mtd-spi-nor-debugfs-fix-out-of-bounds-read-in-spi_nor_params_show.patch
+spi-tegra114-fix-controller-deregistration.patch
+spi-tegra20-sflash-fix-controller-deregistration.patch
+spi-uniphier-convert-to-platform-remove-callback-returning-void.patch
+spi-uniphier-switch-to-use-modern-name.patch
+spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch
+spi-uniphier-fix-controller-deregistration.patch
+mm-hugetlb_cma-round-up-per_node-before-logging-it.patch
+net-wwan-t7xx-validate-port_count-against-message-length-in-t7xx_port_enum_msg_handler.patch
+spi-microchip-core-qspi-convert-to-platform-remove-callback-returning-void.patch
+spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch
+spi-microchip-core-qspi-fix-controller-deregistration.patch
+fbcon-avoid-oob-font-access-if-console-rotation-fails.patch
+spi-topcliff-pch-convert-to-platform-remove-callback-returning-void.patch
+btrfs-fix-btrfs_ioctl_space_info-slot_count-toctou-which-can-lead-to-info-leak.patch
+tracing-probes-limit-size-of-event-probe-to-3k.patch
+btrfs-remove-fs_info-argument-from-btrfs_sysfs_add_space_info_type.patch
+btrfs-fix-double-free-in-create_space_info_sub_group-error-path.patch
+pmdomain-core-fix-detach-procedure-for-virtual-devices-in-genpd.patch
+smb-client-validate-dacloffset-before-building-dacl-pointers.patch
+smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
+btrfs-fix-missing-last_unlink_trans-update-when-removing-a-directory.patch
+mptcp-fastclose-msk-when-linger-time-is-0.patch
+mptcp-pm-prio-skip-closed-subflows.patch
+mptcp-pm-kernel-correctly-retransmit-add_addr-id-0.patch
+mptcp-pm-add_addr-rtx-allow-id-0.patch
+mptcp-pm-add_addr-rtx-fix-potential-data-race.patch
+mptcp-pm-add_addr-rtx-resched-blocked-add_addr-quicker.patch
+f2fs-fix-incorrect-file-address-mapping-when-inline-inode-is-unwritten.patch
+f2fs-fix-false-alarm-of-lockdep-on-cp_global_sem-lock.patch
+spi-st-ssc4-switch-to-use-modern-name.patch
+spi-st-ssc4-fix-controller-deregistration.patch
+spi-lantiq-ssc-fix-controller-deregistration.patch
+cgroup-cpuset-reset-dl-migration-state-on-can_attach-failure.patch
+genetlink-use-internal-flags-for-multicast-groups.patch
+smb-client-require-net-admin-for-cifs-swn-netlink.patch
+bluetooth-hci_qca-convert-timeout-from-jiffies-to-ms.patch
+mm-memory-fix-spurious-warning-when-unmapping-device-private-exclusive-pages.patch
+bluetooth-init-sk_peer_-on-bt_sock_alloc.patch
+bluetooth-serialize-accept_q-access.patch
+net-hsr-defer-node-table-free-until-after-rcu-readers.patch
+ipv6-ioam-add-null-check-for-idev-in-ipv6_hop_ioam.patch
+ice-fix-vf-queue-configuration-with-low-mtu-values.patch
+mptcp-pm-fix-add_addr-timer-infinite-retry-on-option-space-insufficient.patch
+selftests-mptcp-drop-nanoseconds-width-specifier.patch
+octeontx2-af-replace-deprecated-strncpy-with-strscpy.patch
+octeontx2-af-cgx-add-bounds-check-to-cgx_speed_mbps-index.patch
+mptcp-reset-rcv-wnd-on-disconnect.patch
+mptcp-do-not-drop-partial-packets.patch
+platform-x86-intel-vsec-add-private-data-for-per-device-data.patch
+platform-x86-intel-vsec-create-wrapper-to-walk-pci-config-space.patch
+platform-x86-intel-vsec-make-driver_data-info-const.patch
+platform-x86-intel-vsec-fix-enable_cnt-imbalance-on-pcie-error-recovery.patch
+octeontx2-pf-avoid-double-free-of-pool-stack-on-aq-init-failure.patch
+spi-qup-switch-to-use-modern-name.patch
+spi-qup-fix-error-pointer-deref-after-dma-setup-failure.patch
+arm64-tlb-flush-walk-cache-when-unsharing-pmd-tables.patch
+phy-tegra-xusb-disable-trk-clk-when-not-in-use.patch
+phy-tegra-xusb-fix-per-pad-high-speed-termination-calibration.patch
+iio-adc-fix-the-return-value-handle-for-platform_get_irq.patch
+iio-adc-npcm-convert-to-platform-remove-callback-returning-void.patch
+iio-adc-npcm-fix-unbalanced-clk_disable_unprepare.patch
+iio-gyro-adis16260-fix-division-by-zero-in-write_raw.patch
+iio-chemical-scd30-use-guard-mutex-to-allow-early-returns.patch
+iio-chemical-scd30-fix-division-by-zero-in-write_raw.patch
+usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch
+iio-dac-ad5686-fix-ref-bit-initialization-for-single-channel-parts.patch
+alsa-firewire-motu-protect-register-dsp-event-queue-positions.patch
+serial-samsung_tty-use-port-lock-wrappers.patch
+tty-serial-samsung-use-u32-for-register-interactions.patch
+tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch
+usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch
+usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch
+usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch
+usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch
+usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch
+thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch
+tty-serial-qcom-geni-serial-remove-unused-symbols.patch
+tty-serial-qcom-geni-serial-align-define-values.patch
+serial-qcom-geni-fix-uart_rx_par_en-bit-position.patch
+scsi-target-iscsi-fix-crc-overread-and-double-free-in-iscsit_handle_text_cmd.patch
+usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch
+netfilter-nft_fib-fix-stale-stack-leak-via-the-oifname-register.patch
+hv_netvsc-use-kmap_local_page-in-netvsc_copy_to_send_buf.patch
+mm-hugetlb-rename-isolate_hugetlb-to-folio_isolate_hugetlb.patch
+mm-migrate-don-t-call-folio_putback_active_hugetlb-on-dst-hugetlb-folio.patch
+mm-hugetlb-rename-folio_putback_active_hugetlb-to-folio_putback_hugetlb.patch
+mm-memory-failure-fix-missing-mf_stats-count-in-hugetlb-poison.patch
+mm-memory-failure-fix-hugetlb_lock-aa-deadlock-in-get_huge_page_for_hwpoison.patch
+rdma-umem-fix-kernel-doc-warnings.patch
+rdma-move-dma-block-iterator-logic-into-dedicated-files.patch
+rdma-umem-fix-truncation-for-block-sizes-4g.patch
diff --git a/queue-6.1/smb-client-require-net-admin-for-cifs-swn-netlink.patch b/queue-6.1/smb-client-require-net-admin-for-cifs-swn-netlink.patch
new file mode 100644 (file)
index 0000000..7289ae4
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-256668-greg=kroah.com@vger.kernel.org Fri May 29 22:49:35 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 29 May 2026 13:06:10 -0400
+Subject: smb: client: require net admin for CIFS SWN netlink
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260529170610.1279657-2-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit d1ebfce2c1d161186a82e77590bf7da2ea1bce91 ]
+
+CIFS_GENL_CMD_SWN_NOTIFY is the userspace witness-notify command.  The
+intended sender is the cifs.witness helper, but the generic-netlink
+operation currently has no capability flag, so any local process can send
+RESOURCE_CHANGE or CLIENT_MOVE notifications to the in-kernel witness
+handler.
+
+The same family exposes CIFS_GENL_MCGRP_SWN without multicast-group
+capability flags.  Register messages sent to that group include the witness
+registration id and, for NTLM-authenticated mounts, the username, domain,
+and password attributes copied from the CIFS session.  An unprivileged
+local process should not be able to join that group and receive those
+messages.
+
+Require CAP_NET_ADMIN for incoming SWN_NOTIFY commands with
+GENL_ADMIN_PERM, and require CAP_NET_ADMIN over the network namespace for
+joining the SWN multicast group with GENL_MCAST_CAP_NET_ADMIN.  The
+cifs.witness service runs with the privileges needed for both operations.
+
+Fixes: fed979a7e082 ("cifs: Set witness notification handler for messages from userspace daemon")
+Cc: stable@vger.kernel.org
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Steve French <stfrench@microsoft.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/netlink.c |    6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+--- a/fs/smb/client/netlink.c
++++ b/fs/smb/client/netlink.c
+@@ -33,13 +33,17 @@ static const struct nla_policy cifs_genl
+ static const struct genl_ops cifs_genl_ops[] = {
+       {
+               .cmd = CIFS_GENL_CMD_SWN_NOTIFY,
++              .flags = GENL_ADMIN_PERM,
+               .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+               .doit = cifs_swn_notify,
+       },
+ };
+ static const struct genl_multicast_group cifs_genl_mcgrps[] = {
+-      [CIFS_GENL_MCGRP_SWN] = { .name = CIFS_GENL_MCGRP_SWN_NAME },
++      [CIFS_GENL_MCGRP_SWN] = {
++              .name = CIFS_GENL_MCGRP_SWN_NAME,
++              .flags = GENL_MCAST_CAP_NET_ADMIN,
++      },
+ };
+ struct genl_family cifs_genl_family = {
diff --git a/queue-6.1/smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch b/queue-6.1/smb-client-use-fullsessionkey-for-aes-256-encryption-key-derivation.patch
new file mode 100644 (file)
index 0000000..d9c6165
--- /dev/null
@@ -0,0 +1,154 @@
+From stable+bounces-249112-greg=kroah.com@vger.kernel.org Sun May 17 21:18:41 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 17 May 2026 11:48:33 -0400
+Subject: smb: client: Use FullSessionKey for AES-256 encryption key derivation
+To: stable@vger.kernel.org
+Cc: Piyush Sachdeva <s.piyush1024@gmail.com>, Bharath SM <bharathsm@microsoft.com>, Piyush Sachdeva <psachdeva@microsoft.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260517154833.296848-1-sashal@kernel.org>
+
+From: Piyush Sachdeva <s.piyush1024@gmail.com>
+
+[ Upstream commit 5be7a0cef3229fb3b63a07c0d289daf752545424 ]
+
+When Kerberos authentication is used with AES-256 encryption (AES-256-CCM
+or AES-256-GCM), the SMB3 encryption and decryption keys must be derived
+using the full session key (Session.FullSessionKey) rather than just the
+first 16 bytes (Session.SessionKey).
+
+Per MS-SMB2 section 3.2.5.3.1, when Connection.Dialect is "3.1.1" and
+Connection.CipherId is AES-256-CCM or AES-256-GCM, Session.FullSessionKey
+must be set to the full cryptographic key from the GSS authentication
+context. The encryption and decryption key derivation (SMBC2SCipherKey,
+SMBS2CCipherKey) must use this FullSessionKey as the KDF input. The
+signing key derivation continues to use Session.SessionKey (first 16
+bytes) in all cases.
+
+Previously, generate_key() hardcoded SMB2_NTLMV2_SESSKEY_SIZE (16) as the
+HMAC-SHA256 key input length for all derivations. When Kerberos with
+AES-256 provides a 32-byte session key, the KDF for encryption/decryption
+was using only the first 16 bytes, producing keys that did not match the
+server's, causing mount failures with sec=krb5 and require_gcm_256=1.
+
+Add a full_key_size parameter to generate_key() and pass the appropriate
+size from generate_smb3signingkey():
+ - Signing: always SMB2_NTLMV2_SESSKEY_SIZE (16 bytes)
+ - Encryption/Decryption: ses->auth_key.len when AES-256, otherwise 16
+
+Also fix cifs_dump_full_key() to report the actual session key length for
+AES-256 instead of hardcoded CIFS_SESS_KEY_SIZE, so that userspace tools
+like Wireshark receive the correct key for decryption.
+
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Bharath SM <bharathsm@microsoft.com>
+Signed-off-by: Piyush Sachdeva <psachdeva@microsoft.com>
+Signed-off-by: Piyush Sachdeva <s.piyush1024@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ adapted upstream's void/hmac_sha256_init_usingrawkey-based generate_key() to 6.12's int-return crypto_shash_* form while threading full_key_size through all callers. ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/ioctl.c         |    2 +-
+ fs/smb/client/smb2transport.c |   32 +++++++++++++++++++++++++-------
+ 2 files changed, 26 insertions(+), 8 deletions(-)
+
+--- a/fs/smb/client/ioctl.c
++++ b/fs/smb/client/ioctl.c
+@@ -279,7 +279,7 @@ search_end:
+               break;
+       case SMB2_ENCRYPTION_AES256_CCM:
+       case SMB2_ENCRYPTION_AES256_GCM:
+-              out.session_key_length = CIFS_SESS_KEY_SIZE;
++              out.session_key_length = ses->auth_key.len;
+               out.server_in_key_length = out.server_out_key_length = SMB3_GCM256_CRYPTKEY_SIZE;
+               break;
+       default:
+--- a/fs/smb/client/smb2transport.c
++++ b/fs/smb/client/smb2transport.c
+@@ -307,7 +307,8 @@ out:
+ }
+ static int generate_key(struct cifs_ses *ses, struct kvec label,
+-                      struct kvec context, __u8 *key, unsigned int key_size)
++                      struct kvec context, __u8 *key, unsigned int key_size,
++                      unsigned int full_key_size)
+ {
+       unsigned char zero = 0x0;
+       __u8 i[4] = {0, 0, 0, 1};
+@@ -328,7 +329,7 @@ static int generate_key(struct cifs_ses
+       }
+       rc = crypto_shash_setkey(server->secmech.hmacsha256->tfm,
+-              ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE);
++              ses->auth_key.response, full_key_size);
+       if (rc) {
+               cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__);
+               goto smb3signkey_ret;
+@@ -403,6 +404,7 @@ generate_smb3signingkey(struct cifs_ses
+                       struct TCP_Server_Info *server,
+                       const struct derivation_triplet *ptriplet)
+ {
++      unsigned int full_key_size = SMB2_NTLMV2_SESSKEY_SIZE;
+       int rc;
+       bool is_binding = false;
+       int chan_index = 0;
+@@ -431,17 +433,31 @@ generate_smb3signingkey(struct cifs_ses
+               rc = generate_key(ses, ptriplet->signing.label,
+                                 ptriplet->signing.context,
+                                 ses->chans[chan_index].signkey,
+-                                SMB3_SIGN_KEY_SIZE);
++                                SMB3_SIGN_KEY_SIZE,
++                                SMB2_NTLMV2_SESSKEY_SIZE);
+               if (rc)
+                       return rc;
+       } else {
+               rc = generate_key(ses, ptriplet->signing.label,
+                                 ptriplet->signing.context,
+                                 ses->smb3signingkey,
+-                                SMB3_SIGN_KEY_SIZE);
++                                SMB3_SIGN_KEY_SIZE,
++                                SMB2_NTLMV2_SESSKEY_SIZE);
+               if (rc)
+                       return rc;
++              /*
++               * Per MS-SMB2 3.2.5.3.1, signing key always uses Session.SessionKey
++               * (first 16 bytes). Encryption/decryption keys use
++               * Session.FullSessionKey when dialect is 3.1.1 and cipher is
++               * AES-256-CCM or AES-256-GCM, otherwise Session.SessionKey.
++               */
++
++              if (server->dialect == SMB311_PROT_ID &&
++                  (server->cipher_type == SMB2_ENCRYPTION_AES256_CCM ||
++                   server->cipher_type == SMB2_ENCRYPTION_AES256_GCM))
++                      full_key_size = ses->auth_key.len;
++
+               /* safe to access primary channel, since it will never go away */
+               spin_lock(&ses->chan_lock);
+               memcpy(ses->chans[chan_index].signkey, ses->smb3signingkey,
+@@ -451,13 +467,15 @@ generate_smb3signingkey(struct cifs_ses
+               rc = generate_key(ses, ptriplet->encryption.label,
+                                 ptriplet->encryption.context,
+                                 ses->smb3encryptionkey,
+-                                SMB3_ENC_DEC_KEY_SIZE);
++                                SMB3_ENC_DEC_KEY_SIZE,
++                                full_key_size);
+               if (rc)
+                       return rc;
+               rc = generate_key(ses, ptriplet->decryption.label,
+                                 ptriplet->decryption.context,
+                                 ses->smb3decryptionkey,
+-                                SMB3_ENC_DEC_KEY_SIZE);
++                                SMB3_ENC_DEC_KEY_SIZE,
++                                full_key_size);
+               if (rc)
+                       return rc;
+       }
+@@ -472,7 +490,7 @@ generate_smb3signingkey(struct cifs_ses
+                       &ses->Suid);
+       cifs_dbg(VFS, "Cipher type   %d\n", server->cipher_type);
+       cifs_dbg(VFS, "Session Key   %*ph\n",
+-               SMB2_NTLMV2_SESSKEY_SIZE, ses->auth_key.response);
++               (int)ses->auth_key.len, ses->auth_key.response);
+       cifs_dbg(VFS, "Signing Key   %*ph\n",
+                SMB3_SIGN_KEY_SIZE, ses->smb3signingkey);
+       if ((server->cipher_type == SMB2_ENCRYPTION_AES256_CCM) ||
diff --git a/queue-6.1/smb-client-validate-dacloffset-before-building-dacl-pointers.patch b/queue-6.1/smb-client-validate-dacloffset-before-building-dacl-pointers.patch
new file mode 100644 (file)
index 0000000..31619e6
--- /dev/null
@@ -0,0 +1,120 @@
+From stable+bounces-248925-greg=kroah.com@vger.kernel.org Sat May 16 03:06:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 17:36:00 -0400
+Subject: smb: client: validate dacloffset before building DACL pointers
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Steve French <stfrench@microsoft.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515213600.3513360-1-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit f98b48151cc502ada59d9778f0112d21f2586ca3 ]
+
+parse_sec_desc(), build_sec_desc(), and the chown path in
+id_mode_to_cifs_acl() all add the server-supplied dacloffset to pntsd
+before proving a DACL header fits inside the returned security
+descriptor.
+
+On 32-bit builds a malicious server can return dacloffset near
+U32_MAX, wrap the derived DACL pointer below end_of_acl, and then slip
+past the later pointer-based bounds checks. build_sec_desc() and
+id_mode_to_cifs_acl() can then dereference DACL fields from the wrapped
+pointer in the chmod/chown rewrite paths.
+
+Validate dacloffset numerically before building any DACL pointer and
+reuse the same helper at the three DACL entry points.
+
+Fixes: bc3e9dd9d104 ("cifs: Change SIDs in ACEs while transferring file ownership.")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-6
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Steve French <stfrench@microsoft.com>
+[ renamed smb_ntsd/smb_acl structs to cifs_ntsd/cifs_acl and kept existing inline ACL size check instead of using missing validate_dacl() helper ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/smb/client/cifsacl.c |   35 ++++++++++++++++++++++++++++++++---
+ 1 file changed, 32 insertions(+), 3 deletions(-)
+
+--- a/fs/smb/client/cifsacl.c
++++ b/fs/smb/client/cifsacl.c
+@@ -1254,6 +1254,17 @@ static int parse_sid(struct cifs_sid *ps
+       return 0;
+ }
++static bool dacl_offset_valid(unsigned int acl_len, __u32 dacloffset)
++{
++      if (acl_len < sizeof(struct cifs_acl))
++              return false;
++
++      if (dacloffset < sizeof(struct cifs_ntsd))
++              return false;
++
++      return dacloffset <= acl_len - sizeof(struct cifs_acl);
++}
++
+ /* Convert CIFS ACL to POSIX form */
+ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
+@@ -1274,7 +1285,6 @@ static int parse_sec_desc(struct cifs_sb
+       group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+                               le32_to_cpu(pntsd->gsidoffset));
+       dacloffset = le32_to_cpu(pntsd->dacloffset);
+-      dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
+       cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
+                pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset),
+                le32_to_cpu(pntsd->gsidoffset),
+@@ -1305,11 +1315,18 @@ static int parse_sec_desc(struct cifs_sb
+               return rc;
+       }
+-      if (dacloffset)
++      if (dacloffset) {
++              if (!dacl_offset_valid(acl_len, dacloffset)) {
++                      cifs_dbg(VFS, "Server returned illegal DACL offset\n");
++                      return -EINVAL;
++              }
++
++              dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
+               parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr,
+                          group_sid_ptr, fattr, get_mode_from_special_sid);
+-      else
++      } else {
+               cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */
++      }
+       return rc;
+ }
+@@ -1332,6 +1349,11 @@ static int build_sec_desc(struct cifs_nt
+       dacloffset = le32_to_cpu(pntsd->dacloffset);
+       if (dacloffset) {
++              if (!dacl_offset_valid(secdesclen, dacloffset)) {
++                      cifs_dbg(VFS, "Server returned illegal DACL offset\n");
++                      return -EINVAL;
++              }
++
+               dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
+               rc = validate_dacl(dacl_ptr, end_of_acl);
+               if (rc)
+@@ -1698,6 +1720,12 @@ id_mode_to_cifs_acl(struct inode *inode,
+               nsecdesclen = sizeof(struct cifs_ntsd) + (sizeof(struct cifs_sid) * 2);
+               dacloffset = le32_to_cpu(pntsd->dacloffset);
+               if (dacloffset) {
++                      if (!dacl_offset_valid(secdesclen, dacloffset)) {
++                              cifs_dbg(VFS, "Server returned illegal DACL offset\n");
++                              rc = -EINVAL;
++                              goto id_mode_to_cifs_acl_exit;
++                      }
++
+                       dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
+                       rc = validate_dacl(dacl_ptr, (char *)pntsd + secdesclen);
+                       if (rc) {
+@@ -1740,6 +1768,7 @@ id_mode_to_cifs_acl(struct inode *inode,
+               rc = ops->set_acl(pnntsd, nsecdesclen, inode, path, aclflag);
+               cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc);
+       }
++id_mode_to_cifs_acl_exit:
+       cifs_put_tlink(tlink);
+       kfree(pnntsd);
diff --git a/queue-6.1/spi-convert-to-spi_controller_half_duplex.patch b/queue-6.1/spi-convert-to-spi_controller_half_duplex.patch
new file mode 100644 (file)
index 0000000..d9809ea
--- /dev/null
@@ -0,0 +1,167 @@
+From stable+bounces-247003-greg=kroah.com@vger.kernel.org Wed May 13 23:58:16 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:20:14 -0400
+Subject: spi: Convert to SPI_CONTROLLER_HALF_DUPLEX
+To: stable@vger.kernel.org
+Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513182017.3918352-1-sashal@kernel.org>
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 7a2b552c8e0e5bb280558f6c120140f5f06323bc ]
+
+Convert the users under SPI subsystem to SPI_CONTROLLER_HALF_DUPLEX.
+
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Link: https://lore.kernel.org/r/20230710154932.68377-15-andriy.shevchenko@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0c18a1bacbb1 ("spi: ti-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-amd.c             |    2 +-
+ drivers/spi/spi-cavium-thunderx.c |    2 +-
+ drivers/spi/spi-falcon.c          |    2 +-
+ drivers/spi/spi-lp8841-rtc.c      |    2 +-
+ drivers/spi/spi-mxs.c             |    2 +-
+ drivers/spi/spi-omap-uwire.c      |    2 +-
+ drivers/spi/spi-pic32-sqi.c       |    2 +-
+ drivers/spi/spi-qcom-qspi.c       |    2 +-
+ drivers/spi/spi-rockchip-sfc.c    |    2 +-
+ drivers/spi/spi-sprd-adi.c        |    2 +-
+ drivers/spi/spi-ti-qspi.c         |    2 +-
+ drivers/spi/spi-xcomm.c           |    2 +-
+ 12 files changed, 12 insertions(+), 12 deletions(-)
+
+--- a/drivers/spi/spi-amd.c
++++ b/drivers/spi/spi-amd.c
+@@ -404,7 +404,7 @@ static int amd_spi_probe(struct platform
+       master->bus_num = 0;
+       master->num_chipselect = 4;
+       master->mode_bits = 0;
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->max_speed_hz = AMD_SPI_MAX_HZ;
+       master->min_speed_hz = AMD_SPI_MIN_HZ;
+       master->setup = amd_spi_master_setup;
+--- a/drivers/spi/spi-cavium-thunderx.c
++++ b/drivers/spi/spi-cavium-thunderx.c
+@@ -64,7 +64,7 @@ static int thunderx_spi_probe(struct pci
+               p->sys_freq = SYS_FREQ_DEFAULT;
+       dev_info(dev, "Set system clock to %u\n", p->sys_freq);
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->num_chipselect = 4;
+       master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH |
+                           SPI_LSB_FIRST | SPI_3WIRE;
+--- a/drivers/spi/spi-falcon.c
++++ b/drivers/spi/spi-falcon.c
+@@ -401,7 +401,7 @@ static int falcon_sflash_probe(struct pl
+       priv->master = master;
+       master->mode_bits = SPI_MODE_3;
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->setup = falcon_sflash_setup;
+       master->transfer_one_message = falcon_sflash_xfer_one;
+       master->dev.of_node = pdev->dev.of_node;
+--- a/drivers/spi/spi-lp8841-rtc.c
++++ b/drivers/spi/spi-lp8841-rtc.c
+@@ -191,7 +191,7 @@ spi_lp8841_rtc_probe(struct platform_dev
+               return -ENOMEM;
+       platform_set_drvdata(pdev, master);
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->mode_bits = SPI_CS_HIGH | SPI_3WIRE | SPI_LSB_FIRST;
+       master->bus_num = pdev->id;
+--- a/drivers/spi/spi-mxs.c
++++ b/drivers/spi/spi-mxs.c
+@@ -573,7 +573,7 @@ static int mxs_spi_probe(struct platform
+       master->mode_bits = SPI_CPOL | SPI_CPHA;
+       master->num_chipselect = 3;
+       master->dev.of_node = np;
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->auto_runtime_pm = true;
+       spi = spi_master_get_devdata(master);
+--- a/drivers/spi/spi-omap-uwire.c
++++ b/drivers/spi/spi-omap-uwire.c
+@@ -491,7 +491,7 @@ static int uwire_probe(struct platform_d
+       /* the spi->mode bits understood by this driver: */
+       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+       master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 16);
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->bus_num = 2;    /* "official" */
+       master->num_chipselect = 4;
+--- a/drivers/spi/spi-pic32-sqi.c
++++ b/drivers/spi/spi-pic32-sqi.c
+@@ -648,7 +648,7 @@ static int pic32_sqi_probe(struct platfo
+       master->dev.of_node     = pdev->dev.of_node;
+       master->mode_bits       = SPI_MODE_3 | SPI_MODE_0 | SPI_TX_DUAL |
+                                 SPI_RX_DUAL | SPI_TX_QUAD | SPI_RX_QUAD;
+-      master->flags           = SPI_MASTER_HALF_DUPLEX;
++      master->flags           = SPI_CONTROLLER_HALF_DUPLEX;
+       master->can_dma         = pic32_sqi_can_dma;
+       master->bits_per_word_mask      = SPI_BPW_RANGE_MASK(8, 32);
+       master->transfer_one_message    = pic32_sqi_one_message;
+--- a/drivers/spi/spi-qcom-qspi.c
++++ b/drivers/spi/spi-qcom-qspi.c
+@@ -523,7 +523,7 @@ static int qcom_qspi_probe(struct platfo
+       master->mode_bits = SPI_MODE_0 |
+                           SPI_TX_DUAL | SPI_RX_DUAL |
+                           SPI_TX_QUAD | SPI_RX_QUAD;
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->prepare_message = qcom_qspi_prepare_message;
+       master->transfer_one = qcom_qspi_transfer_one;
+       master->handle_err = qcom_qspi_handle_err;
+--- a/drivers/spi/spi-rockchip-sfc.c
++++ b/drivers/spi/spi-rockchip-sfc.c
+@@ -566,7 +566,7 @@ static int rockchip_sfc_probe(struct pla
+       if (!master)
+               return -ENOMEM;
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->mem_ops = &rockchip_sfc_mem_ops;
+       master->dev.of_node = pdev->dev.of_node;
+       master->mode_bits = SPI_TX_QUAD | SPI_TX_DUAL | SPI_RX_QUAD | SPI_RX_DUAL;
+--- a/drivers/spi/spi-sprd-adi.c
++++ b/drivers/spi/spi-sprd-adi.c
+@@ -570,7 +570,7 @@ static int sprd_adi_probe(struct platfor
+       ctlr->dev.of_node = pdev->dev.of_node;
+       ctlr->bus_num = pdev->id;
+       ctlr->num_chipselect = num_chipselect;
+-      ctlr->flags = SPI_MASTER_HALF_DUPLEX;
++      ctlr->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       ctlr->bits_per_word_mask = 0;
+       ctlr->transfer_one = sprd_adi_transfer_one;
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -770,7 +770,7 @@ static int ti_qspi_probe(struct platform
+       master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->setup = ti_qspi_setup;
+       master->auto_runtime_pm = true;
+       master->transfer_one_message = ti_qspi_start_transfer_one;
+--- a/drivers/spi/spi-xcomm.c
++++ b/drivers/spi/spi-xcomm.c
+@@ -219,7 +219,7 @@ static int spi_xcomm_probe(struct i2c_cl
+       master->num_chipselect = 16;
+       master->mode_bits = SPI_CPHA | SPI_CPOL | SPI_3WIRE;
+       master->bits_per_word_mask = SPI_BPW_MASK(8);
+-      master->flags = SPI_MASTER_HALF_DUPLEX;
++      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+       master->transfer_one_message = spi_xcomm_transfer_one;
+       master->dev.of_node = i2c->dev.of_node;
+       i2c_set_clientdata(i2c, master);
diff --git a/queue-6.1/spi-lantiq-ssc-fix-controller-deregistration.patch b/queue-6.1/spi-lantiq-ssc-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..859415c
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-249945-greg=kroah.com@vger.kernel.org Wed May 20 20:18:04 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 10:28:08 -0400
+Subject: spi: lantiq-ssc: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Hauke Mehrtens <hauke@hauke-m.de>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520142808.3647890-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit b99206710d032c16b7f8b75e4bc18414d8e4b9f4 ]
+
+Make sure to deregister the controller before releasing underlying
+resources like clocks during driver unbind.
+
+Fixes: 17f84b793c01 ("spi: lantiq-ssc: add support for Lantiq SSC SPI controller")
+Cc: stable@vger.kernel.org     # 4.11
+Cc: Hauke Mehrtens <hauke@hauke-m.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260409120419.388546-17-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+[ adapted spi_controller/host naming to spi_master/master and preserved the int-returning remove() with trailing return 0 ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-lantiq-ssc.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-lantiq-ssc.c
++++ b/drivers/spi/spi-lantiq-ssc.c
+@@ -997,7 +997,7 @@ static int lantiq_ssc_probe(struct platf
+               "Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n",
+               revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma);
+-      err = devm_spi_register_master(dev, master);
++      err = spi_register_master(master);
+       if (err) {
+               dev_err(dev, "failed to register spi_master\n");
+               goto err_wq_destroy;
+@@ -1021,6 +1021,10 @@ static int lantiq_ssc_remove(struct plat
+ {
+       struct lantiq_ssc_spi *spi = platform_get_drvdata(pdev);
++      spi_master_get(spi->master);
++
++      spi_unregister_master(spi->master);
++
+       lantiq_ssc_writel(spi, 0, LTQ_SPI_IRNEN);
+       lantiq_ssc_writel(spi, 0, LTQ_SPI_CLC);
+       rx_fifo_flush(spi);
+@@ -1031,6 +1035,8 @@ static int lantiq_ssc_remove(struct plat
+       clk_disable_unprepare(spi->spi_clk);
+       clk_put(spi->fpi_clk);
++      spi_master_put(spi->master);
++
+       return 0;
+ }
diff --git a/queue-6.1/spi-microchip-core-qspi-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/spi-microchip-core-qspi-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..d66cc36
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-247278-greg=kroah.com@vger.kernel.org Fri May 15 00:22:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 14:50:12 -0400
+Subject: spi: microchip-core-qspi: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Conor Dooley" <conor.dooley@microchip.com>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260514185014.948789-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit e4cf312d6db2941b8267de6e094312afc1b523ee ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://lore.kernel.org/r/20230303172041.2103336-37-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: e6464140d439 ("spi: microchip-core-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-microchip-core-qspi.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-microchip-core-qspi.c
++++ b/drivers/spi/spi-microchip-core-qspi.c
+@@ -567,7 +567,7 @@ out:
+       return ret;
+ }
+-static int mchp_coreqspi_remove(struct platform_device *pdev)
++static void mchp_coreqspi_remove(struct platform_device *pdev)
+ {
+       struct mchp_coreqspi *qspi = platform_get_drvdata(pdev);
+       u32 control = readl_relaxed(qspi->regs + REG_CONTROL);
+@@ -576,8 +576,6 @@ static int mchp_coreqspi_remove(struct p
+       control &= ~CONTROL_ENABLE;
+       writel_relaxed(control, qspi->regs + REG_CONTROL);
+       clk_disable_unprepare(qspi->clk);
+-
+-      return 0;
+ }
+ static const struct of_device_id mchp_coreqspi_of_match[] = {
+@@ -592,7 +590,7 @@ static struct platform_driver mchp_coreq
+               .name = "microchip,coreqspi",
+               .of_match_table = mchp_coreqspi_of_match,
+       },
+-      .remove = mchp_coreqspi_remove,
++      .remove_new = mchp_coreqspi_remove,
+ };
+ module_platform_driver(mchp_coreqspi_driver);
diff --git a/queue-6.1/spi-microchip-core-qspi-fix-controller-deregistration.patch b/queue-6.1/spi-microchip-core-qspi-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..a614042
--- /dev/null
@@ -0,0 +1,64 @@
+From stable+bounces-247280-greg=kroah.com@vger.kernel.org Fri May 15 00:20:22 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 14:50:14 -0400
+Subject: spi: microchip-core-qspi: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Naga Sureshkumar Relli <nagasuresh.relli@microchip.com>, Conor Dooley <conor.dooley@microchip.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514185014.948789-3-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit e6464140d439f2d42f072eb422a5b1fec470c5a6 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like interrupts during driver unbind.
+
+Fixes: 8596124c4c1b ("spi: microchip-core-qspi: Add support for microchip fpga qspi controllers")
+Cc: stable@vger.kernel.org     # 6.1
+Cc: Naga Sureshkumar Relli <nagasuresh.relli@microchip.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Acked-by: Conor Dooley <conor.dooley@microchip.com>
+Link: https://patch.msgid.link/20260409120419.388546-19-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-microchip-core-qspi.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-microchip-core-qspi.c
++++ b/drivers/spi/spi-microchip-core-qspi.c
+@@ -512,7 +512,7 @@ static int mchp_coreqspi_probe(struct pl
+                                    "unable to allocate master for QSPI controller\n");
+       qspi = spi_controller_get_devdata(ctlr);
+-      platform_set_drvdata(pdev, qspi);
++      platform_set_drvdata(pdev, ctlr);
+       qspi->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(qspi->regs))
+@@ -545,7 +545,7 @@ static int mchp_coreqspi_probe(struct pl
+                         SPI_TX_DUAL | SPI_TX_QUAD;
+       ctlr->dev.of_node = np;
+-      ret = devm_spi_register_controller(&pdev->dev, ctlr);
++      ret = spi_register_controller(ctlr);
+       if (ret)
+               return dev_err_probe(&pdev->dev, ret,
+                                    "spi_register_controller failed\n");
+@@ -555,9 +555,13 @@ static int mchp_coreqspi_probe(struct pl
+ static void mchp_coreqspi_remove(struct platform_device *pdev)
+ {
+-      struct mchp_coreqspi *qspi = platform_get_drvdata(pdev);
+-      u32 control = readl_relaxed(qspi->regs + REG_CONTROL);
++      struct spi_controller *ctlr = platform_get_drvdata(pdev);
++      struct mchp_coreqspi *qspi = spi_controller_get_devdata(ctlr);
++      u32 control;
++      spi_unregister_controller(ctlr);
++
++      control = readl_relaxed(qspi->regs + REG_CONTROL);
+       mchp_coreqspi_disable_ints(qspi);
+       control &= ~CONTROL_ENABLE;
+       writel_relaxed(control, qspi->regs + REG_CONTROL);
diff --git a/queue-6.1/spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch b/queue-6.1/spi-microchip-core-qspi-use-helper-function-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..22e7aeb
--- /dev/null
@@ -0,0 +1,96 @@
+From stable+bounces-247279-greg=kroah.com@vger.kernel.org Fri May 15 00:23:01 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 14:50:13 -0400
+Subject: spi: microchip-core-qspi: Use helper function devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Li Zetao <lizetao1@huawei.com>, Jonathan Cameron <Jonathan.Cameron@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514185014.948789-2-sashal@kernel.org>
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ Upstream commit e922f3fff21445117e9196bd8e940ad8e15ca8c7 ]
+
+Since commit 7ef9651e9792 ("clk: Provide new devm_clk helpers for prepared
+and enabled clocks"), devm_clk_get() and clk_prepare_enable() can now be
+replaced by devm_clk_get_enabled() when driver enables (and possibly
+prepares) the clocks for the whole lifetime of the device. Moreover, it is
+no longer necessary to unprepare and disable the clocks explicitly.
+
+Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
+Signed-off-by: Li Zetao <lizetao1@huawei.com>
+Link: https://lore.kernel.org/r/20230823133938.1359106-18-lizetao1@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: e6464140d439 ("spi: microchip-core-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-microchip-core-qspi.c |   29 +++++++----------------------
+ 1 file changed, 7 insertions(+), 22 deletions(-)
+
+--- a/drivers/spi/spi-microchip-core-qspi.c
++++ b/drivers/spi/spi-microchip-core-qspi.c
+@@ -519,30 +519,23 @@ static int mchp_coreqspi_probe(struct pl
+               return dev_err_probe(&pdev->dev, PTR_ERR(qspi->regs),
+                                    "failed to map registers\n");
+-      qspi->clk = devm_clk_get(&pdev->dev, NULL);
++      qspi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(qspi->clk))
+               return dev_err_probe(&pdev->dev, PTR_ERR(qspi->clk),
+                                    "could not get clock\n");
+-      ret = clk_prepare_enable(qspi->clk);
+-      if (ret)
+-              return dev_err_probe(&pdev->dev, ret,
+-                                   "failed to enable clock\n");
+-
+       init_completion(&qspi->data_completion);
+       mutex_init(&qspi->op_lock);
+       qspi->irq = platform_get_irq(pdev, 0);
+-      if (qspi->irq < 0) {
+-              ret = qspi->irq;
+-              goto out;
+-      }
++      if (qspi->irq < 0)
++              return qspi->irq;
+       ret = devm_request_irq(&pdev->dev, qspi->irq, mchp_coreqspi_isr,
+                              IRQF_SHARED, pdev->name, qspi);
+       if (ret) {
+               dev_err(&pdev->dev, "request_irq failed %d\n", ret);
+-              goto out;
++              return ret;
+       }
+       ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+@@ -553,18 +546,11 @@ static int mchp_coreqspi_probe(struct pl
+       ctlr->dev.of_node = np;
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
+-      if (ret) {
+-              dev_err_probe(&pdev->dev, ret,
+-                            "spi_register_controller failed\n");
+-              goto out;
+-      }
++      if (ret)
++              return dev_err_probe(&pdev->dev, ret,
++                                   "spi_register_controller failed\n");
+       return 0;
+-
+-out:
+-      clk_disable_unprepare(qspi->clk);
+-
+-      return ret;
+ }
+ static void mchp_coreqspi_remove(struct platform_device *pdev)
+@@ -575,7 +561,6 @@ static void mchp_coreqspi_remove(struct
+       mchp_coreqspi_disable_ints(qspi);
+       control &= ~CONTROL_ENABLE;
+       writel_relaxed(control, qspi->regs + REG_CONTROL);
+-      clk_disable_unprepare(qspi->clk);
+ }
+ static const struct of_device_id mchp_coreqspi_of_match[] = {
diff --git a/queue-6.1/spi-qup-fix-error-pointer-deref-after-dma-setup-failure.patch b/queue-6.1/spi-qup-fix-error-pointer-deref-after-dma-setup-failure.patch
new file mode 100644 (file)
index 0000000..bfd719d
--- /dev/null
@@ -0,0 +1,47 @@
+From stable+bounces-259389-greg=kroah.com@vger.kernel.org Mon Jun  1 06:10:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 May 2026 20:38:30 -0400
+Subject: spi: qup: fix error pointer deref after DMA setup failure
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601003830.82222-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit a7e8f3efd50a165ba0189f6dc57f7e51a7d149db ]
+
+The driver falls back to PIO mode if DMA setup fails during probe.
+
+Make sure to the clear the DMA channel pointers on setup failure to
+avoid dereferencing an error pointer (or attempting to release a channel
+a second time) on later probe errors or driver unbind.
+
+This issue was flagged by Sashiko when reviewing a devres allocation
+conversion patch.
+
+Fixes: 612762e82ae6 ("spi: qup: Add DMA capabilities")
+Link: https://sashiko.dev/#/patchset/20260505072909.618363-1-johan%40kernel.org?part=4
+Cc: stable@vger.kernel.org     # 4.1
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260512074334.914735-1-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-qup.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -968,8 +968,11 @@ static int spi_qup_init_dma(struct spi_c
+ err:
+       dma_release_channel(host->dma_tx);
++      host->dma_tx = NULL;
+ err_tx:
+       dma_release_channel(host->dma_rx);
++      host->dma_rx = NULL;
++
+       return ret;
+ }
diff --git a/queue-6.1/spi-qup-switch-to-use-modern-name.patch b/queue-6.1/spi-qup-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..ef4d0d7
--- /dev/null
@@ -0,0 +1,463 @@
+From stable+bounces-259390-greg=kroah.com@vger.kernel.org Mon Jun  1 06:10:48 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 31 May 2026 20:38:29 -0400
+Subject: spi: qup: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260601003830.82222-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 597442ff4f6226206b7cc28b86eb2be0ae9c6418 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://lore.kernel.org/r/20230818093154.1183529-10-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: a7e8f3efd50a ("spi: qup: fix error pointer deref after DMA setup failure")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-qup.c |  168 +++++++++++++++++++++++++-------------------------
+ 1 file changed, 84 insertions(+), 84 deletions(-)
+
+--- a/drivers/spi/spi-qup.c
++++ b/drivers/spi/spi-qup.c
+@@ -386,20 +386,20 @@ static void spi_qup_write(struct spi_qup
+       } while (remainder);
+ }
+-static int spi_qup_prep_sg(struct spi_master *master, struct scatterlist *sgl,
++static int spi_qup_prep_sg(struct spi_controller *host, struct scatterlist *sgl,
+                          unsigned int nents, enum dma_transfer_direction dir,
+                          dma_async_tx_callback callback)
+ {
+-      struct spi_qup *qup = spi_master_get_devdata(master);
++      struct spi_qup *qup = spi_controller_get_devdata(host);
+       unsigned long flags = DMA_PREP_INTERRUPT | DMA_PREP_FENCE;
+       struct dma_async_tx_descriptor *desc;
+       struct dma_chan *chan;
+       dma_cookie_t cookie;
+       if (dir == DMA_MEM_TO_DEV)
+-              chan = master->dma_tx;
++              chan = host->dma_tx;
+       else
+-              chan = master->dma_rx;
++              chan = host->dma_rx;
+       desc = dmaengine_prep_slave_sg(chan, sgl, nents, dir, flags);
+       if (IS_ERR_OR_NULL(desc))
+@@ -413,13 +413,13 @@ static int spi_qup_prep_sg(struct spi_ma
+       return dma_submit_error(cookie);
+ }
+-static void spi_qup_dma_terminate(struct spi_master *master,
++static void spi_qup_dma_terminate(struct spi_controller *host,
+                                 struct spi_transfer *xfer)
+ {
+       if (xfer->tx_buf)
+-              dmaengine_terminate_all(master->dma_tx);
++              dmaengine_terminate_all(host->dma_tx);
+       if (xfer->rx_buf)
+-              dmaengine_terminate_all(master->dma_rx);
++              dmaengine_terminate_all(host->dma_rx);
+ }
+ static u32 spi_qup_sgl_get_nents_len(struct scatterlist *sgl, u32 max,
+@@ -446,8 +446,8 @@ static int spi_qup_do_dma(struct spi_dev
+                         unsigned long timeout)
+ {
+       dma_async_tx_callback rx_done = NULL, tx_done = NULL;
+-      struct spi_master *master = spi->master;
+-      struct spi_qup *qup = spi_master_get_devdata(master);
++      struct spi_controller *host = spi->controller;
++      struct spi_qup *qup = spi_controller_get_devdata(host);
+       struct scatterlist *tx_sgl, *rx_sgl;
+       int ret;
+@@ -482,20 +482,20 @@ static int spi_qup_do_dma(struct spi_dev
+                       return ret;
+               }
+               if (rx_sgl) {
+-                      ret = spi_qup_prep_sg(master, rx_sgl, rx_nents,
++                      ret = spi_qup_prep_sg(host, rx_sgl, rx_nents,
+                                             DMA_DEV_TO_MEM, rx_done);
+                       if (ret)
+                               return ret;
+-                      dma_async_issue_pending(master->dma_rx);
++                      dma_async_issue_pending(host->dma_rx);
+               }
+               if (tx_sgl) {
+-                      ret = spi_qup_prep_sg(master, tx_sgl, tx_nents,
++                      ret = spi_qup_prep_sg(host, tx_sgl, tx_nents,
+                                             DMA_MEM_TO_DEV, tx_done);
+                       if (ret)
+                               return ret;
+-                      dma_async_issue_pending(master->dma_tx);
++                      dma_async_issue_pending(host->dma_tx);
+               }
+               if (!wait_for_completion_timeout(&qup->done, timeout))
+@@ -514,8 +514,8 @@ static int spi_qup_do_dma(struct spi_dev
+ static int spi_qup_do_pio(struct spi_device *spi, struct spi_transfer *xfer,
+                         unsigned long timeout)
+ {
+-      struct spi_master *master = spi->master;
+-      struct spi_qup *qup = spi_master_get_devdata(master);
++      struct spi_controller *host = spi->controller;
++      struct spi_qup *qup = spi_controller_get_devdata(host);
+       int ret, n_words, iterations, offset = 0;
+       n_words = qup->n_words;
+@@ -659,7 +659,7 @@ static irqreturn_t spi_qup_qup_irq(int i
+ /* set clock freq ... bits per word, determine mode */
+ static int spi_qup_io_prep(struct spi_device *spi, struct spi_transfer *xfer)
+ {
+-      struct spi_qup *controller = spi_master_get_devdata(spi->master);
++      struct spi_qup *controller = spi_controller_get_devdata(spi->controller);
+       int ret;
+       if (spi->mode & SPI_LOOP && xfer->len > controller->in_fifo_sz) {
+@@ -680,9 +680,9 @@ static int spi_qup_io_prep(struct spi_de
+       if (controller->n_words <= (controller->in_fifo_sz / sizeof(u32)))
+               controller->mode = QUP_IO_M_MODE_FIFO;
+-      else if (spi->master->can_dma &&
+-               spi->master->can_dma(spi->master, spi, xfer) &&
+-               spi->master->cur_msg_mapped)
++      else if (spi->controller->can_dma &&
++               spi->controller->can_dma(spi->controller, spi, xfer) &&
++               spi->controller->cur_msg_mapped)
+               controller->mode = QUP_IO_M_MODE_BAM;
+       else
+               controller->mode = QUP_IO_M_MODE_BLOCK;
+@@ -693,7 +693,7 @@ static int spi_qup_io_prep(struct spi_de
+ /* prep qup for another spi transaction of specific type */
+ static int spi_qup_io_config(struct spi_device *spi, struct spi_transfer *xfer)
+ {
+-      struct spi_qup *controller = spi_master_get_devdata(spi->master);
++      struct spi_qup *controller = spi_controller_get_devdata(spi->controller);
+       u32 config, iomode, control;
+       unsigned long flags;
+@@ -841,11 +841,11 @@ static int spi_qup_io_config(struct spi_
+       return 0;
+ }
+-static int spi_qup_transfer_one(struct spi_master *master,
++static int spi_qup_transfer_one(struct spi_controller *host,
+                             struct spi_device *spi,
+                             struct spi_transfer *xfer)
+ {
+-      struct spi_qup *controller = spi_master_get_devdata(master);
++      struct spi_qup *controller = spi_controller_get_devdata(host);
+       unsigned long timeout, flags;
+       int ret;
+@@ -879,21 +879,21 @@ static int spi_qup_transfer_one(struct s
+       spin_unlock_irqrestore(&controller->lock, flags);
+       if (ret && spi_qup_is_dma_xfer(controller->mode))
+-              spi_qup_dma_terminate(master, xfer);
++              spi_qup_dma_terminate(host, xfer);
+       return ret;
+ }
+-static bool spi_qup_can_dma(struct spi_master *master, struct spi_device *spi,
++static bool spi_qup_can_dma(struct spi_controller *host, struct spi_device *spi,
+                           struct spi_transfer *xfer)
+ {
+-      struct spi_qup *qup = spi_master_get_devdata(master);
++      struct spi_qup *qup = spi_controller_get_devdata(host);
+       size_t dma_align = dma_get_cache_alignment();
+       int n_words;
+       if (xfer->rx_buf) {
+               if (!IS_ALIGNED((size_t)xfer->rx_buf, dma_align) ||
+-                  IS_ERR_OR_NULL(master->dma_rx))
++                  IS_ERR_OR_NULL(host->dma_rx))
+                       return false;
+               if (qup->qup_v1 && (xfer->len % qup->in_blk_sz))
+                       return false;
+@@ -901,7 +901,7 @@ static bool spi_qup_can_dma(struct spi_m
+       if (xfer->tx_buf) {
+               if (!IS_ALIGNED((size_t)xfer->tx_buf, dma_align) ||
+-                  IS_ERR_OR_NULL(master->dma_tx))
++                  IS_ERR_OR_NULL(host->dma_tx))
+                       return false;
+               if (qup->qup_v1 && (xfer->len % qup->out_blk_sz))
+                       return false;
+@@ -914,30 +914,30 @@ static bool spi_qup_can_dma(struct spi_m
+       return true;
+ }
+-static void spi_qup_release_dma(struct spi_master *master)
++static void spi_qup_release_dma(struct spi_controller *host)
+ {
+-      if (!IS_ERR_OR_NULL(master->dma_rx))
+-              dma_release_channel(master->dma_rx);
+-      if (!IS_ERR_OR_NULL(master->dma_tx))
+-              dma_release_channel(master->dma_tx);
++      if (!IS_ERR_OR_NULL(host->dma_rx))
++              dma_release_channel(host->dma_rx);
++      if (!IS_ERR_OR_NULL(host->dma_tx))
++              dma_release_channel(host->dma_tx);
+ }
+-static int spi_qup_init_dma(struct spi_master *master, resource_size_t base)
++static int spi_qup_init_dma(struct spi_controller *host, resource_size_t base)
+ {
+-      struct spi_qup *spi = spi_master_get_devdata(master);
++      struct spi_qup *spi = spi_controller_get_devdata(host);
+       struct dma_slave_config *rx_conf = &spi->rx_conf,
+                               *tx_conf = &spi->tx_conf;
+       struct device *dev = spi->dev;
+       int ret;
+       /* allocate dma resources, if available */
+-      master->dma_rx = dma_request_chan(dev, "rx");
+-      if (IS_ERR(master->dma_rx))
+-              return PTR_ERR(master->dma_rx);
+-
+-      master->dma_tx = dma_request_chan(dev, "tx");
+-      if (IS_ERR(master->dma_tx)) {
+-              ret = PTR_ERR(master->dma_tx);
++      host->dma_rx = dma_request_chan(dev, "rx");
++      if (IS_ERR(host->dma_rx))
++              return PTR_ERR(host->dma_rx);
++
++      host->dma_tx = dma_request_chan(dev, "tx");
++      if (IS_ERR(host->dma_tx)) {
++              ret = PTR_ERR(host->dma_tx);
+               goto err_tx;
+       }
+@@ -952,13 +952,13 @@ static int spi_qup_init_dma(struct spi_m
+       tx_conf->dst_addr = base + QUP_OUTPUT_FIFO;
+       tx_conf->dst_maxburst = spi->out_blk_sz;
+-      ret = dmaengine_slave_config(master->dma_rx, rx_conf);
++      ret = dmaengine_slave_config(host->dma_rx, rx_conf);
+       if (ret) {
+               dev_err(dev, "failed to configure RX channel\n");
+               goto err;
+       }
+-      ret = dmaengine_slave_config(master->dma_tx, tx_conf);
++      ret = dmaengine_slave_config(host->dma_tx, tx_conf);
+       if (ret) {
+               dev_err(dev, "failed to configure TX channel\n");
+               goto err;
+@@ -967,9 +967,9 @@ static int spi_qup_init_dma(struct spi_m
+       return 0;
+ err:
+-      dma_release_channel(master->dma_tx);
++      dma_release_channel(host->dma_tx);
+ err_tx:
+-      dma_release_channel(master->dma_rx);
++      dma_release_channel(host->dma_rx);
+       return ret;
+ }
+@@ -979,7 +979,7 @@ static void spi_qup_set_cs(struct spi_de
+       u32 spi_ioc;
+       u32 spi_ioc_orig;
+-      controller = spi_master_get_devdata(spi->master);
++      controller = spi_controller_get_devdata(spi->controller);
+       spi_ioc = readl_relaxed(controller->base + SPI_IO_CONTROL);
+       spi_ioc_orig = spi_ioc;
+       if (!val)
+@@ -993,7 +993,7 @@ static void spi_qup_set_cs(struct spi_de
+ static int spi_qup_probe(struct platform_device *pdev)
+ {
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct clk *iclk, *cclk;
+       struct spi_qup *controller;
+       struct resource *res;
+@@ -1029,34 +1029,34 @@ static int spi_qup_probe(struct platform
+               return -ENXIO;
+       }
+-      master = spi_alloc_master(dev, sizeof(struct spi_qup));
+-      if (!master) {
+-              dev_err(dev, "cannot allocate master\n");
++      host = spi_alloc_host(dev, sizeof(struct spi_qup));
++      if (!host) {
++              dev_err(dev, "cannot allocate host\n");
+               return -ENOMEM;
+       }
+       /* use num-cs unless not present or out of range */
+       if (of_property_read_u32(dev->of_node, "num-cs", &num_cs) ||
+           num_cs > SPI_NUM_CHIPSELECTS)
+-              master->num_chipselect = SPI_NUM_CHIPSELECTS;
++              host->num_chipselect = SPI_NUM_CHIPSELECTS;
+       else
+-              master->num_chipselect = num_cs;
++              host->num_chipselect = num_cs;
+-      master->use_gpio_descriptors = true;
+-      master->max_native_cs = SPI_NUM_CHIPSELECTS;
+-      master->bus_num = pdev->id;
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
+-      master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
+-      master->max_speed_hz = max_freq;
+-      master->transfer_one = spi_qup_transfer_one;
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->auto_runtime_pm = true;
+-      master->dma_alignment = dma_get_cache_alignment();
+-      master->max_dma_len = SPI_MAX_XFER;
++      host->use_gpio_descriptors = true;
++      host->max_native_cs = SPI_NUM_CHIPSELECTS;
++      host->bus_num = pdev->id;
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP;
++      host->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
++      host->max_speed_hz = max_freq;
++      host->transfer_one = spi_qup_transfer_one;
++      host->dev.of_node = pdev->dev.of_node;
++      host->auto_runtime_pm = true;
++      host->dma_alignment = dma_get_cache_alignment();
++      host->max_dma_len = SPI_MAX_XFER;
+-      platform_set_drvdata(pdev, master);
++      platform_set_drvdata(pdev, host);
+-      controller = spi_master_get_devdata(master);
++      controller = spi_controller_get_devdata(host);
+       controller->dev = dev;
+       controller->base = base;
+@@ -1064,16 +1064,16 @@ static int spi_qup_probe(struct platform
+       controller->cclk = cclk;
+       controller->irq = irq;
+-      ret = spi_qup_init_dma(master, res->start);
++      ret = spi_qup_init_dma(host, res->start);
+       if (ret == -EPROBE_DEFER)
+               goto error;
+       else if (!ret)
+-              master->can_dma = spi_qup_can_dma;
++              host->can_dma = spi_qup_can_dma;
+       controller->qup_v1 = (uintptr_t)of_device_get_match_data(dev);
+       if (!controller->qup_v1)
+-              master->set_cs = spi_qup_set_cs;
++              host->set_cs = spi_qup_set_cs;
+       spin_lock_init(&controller->lock);
+       init_completion(&controller->done);
+@@ -1151,7 +1151,7 @@ static int spi_qup_probe(struct platform
+       pm_runtime_set_active(dev);
+       pm_runtime_enable(dev);
+-      ret = devm_spi_register_master(dev, master);
++      ret = devm_spi_register_controller(dev, host);
+       if (ret)
+               goto disable_pm;
+@@ -1163,17 +1163,17 @@ error_clk:
+       clk_disable_unprepare(cclk);
+       clk_disable_unprepare(iclk);
+ error_dma:
+-      spi_qup_release_dma(master);
++      spi_qup_release_dma(host);
+ error:
+-      spi_master_put(master);
++      spi_controller_put(host);
+       return ret;
+ }
+ #ifdef CONFIG_PM
+ static int spi_qup_pm_suspend_runtime(struct device *device)
+ {
+-      struct spi_master *master = dev_get_drvdata(device);
+-      struct spi_qup *controller = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(device);
++      struct spi_qup *controller = spi_controller_get_devdata(host);
+       u32 config;
+       /* Enable clocks auto gaiting */
+@@ -1189,8 +1189,8 @@ static int spi_qup_pm_suspend_runtime(st
+ static int spi_qup_pm_resume_runtime(struct device *device)
+ {
+-      struct spi_master *master = dev_get_drvdata(device);
+-      struct spi_qup *controller = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(device);
++      struct spi_qup *controller = spi_controller_get_devdata(host);
+       u32 config;
+       int ret;
+@@ -1215,8 +1215,8 @@ static int spi_qup_pm_resume_runtime(str
+ #ifdef CONFIG_PM_SLEEP
+ static int spi_qup_suspend(struct device *device)
+ {
+-      struct spi_master *master = dev_get_drvdata(device);
+-      struct spi_qup *controller = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(device);
++      struct spi_qup *controller = spi_controller_get_devdata(host);
+       int ret;
+       if (pm_runtime_suspended(device)) {
+@@ -1224,7 +1224,7 @@ static int spi_qup_suspend(struct device
+               if (ret)
+                       return ret;
+       }
+-      ret = spi_master_suspend(master);
++      ret = spi_controller_suspend(host);
+       if (ret)
+               return ret;
+@@ -1239,8 +1239,8 @@ static int spi_qup_suspend(struct device
+ static int spi_qup_resume(struct device *device)
+ {
+-      struct spi_master *master = dev_get_drvdata(device);
+-      struct spi_qup *controller = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(device);
++      struct spi_qup *controller = spi_controller_get_devdata(host);
+       int ret;
+       ret = clk_prepare_enable(controller->iclk);
+@@ -1257,7 +1257,7 @@ static int spi_qup_resume(struct device
+       if (ret)
+               goto disable_clk;
+-      ret = spi_master_resume(master);
++      ret = spi_controller_resume(host);
+       if (ret)
+               goto disable_clk;
+@@ -1272,8 +1272,8 @@ disable_clk:
+ static int spi_qup_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = dev_get_drvdata(&pdev->dev);
+-      struct spi_qup *controller = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(&pdev->dev);
++      struct spi_qup *controller = spi_controller_get_devdata(host);
+       int ret;
+       ret = pm_runtime_get_sync(&pdev->dev);
+@@ -1291,7 +1291,7 @@ static int spi_qup_remove(struct platfor
+                        ERR_PTR(ret));
+       }
+-      spi_qup_release_dma(master);
++      spi_qup_release_dma(host);
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
diff --git a/queue-6.1/spi-s3c64xx-fix-null-deref-on-driver-unbind.patch b/queue-6.1/spi-s3c64xx-fix-null-deref-on-driver-unbind.patch
new file mode 100644 (file)
index 0000000..c86faf5
--- /dev/null
@@ -0,0 +1,49 @@
+From stable+bounces-247118-greg=kroah.com@vger.kernel.org Thu May 14 10:51:05 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 01:20:32 -0400
+Subject: spi: s3c64xx: fix NULL-deref on driver unbind
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Adithya K V <adithya.kv@samsung.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514052032.41196-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 45daacbead8a009844bd5dba6cfa731332184d17 ]
+
+A change moving DMA channel allocation from probe() back to
+s3c64xx_spi_prepare_transfer() failed to remove the corresponding
+deallocation from remove().
+
+Drop the bogus DMA channel release from remove() to avoid triggering a
+NULL-pointer dereference on driver unbind.
+
+This issue was flagged by Sashiko when reviewing a controller
+deregistration fix.
+
+Fixes: f52b03c70744 ("spi: s3c64xx: requests spi-dma channel only during data transfer")
+Cc: stable@vger.kernel.org     # 6.0
+Cc: Adithya K V <adithya.kv@samsung.com>
+Link: https://sashiko.dev/#/patchset/20260410081757.503099-1-johan%40kernel.org
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410094925.518343-1-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-s3c64xx.c |    5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -1274,11 +1274,6 @@ static int s3c64xx_spi_remove(struct pla
+       writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
+-      if (!is_polling(sdd)) {
+-              dma_release_channel(sdd->rx_dma.ch);
+-              dma_release_channel(sdd->tx_dma.ch);
+-      }
+-
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
diff --git a/queue-6.1/spi-s3c64xx-use-devm_clk_get_enabled.patch b/queue-6.1/spi-s3c64xx-use-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..49fd952
--- /dev/null
@@ -0,0 +1,104 @@
+From stable+bounces-247117-greg=kroah.com@vger.kernel.org Thu May 14 10:50:39 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 01:20:31 -0400
+Subject: spi: s3c64xx: Use devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Andi Shyti <andi.shyti@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514052032.41196-1-sashal@kernel.org>
+
+From: Andi Shyti <andi.shyti@kernel.org>
+
+[ Upstream commit 20c475d21ed9326f7b1396c9bb8991b375cb6c50 ]
+
+Replace the tuple devm_clk_get()/clk_prepare_enable() with the
+single function devm_clk_get_enabled().
+
+Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
+Link: https://lore.kernel.org/r/20230531205550.568340-1-andi.shyti@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 45daacbead8a ("spi: s3c64xx: fix NULL-deref on driver unbind")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-s3c64xx.c |   39 +++++----------------------------------
+ 1 file changed, 5 insertions(+), 34 deletions(-)
+
+--- a/drivers/spi/spi-s3c64xx.c
++++ b/drivers/spi/spi-s3c64xx.c
+@@ -1189,46 +1189,28 @@ static int s3c64xx_spi_probe(struct plat
+       }
+       /* Setup clocks */
+-      sdd->clk = devm_clk_get(&pdev->dev, "spi");
++      sdd->clk = devm_clk_get_enabled(&pdev->dev, "spi");
+       if (IS_ERR(sdd->clk)) {
+               dev_err(&pdev->dev, "Unable to acquire clock 'spi'\n");
+               ret = PTR_ERR(sdd->clk);
+               goto err_deref_master;
+       }
+-      ret = clk_prepare_enable(sdd->clk);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Couldn't enable clock 'spi'\n");
+-              goto err_deref_master;
+-      }
+-
+       sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr);
+-      sdd->src_clk = devm_clk_get(&pdev->dev, clk_name);
++      sdd->src_clk = devm_clk_get_enabled(&pdev->dev, clk_name);
+       if (IS_ERR(sdd->src_clk)) {
+               dev_err(&pdev->dev,
+                       "Unable to acquire clock '%s'\n", clk_name);
+               ret = PTR_ERR(sdd->src_clk);
+-              goto err_disable_clk;
+-      }
+-
+-      ret = clk_prepare_enable(sdd->src_clk);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Couldn't enable clock '%s'\n", clk_name);
+-              goto err_disable_clk;
++              goto err_deref_master;
+       }
+       if (sdd->port_conf->clk_ioclk) {
+-              sdd->ioclk = devm_clk_get(&pdev->dev, "spi_ioclk");
++              sdd->ioclk = devm_clk_get_enabled(&pdev->dev, "spi_ioclk");
+               if (IS_ERR(sdd->ioclk)) {
+                       dev_err(&pdev->dev, "Unable to acquire 'ioclk'\n");
+                       ret = PTR_ERR(sdd->ioclk);
+-                      goto err_disable_src_clk;
+-              }
+-
+-              ret = clk_prepare_enable(sdd->ioclk);
+-              if (ret) {
+-                      dev_err(&pdev->dev, "Couldn't enable clock 'ioclk'\n");
+-                      goto err_disable_src_clk;
++                      goto err_deref_master;
+               }
+       }
+@@ -1277,11 +1259,6 @@ err_pm_put:
+       pm_runtime_disable(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
+-      clk_disable_unprepare(sdd->ioclk);
+-err_disable_src_clk:
+-      clk_disable_unprepare(sdd->src_clk);
+-err_disable_clk:
+-      clk_disable_unprepare(sdd->clk);
+ err_deref_master:
+       spi_master_put(master);
+@@ -1302,12 +1279,6 @@ static int s3c64xx_spi_remove(struct pla
+               dma_release_channel(sdd->tx_dma.ch);
+       }
+-      clk_disable_unprepare(sdd->ioclk);
+-
+-      clk_disable_unprepare(sdd->src_clk);
+-
+-      clk_disable_unprepare(sdd->clk);
+-
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
diff --git a/queue-6.1/spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/spi-spi-ti-qspi-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..dc269c1
--- /dev/null
@@ -0,0 +1,76 @@
+From stable+bounces-247004-greg=kroah.com@vger.kernel.org Wed May 13 23:56:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:20:15 -0400
+Subject: spi: spi-ti-qspi: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513182017.3918352-2-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 2f2802d1a59d79a3d00cb429841db502c2bbc3df ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is ignored (apart
+from emitting a warning) and this typically results in resource leaks.
+
+To improve here there is a quest to make the remove callback return
+void. In the first step of this quest all drivers are converted to
+.remove_new(), which already returns void. Eventually after all drivers
+are converted, .remove_new() will be renamed to .remove().
+
+Add an error message to the error path that returned an error before to
+replace the core's error message with more information. Apart from the
+different wording of the error message, this patch doesn't introduce a
+semantic difference.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20231105172649.3738556-2-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0c18a1bacbb1 ("spi: ti-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-ti-qspi.c |   13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -909,21 +909,22 @@ free_master:
+       return ret;
+ }
+-static int ti_qspi_remove(struct platform_device *pdev)
++static void ti_qspi_remove(struct platform_device *pdev)
+ {
+       struct ti_qspi *qspi = platform_get_drvdata(pdev);
+       int rc;
+       rc = spi_master_suspend(qspi->master);
+-      if (rc)
+-              return rc;
++      if (rc) {
++              dev_alert(&pdev->dev, "spi_master_suspend() failed (%pe)\n",
++                        ERR_PTR(rc));
++              return;
++      }
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       ti_qspi_dma_cleanup(qspi);
+-
+-      return 0;
+ }
+ static const struct dev_pm_ops ti_qspi_pm_ops = {
+@@ -932,7 +933,7 @@ static const struct dev_pm_ops ti_qspi_p
+ static struct platform_driver ti_qspi_driver = {
+       .probe  = ti_qspi_probe,
+-      .remove = ti_qspi_remove,
++      .remove_new = ti_qspi_remove,
+       .driver = {
+               .name   = "ti-qspi",
+               .pm =   &ti_qspi_pm_ops,
diff --git a/queue-6.1/spi-spi-ti-qspi-switch-to-use-modern-name.patch b/queue-6.1/spi-spi-ti-qspi-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..ad8fe45
--- /dev/null
@@ -0,0 +1,293 @@
+From stable+bounces-247005-greg=kroah.com@vger.kernel.org Wed May 13 23:56:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:20:16 -0400
+Subject: spi: spi-ti-qspi: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513182017.3918352-3-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 9d93c8d97b4cdb5edddb4c5530881c90eecb7e44 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-16-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0c18a1bacbb1 ("spi: ti-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-ti-qspi.c |   88 +++++++++++++++++++++++-----------------------
+ 1 file changed, 44 insertions(+), 44 deletions(-)
+
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -41,7 +41,7 @@ struct ti_qspi {
+       /* list synchronization */
+       struct mutex            list_lock;
+-      struct spi_master       *master;
++      struct spi_controller   *host;
+       void __iomem            *base;
+       void __iomem            *mmap_base;
+       size_t                  mmap_size;
+@@ -138,20 +138,20 @@ static inline void ti_qspi_write(struct
+ static int ti_qspi_setup(struct spi_device *spi)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       int ret;
+-      if (spi->master->busy) {
+-              dev_dbg(qspi->dev, "master busy doing other transfers\n");
++      if (spi->controller->busy) {
++              dev_dbg(qspi->dev, "host busy doing other transfers\n");
+               return -EBUSY;
+       }
+-      if (!qspi->master->max_speed_hz) {
++      if (!qspi->host->max_speed_hz) {
+               dev_err(qspi->dev, "spi max frequency not defined\n");
+               return -EINVAL;
+       }
+-      spi->max_speed_hz = min(spi->max_speed_hz, qspi->master->max_speed_hz);
++      spi->max_speed_hz = min(spi->max_speed_hz, qspi->host->max_speed_hz);
+       ret = pm_runtime_resume_and_get(qspi->dev);
+       if (ret < 0) {
+@@ -527,7 +527,7 @@ static int ti_qspi_dma_xfer_sg(struct ti
+ static void ti_qspi_enable_memory_map(struct spi_device *spi)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       ti_qspi_write(qspi, MM_SWITCH, QSPI_SPI_SWITCH_REG);
+       if (qspi->ctrl_base) {
+@@ -541,7 +541,7 @@ static void ti_qspi_enable_memory_map(st
+ static void ti_qspi_disable_memory_map(struct spi_device *spi)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       ti_qspi_write(qspi, 0, QSPI_SPI_SWITCH_REG);
+       if (qspi->ctrl_base)
+@@ -555,7 +555,7 @@ static void ti_qspi_setup_mmap_read(stru
+                                   u8 data_nbits, u8 addr_width,
+                                   u8 dummy_bytes)
+ {
+-      struct ti_qspi  *qspi = spi_master_get_devdata(spi->master);
++      struct ti_qspi  *qspi = spi_controller_get_devdata(spi->controller);
+       u32 memval = opcode;
+       switch (data_nbits) {
+@@ -577,7 +577,7 @@ static void ti_qspi_setup_mmap_read(stru
+ static int ti_qspi_adjust_op_size(struct spi_mem *mem, struct spi_mem_op *op)
+ {
+-      struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->master);
++      struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->controller);
+       size_t max_len;
+       if (op->data.dir == SPI_MEM_DATA_IN) {
+@@ -607,7 +607,7 @@ static int ti_qspi_adjust_op_size(struct
+ static int ti_qspi_exec_mem_op(struct spi_mem *mem,
+                              const struct spi_mem_op *op)
+ {
+-      struct ti_qspi *qspi = spi_master_get_devdata(mem->spi->master);
++      struct ti_qspi *qspi = spi_controller_get_devdata(mem->spi->controller);
+       u32 from = 0;
+       int ret = 0;
+@@ -634,10 +634,10 @@ static int ti_qspi_exec_mem_op(struct sp
+               struct sg_table sgt;
+               if (virt_addr_valid(op->data.buf.in) &&
+-                  !spi_controller_dma_map_mem_op_data(mem->spi->master, op,
++                  !spi_controller_dma_map_mem_op_data(mem->spi->controller, op,
+                                                       &sgt)) {
+                       ret = ti_qspi_dma_xfer_sg(qspi, sgt, from);
+-                      spi_controller_dma_unmap_mem_op_data(mem->spi->master,
++                      spi_controller_dma_unmap_mem_op_data(mem->spi->controller,
+                                                            op, &sgt);
+               } else {
+                       ret = ti_qspi_dma_bounce_buffer(qspi, from,
+@@ -659,10 +659,10 @@ static const struct spi_controller_mem_o
+       .adjust_op_size = ti_qspi_adjust_op_size,
+ };
+-static int ti_qspi_start_transfer_one(struct spi_master *master,
++static int ti_qspi_start_transfer_one(struct spi_controller *host,
+               struct spi_message *m)
+ {
+-      struct ti_qspi *qspi = spi_master_get_devdata(master);
++      struct ti_qspi *qspi = spi_controller_get_devdata(host);
+       struct spi_device *spi = m->spi;
+       struct spi_transfer *t;
+       int status = 0, ret;
+@@ -721,7 +721,7 @@ static int ti_qspi_start_transfer_one(st
+       ti_qspi_write(qspi, qspi->cmd | QSPI_INVAL, QSPI_SPI_CMD_REG);
+       m->status = status;
+-      spi_finalize_current_message(master);
++      spi_finalize_current_message(host);
+       return status;
+ }
+@@ -757,33 +757,33 @@ MODULE_DEVICE_TABLE(of, ti_qspi_match);
+ static int ti_qspi_probe(struct platform_device *pdev)
+ {
+       struct  ti_qspi *qspi;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct resource         *r, *res_mmap;
+       struct device_node *np = pdev->dev.of_node;
+       u32 max_freq;
+       int ret = 0, num_cs, irq;
+       dma_cap_mask_t mask;
+-      master = spi_alloc_master(&pdev->dev, sizeof(*qspi));
+-      if (!master)
++      host = spi_alloc_host(&pdev->dev, sizeof(*qspi));
++      if (!host)
+               return -ENOMEM;
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD;
+-      master->flags = SPI_CONTROLLER_HALF_DUPLEX;
+-      master->setup = ti_qspi_setup;
+-      master->auto_runtime_pm = true;
+-      master->transfer_one_message = ti_qspi_start_transfer_one;
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
+-                                   SPI_BPW_MASK(8);
+-      master->mem_ops = &ti_qspi_mem_ops;
++      host->flags = SPI_CONTROLLER_HALF_DUPLEX;
++      host->setup = ti_qspi_setup;
++      host->auto_runtime_pm = true;
++      host->transfer_one_message = ti_qspi_start_transfer_one;
++      host->dev.of_node = pdev->dev.of_node;
++      host->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(16) |
++                                 SPI_BPW_MASK(8);
++      host->mem_ops = &ti_qspi_mem_ops;
+       if (!of_property_read_u32(np, "num-cs", &num_cs))
+-              master->num_chipselect = num_cs;
++              host->num_chipselect = num_cs;
+-      qspi = spi_master_get_devdata(master);
+-      qspi->master = master;
++      qspi = spi_controller_get_devdata(host);
++      qspi->host = host;
+       qspi->dev = &pdev->dev;
+       platform_set_drvdata(pdev, qspi);
+@@ -793,7 +793,7 @@ static int ti_qspi_probe(struct platform
+               if (r == NULL) {
+                       dev_err(&pdev->dev, "missing platform data\n");
+                       ret = -ENODEV;
+-                      goto free_master;
++                      goto free_host;
+               }
+       }
+@@ -813,7 +813,7 @@ static int ti_qspi_probe(struct platform
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+-              goto free_master;
++              goto free_host;
+       }
+       mutex_init(&qspi->list_lock);
+@@ -821,7 +821,7 @@ static int ti_qspi_probe(struct platform
+       qspi->base = devm_ioremap_resource(&pdev->dev, r);
+       if (IS_ERR(qspi->base)) {
+               ret = PTR_ERR(qspi->base);
+-              goto free_master;
++              goto free_host;
+       }
+@@ -831,7 +831,7 @@ static int ti_qspi_probe(struct platform
+                                               "syscon-chipselects");
+               if (IS_ERR(qspi->ctrl_base)) {
+                       ret = PTR_ERR(qspi->ctrl_base);
+-                      goto free_master;
++                      goto free_host;
+               }
+               ret = of_property_read_u32_index(np,
+                                                "syscon-chipselects",
+@@ -839,7 +839,7 @@ static int ti_qspi_probe(struct platform
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "couldn't get ctrl_mod reg index\n");
+-                      goto free_master;
++                      goto free_host;
+               }
+       }
+@@ -854,7 +854,7 @@ static int ti_qspi_probe(struct platform
+       pm_runtime_enable(&pdev->dev);
+       if (!of_property_read_u32(np, "spi-max-frequency", &max_freq))
+-              master->max_speed_hz = max_freq;
++              host->max_speed_hz = max_freq;
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_MEMCPY, mask);
+@@ -878,7 +878,7 @@ static int ti_qspi_probe(struct platform
+               qspi->rx_chan = NULL;
+               goto no_dma;
+       }
+-      master->dma_rx = qspi->rx_chan;
++      host->dma_rx = qspi->rx_chan;
+       init_completion(&qspi->transfer_complete);
+       if (res_mmap)
+               qspi->mmap_phys_base = (dma_addr_t)res_mmap->start;
+@@ -891,21 +891,21 @@ no_dma:
+                                "mmap failed with error %ld using PIO mode\n",
+                                PTR_ERR(qspi->mmap_base));
+                       qspi->mmap_base = NULL;
+-                      master->mem_ops = NULL;
++                      host->mem_ops = NULL;
+               }
+       }
+       qspi->mmap_enabled = false;
+       qspi->current_cs = -1;
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (!ret)
+               return 0;
+       ti_qspi_dma_cleanup(qspi);
+       pm_runtime_disable(&pdev->dev);
+-free_master:
+-      spi_master_put(master);
++free_host:
++      spi_controller_put(host);
+       return ret;
+ }
+@@ -914,9 +914,9 @@ static void ti_qspi_remove(struct platfo
+       struct ti_qspi *qspi = platform_get_drvdata(pdev);
+       int rc;
+-      rc = spi_master_suspend(qspi->master);
++      rc = spi_controller_suspend(qspi->host);
+       if (rc) {
+-              dev_alert(&pdev->dev, "spi_master_suspend() failed (%pe)\n",
++              dev_alert(&pdev->dev, "spi_controller_suspend() failed (%pe)\n",
+                         ERR_PTR(rc));
+               return;
+       }
diff --git a/queue-6.1/spi-spi-zynq-do-not-check-for-0-return-after-calling-platform_get_irq.patch b/queue-6.1/spi-spi-zynq-do-not-check-for-0-return-after-calling-platform_get_irq.patch
new file mode 100644 (file)
index 0000000..7495040
--- /dev/null
@@ -0,0 +1,52 @@
+From stable+bounces-247025-greg=kroah.com@vger.kernel.org Thu May 14 01:04:27 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 15:34:17 -0400
+Subject: spi: spi-zynq: Do not check for 0 return after calling platform_get_irq()
+To: stable@vger.kernel.org
+Cc: Ruan Jinjie <ruanjinjie@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513193420.3938432-2-sashal@kernel.org>
+
+From: Ruan Jinjie <ruanjinjie@huawei.com>
+
+[ Upstream commit 3182d49aad5f1cd8acdcf7de0c5b651772edd32e ]
+
+It is not possible for platform_get_irq() to return 0. Use the
+return value from platform_get_irq().
+
+Signed-off-by: Ruan Jinjie <ruanjinjie@huawei.com>
+Link: https://lore.kernel.org/r/20230802094357.981100-1-ruanjinjie@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: c9c012706c9f ("spi: zynq-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c    |    4 ++--
+ drivers/spi/spi-zynqmp-gqspi.c |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -688,8 +688,8 @@ static int zynq_qspi_probe(struct platfo
+       }
+       xqspi->irq = platform_get_irq(pdev, 0);
+-      if (xqspi->irq <= 0) {
+-              ret = -ENXIO;
++      if (xqspi->irq < 0) {
++              ret = xqspi->irq;
+               goto clk_dis_all;
+       }
+       ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq,
+--- a/drivers/spi/spi-zynqmp-gqspi.c
++++ b/drivers/spi/spi-zynqmp-gqspi.c
+@@ -1164,8 +1164,8 @@ static int zynqmp_qspi_probe(struct plat
+       zynqmp_qspi_init_hw(xqspi);
+       xqspi->irq = platform_get_irq(pdev, 0);
+-      if (xqspi->irq <= 0) {
+-              ret = -ENXIO;
++      if (xqspi->irq < 0) {
++              ret = xqspi->irq;
+               goto clk_dis_all;
+       }
+       ret = devm_request_irq(&pdev->dev, xqspi->irq, zynqmp_qspi_irq,
diff --git a/queue-6.1/spi-st-ssc4-fix-controller-deregistration.patch b/queue-6.1/spi-st-ssc4-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..c9947cf
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-249918-greg=kroah.com@vger.kernel.org Wed May 20 18:42:06 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:11:33 -0400
+Subject: spi: st-ssc4: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Lee Jones <lee@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520131133.3608592-2-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 19857374010d06ca6a2f7c2c53464122eb804df0 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: 9e862375c542 ("spi: Add new driver for STMicroelectronics' SPI Controller")
+Cc: stable@vger.kernel.org     # 4.0
+Cc: Lee Jones <lee@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-18-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-st-ssc4.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-st-ssc4.c
++++ b/drivers/spi/spi-st-ssc4.c
+@@ -349,7 +349,7 @@ static int spi_st_probe(struct platform_
+       platform_set_drvdata(pdev, host);
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (ret) {
+               dev_err(&pdev->dev, "Failed to register host\n");
+               goto rpm_disable;
+@@ -371,10 +371,16 @@ static int spi_st_remove(struct platform
+       struct spi_controller *host = platform_get_drvdata(pdev);
+       struct spi_st *spi_st = spi_controller_get_devdata(host);
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       pm_runtime_disable(&pdev->dev);
+       clk_disable_unprepare(spi_st->clk);
++      spi_controller_put(host);
++
+       pinctrl_pm_select_sleep_state(&pdev->dev);
+       return 0;
diff --git a/queue-6.1/spi-st-ssc4-switch-to-use-modern-name.patch b/queue-6.1/spi-st-ssc4-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..d227a54
--- /dev/null
@@ -0,0 +1,210 @@
+From stable+bounces-249919-greg=kroah.com@vger.kernel.org Wed May 20 18:50:13 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 May 2026 09:11:32 -0400
+Subject: spi: st-ssc4: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260520131133.3608592-1-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit e6b7e64cb11966b26646a362677ca5a08481157e ]
+
+Change legacy name master/slave to modern name host/target or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-4-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 19857374010d ("spi: st-ssc4: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-st-ssc4.c |   70 +++++++++++++++++++++++-----------------------
+ 1 file changed, 35 insertions(+), 35 deletions(-)
+
+--- a/drivers/spi/spi-st-ssc4.c
++++ b/drivers/spi/spi-st-ssc4.c
+@@ -6,7 +6,7 @@
+  *          Patrice Chotard <patrice.chotard@st.com>
+  *          Lee Jones <lee.jones@linaro.org>
+  *
+- *  SPI master mode controller driver, used in STMicroelectronics devices.
++ *  SPI host mode controller driver, used in STMicroelectronics devices.
+  */
+ #include <linux/clk.h>
+@@ -115,10 +115,10 @@ static void ssc_read_rx_fifo(struct spi_
+       spi_st->words_remaining -= count;
+ }
+-static int spi_st_transfer_one(struct spi_master *master,
++static int spi_st_transfer_one(struct spi_controller *host,
+                              struct spi_device *spi, struct spi_transfer *t)
+ {
+-      struct spi_st *spi_st = spi_master_get_devdata(master);
++      struct spi_st *spi_st = spi_controller_get_devdata(host);
+       uint32_t ctl = 0;
+       /* Setup transfer */
+@@ -165,7 +165,7 @@ static int spi_st_transfer_one(struct sp
+       if (ctl)
+               writel_relaxed(ctl, spi_st->base + SSC_CTL);
+-      spi_finalize_current_transfer(spi->master);
++      spi_finalize_current_transfer(spi->controller);
+       return t->len;
+ }
+@@ -174,7 +174,7 @@ static int spi_st_transfer_one(struct sp
+ #define MODEBITS  (SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH)
+ static int spi_st_setup(struct spi_device *spi)
+ {
+-      struct spi_st *spi_st = spi_master_get_devdata(spi->master);
++      struct spi_st *spi_st = spi_controller_get_devdata(spi->controller);
+       u32 spi_st_clk, sscbrg, var;
+       u32 hz = spi->max_speed_hz;
+@@ -274,35 +274,35 @@ static irqreturn_t spi_st_irq(int irq, v
+ static int spi_st_probe(struct platform_device *pdev)
+ {
+       struct device_node *np = pdev->dev.of_node;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct spi_st *spi_st;
+       int irq, ret = 0;
+       u32 var;
+-      master = spi_alloc_master(&pdev->dev, sizeof(*spi_st));
+-      if (!master)
++      host = spi_alloc_host(&pdev->dev, sizeof(*spi_st));
++      if (!host)
+               return -ENOMEM;
+-      master->dev.of_node             = np;
+-      master->mode_bits               = MODEBITS;
+-      master->setup                   = spi_st_setup;
+-      master->transfer_one            = spi_st_transfer_one;
+-      master->bits_per_word_mask      = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
+-      master->auto_runtime_pm         = true;
+-      master->bus_num                 = pdev->id;
+-      master->use_gpio_descriptors    = true;
+-      spi_st                          = spi_master_get_devdata(master);
++      host->dev.of_node               = np;
++      host->mode_bits                 = MODEBITS;
++      host->setup                     = spi_st_setup;
++      host->transfer_one              = spi_st_transfer_one;
++      host->bits_per_word_mask        = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
++      host->auto_runtime_pm           = true;
++      host->bus_num                   = pdev->id;
++      host->use_gpio_descriptors      = true;
++      spi_st                          = spi_controller_get_devdata(host);
+       spi_st->clk = devm_clk_get(&pdev->dev, "ssc");
+       if (IS_ERR(spi_st->clk)) {
+               dev_err(&pdev->dev, "Unable to request clock\n");
+               ret = PTR_ERR(spi_st->clk);
+-              goto put_master;
++              goto put_host;
+       }
+       ret = clk_prepare_enable(spi_st->clk);
+       if (ret)
+-              goto put_master;
++              goto put_host;
+       init_completion(&spi_st->done);
+@@ -324,7 +324,7 @@ static int spi_st_probe(struct platform_
+       var &= ~SSC_CTL_SR;
+       writel_relaxed(var, spi_st->base + SSC_CTL);
+-      /* Set SSC into slave mode before reconfiguring PIO pins */
++      /* Set SSC into target mode before reconfiguring PIO pins */
+       var = readl_relaxed(spi_st->base + SSC_CTL);
+       var &= ~SSC_CTL_MS;
+       writel_relaxed(var, spi_st->base + SSC_CTL);
+@@ -347,11 +347,11 @@ static int spi_st_probe(struct platform_
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+-      platform_set_drvdata(pdev, master);
++      platform_set_drvdata(pdev, host);
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (ret) {
+-              dev_err(&pdev->dev, "Failed to register master\n");
++              dev_err(&pdev->dev, "Failed to register host\n");
+               goto rpm_disable;
+       }
+@@ -361,15 +361,15 @@ rpm_disable:
+       pm_runtime_disable(&pdev->dev);
+ clk_disable:
+       clk_disable_unprepare(spi_st->clk);
+-put_master:
+-      spi_master_put(master);
++put_host:
++      spi_controller_put(host);
+       return ret;
+ }
+ static int spi_st_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = platform_get_drvdata(pdev);
+-      struct spi_st *spi_st = spi_master_get_devdata(master);
++      struct spi_controller *host = platform_get_drvdata(pdev);
++      struct spi_st *spi_st = spi_controller_get_devdata(host);
+       pm_runtime_disable(&pdev->dev);
+@@ -383,8 +383,8 @@ static int spi_st_remove(struct platform
+ #ifdef CONFIG_PM
+ static int spi_st_runtime_suspend(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct spi_st *spi_st = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct spi_st *spi_st = spi_controller_get_devdata(host);
+       writel_relaxed(0, spi_st->base + SSC_IEN);
+       pinctrl_pm_select_sleep_state(dev);
+@@ -396,8 +396,8 @@ static int spi_st_runtime_suspend(struct
+ static int spi_st_runtime_resume(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct spi_st *spi_st = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct spi_st *spi_st = spi_controller_get_devdata(host);
+       int ret;
+       ret = clk_prepare_enable(spi_st->clk);
+@@ -410,10 +410,10 @@ static int spi_st_runtime_resume(struct
+ #ifdef CONFIG_PM_SLEEP
+ static int spi_st_suspend(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
++      struct spi_controller *host = dev_get_drvdata(dev);
+       int ret;
+-      ret = spi_master_suspend(master);
++      ret = spi_controller_suspend(host);
+       if (ret)
+               return ret;
+@@ -422,10 +422,10 @@ static int spi_st_suspend(struct device
+ static int spi_st_resume(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
++      struct spi_controller *host = dev_get_drvdata(dev);
+       int ret;
+-      ret = spi_master_resume(master);
++      ret = spi_controller_resume(host);
+       if (ret)
+               return ret;
diff --git a/queue-6.1/spi-sun4i-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/spi-sun4i-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..b59dc7c
--- /dev/null
@@ -0,0 +1,58 @@
+From stable+bounces-246980-greg=kroah.com@vger.kernel.org Wed May 13 23:22:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:44:59 -0400
+Subject: spi: sun4i: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Andre Przywara" <andre.przywara@arm.com>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513174501.3896424-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit b7b949458ac391963e56ae354b73fee63016dcee ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Reviewed-by: Andre Przywara <andre.przywara@arm.com>
+Link: https://lore.kernel.org/r/20230303172041.2103336-75-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 42108a2f03e0 ("spi: sun4i: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun4i.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-sun4i.c
++++ b/drivers/spi/spi-sun4i.c
+@@ -519,11 +519,9 @@ err_free_master:
+       return ret;
+ }
+-static int sun4i_spi_remove(struct platform_device *pdev)
++static void sun4i_spi_remove(struct platform_device *pdev)
+ {
+       pm_runtime_force_suspend(&pdev->dev);
+-
+-      return 0;
+ }
+ static const struct of_device_id sun4i_spi_match[] = {
+@@ -539,7 +537,7 @@ static const struct dev_pm_ops sun4i_spi
+ static struct platform_driver sun4i_spi_driver = {
+       .probe  = sun4i_spi_probe,
+-      .remove = sun4i_spi_remove,
++      .remove_new = sun4i_spi_remove,
+       .driver = {
+               .name           = "sun4i-spi",
+               .of_match_table = sun4i_spi_match,
diff --git a/queue-6.1/spi-sun4i-fix-controller-deregistration.patch b/queue-6.1/spi-sun4i-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..03f3c8e
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-246982-greg=kroah.com@vger.kernel.org Wed May 13 23:25:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:45:01 -0400
+Subject: spi: sun4i: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Maxime Ripard <mripard@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513174501.3896424-3-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 42108a2f03e0fdeabe9d02d085bdb058baa1189f ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: b5f6517948cc ("spi: sunxi: Add Allwinner A10 SPI controller driver")
+Cc: stable@vger.kernel.org     # 3.15
+Cc: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-19-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun4i.c |   10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-sun4i.c
++++ b/drivers/spi/spi-sun4i.c
+@@ -503,7 +503,7 @@ static int sun4i_spi_probe(struct platfo
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_idle(&pdev->dev);
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot register SPI host\n");
+               goto err_pm_disable;
+@@ -521,7 +521,15 @@ err_free_host:
+ static void sun4i_spi_remove(struct platform_device *pdev)
+ {
++      struct spi_controller *host = platform_get_drvdata(pdev);
++
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       pm_runtime_force_suspend(&pdev->dev);
++
++      spi_controller_put(host);
+ }
+ static const struct of_device_id sun4i_spi_match[] = {
diff --git a/queue-6.1/spi-sun4i-switch-to-use-modern-name.patch b/queue-6.1/spi-sun4i-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..66290eb
--- /dev/null
@@ -0,0 +1,207 @@
+From stable+bounces-246981-greg=kroah.com@vger.kernel.org Wed May 13 23:25:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:45:00 -0400
+Subject: spi: sun4i: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513174501.3896424-2-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 6d232cc8a7e59af0c083319827541966a68817a0 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-7-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 42108a2f03e0 ("spi: sun4i: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun4i.c |   72 ++++++++++++++++++++++++------------------------
+ 1 file changed, 36 insertions(+), 36 deletions(-)
+
+--- a/drivers/spi/spi-sun4i.c
++++ b/drivers/spi/spi-sun4i.c
+@@ -75,7 +75,7 @@
+ #define SUN4I_FIFO_STA_TF_CNT_BITS            16
+ struct sun4i_spi {
+-      struct spi_master       *master;
++      struct spi_controller   *host;
+       void __iomem            *base_addr;
+       struct clk              *hclk;
+       struct clk              *mclk;
+@@ -161,7 +161,7 @@ static inline void sun4i_spi_fill_fifo(s
+ static void sun4i_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+-      struct sun4i_spi *sspi = spi_master_get_devdata(spi->master);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(spi->controller);
+       u32 reg;
+       reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
+@@ -201,11 +201,11 @@ static size_t sun4i_spi_max_transfer_siz
+       return SUN4I_MAX_XFER_SIZE - 1;
+ }
+-static int sun4i_spi_transfer_one(struct spi_master *master,
++static int sun4i_spi_transfer_one(struct spi_controller *host,
+                                 struct spi_device *spi,
+                                 struct spi_transfer *tfr)
+ {
+-      struct sun4i_spi *sspi = spi_master_get_devdata(master);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(host);
+       unsigned int mclk_rate, div, timeout;
+       unsigned int start, end, tx_time;
+       unsigned int tx_len = 0;
+@@ -334,7 +334,7 @@ static int sun4i_spi_transfer_one(struct
+                                             msecs_to_jiffies(tx_time));
+       end = jiffies;
+       if (!timeout) {
+-              dev_warn(&master->dev,
++              dev_warn(&host->dev,
+                        "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
+                        dev_name(&spi->dev), tfr->len, tfr->speed_hz,
+                        jiffies_to_msecs(end - start), tx_time);
+@@ -389,8 +389,8 @@ static irqreturn_t sun4i_spi_handler(int
+ static int sun4i_spi_runtime_resume(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct sun4i_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+       ret = clk_prepare_enable(sspi->hclk);
+@@ -418,8 +418,8 @@ out:
+ static int sun4i_spi_runtime_suspend(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct sun4i_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct sun4i_spi *sspi = spi_controller_get_devdata(host);
+       clk_disable_unprepare(sspi->mclk);
+       clk_disable_unprepare(sspi->hclk);
+@@ -429,62 +429,62 @@ static int sun4i_spi_runtime_suspend(str
+ static int sun4i_spi_probe(struct platform_device *pdev)
+ {
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct sun4i_spi *sspi;
+       int ret = 0, irq;
+-      master = spi_alloc_master(&pdev->dev, sizeof(struct sun4i_spi));
+-      if (!master) {
+-              dev_err(&pdev->dev, "Unable to allocate SPI Master\n");
++      host = spi_alloc_host(&pdev->dev, sizeof(struct sun4i_spi));
++      if (!host) {
++              dev_err(&pdev->dev, "Unable to allocate SPI Host\n");
+               return -ENOMEM;
+       }
+-      platform_set_drvdata(pdev, master);
+-      sspi = spi_master_get_devdata(master);
++      platform_set_drvdata(pdev, host);
++      sspi = spi_controller_get_devdata(host);
+       sspi->base_addr = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(sspi->base_addr)) {
+               ret = PTR_ERR(sspi->base_addr);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = -ENXIO;
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       ret = devm_request_irq(&pdev->dev, irq, sun4i_spi_handler,
+                              0, "sun4i-spi", sspi);
+       if (ret) {
+               dev_err(&pdev->dev, "Cannot request IRQ\n");
+-              goto err_free_master;
++              goto err_free_host;
+       }
+-      sspi->master = master;
+-      master->max_speed_hz = 100 * 1000 * 1000;
+-      master->min_speed_hz = 3 * 1000;
+-      master->set_cs = sun4i_spi_set_cs;
+-      master->transfer_one = sun4i_spi_transfer_one;
+-      master->num_chipselect = 4;
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
+-      master->bits_per_word_mask = SPI_BPW_MASK(8);
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->auto_runtime_pm = true;
+-      master->max_transfer_size = sun4i_spi_max_transfer_size;
++      sspi->host = host;
++      host->max_speed_hz = 100 * 1000 * 1000;
++      host->min_speed_hz = 3 * 1000;
++      host->set_cs = sun4i_spi_set_cs;
++      host->transfer_one = sun4i_spi_transfer_one;
++      host->num_chipselect = 4;
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
++      host->bits_per_word_mask = SPI_BPW_MASK(8);
++      host->dev.of_node = pdev->dev.of_node;
++      host->auto_runtime_pm = true;
++      host->max_transfer_size = sun4i_spi_max_transfer_size;
+       sspi->hclk = devm_clk_get(&pdev->dev, "ahb");
+       if (IS_ERR(sspi->hclk)) {
+               dev_err(&pdev->dev, "Unable to acquire AHB clock\n");
+               ret = PTR_ERR(sspi->hclk);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       sspi->mclk = devm_clk_get(&pdev->dev, "mod");
+       if (IS_ERR(sspi->mclk)) {
+               dev_err(&pdev->dev, "Unable to acquire module clock\n");
+               ret = PTR_ERR(sspi->mclk);
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       init_completion(&sspi->done);
+@@ -496,16 +496,16 @@ static int sun4i_spi_probe(struct platfo
+       ret = sun4i_spi_runtime_resume(&pdev->dev);
+       if (ret) {
+               dev_err(&pdev->dev, "Couldn't resume the device\n");
+-              goto err_free_master;
++              goto err_free_host;
+       }
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+       pm_runtime_idle(&pdev->dev);
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (ret) {
+-              dev_err(&pdev->dev, "cannot register SPI master\n");
++              dev_err(&pdev->dev, "cannot register SPI host\n");
+               goto err_pm_disable;
+       }
+@@ -514,8 +514,8 @@ static int sun4i_spi_probe(struct platfo
+ err_pm_disable:
+       pm_runtime_disable(&pdev->dev);
+       sun4i_spi_runtime_suspend(&pdev->dev);
+-err_free_master:
+-      spi_master_put(master);
++err_free_host:
++      spi_controller_put(host);
+       return ret;
+ }
diff --git a/queue-6.1/spi-sun6i-fix-controller-deregistration.patch b/queue-6.1/spi-sun6i-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..68121c8
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-247095-greg=kroah.com@vger.kernel.org Thu May 14 08:40:56 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 23:10:51 -0400
+Subject: spi: sun6i: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Maxime Ripard <mripard@kernel.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514031051.4119801-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit d874a1c33aee0d88fb4ba2f8aeadaa9f1965209a ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: 3558fe900e8a ("spi: sunxi: Add Allwinner A31 SPI controller driver")
+Cc: stable@vger.kernel.org     # 3.15
+Cc: Maxime Ripard <mripard@kernel.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-20-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+[ renamed spi_controller APIs to spi_master equivalents and kept int return type for sun6i_spi_remove ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-sun6i.c |    9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-sun6i.c
++++ b/drivers/spi/spi-sun6i.c
+@@ -688,7 +688,7 @@ static int sun6i_spi_probe(struct platfo
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = spi_register_master(master);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot register SPI master\n");
+               goto err_pm_disable;
+@@ -714,12 +714,19 @@ static int sun6i_spi_remove(struct platf
+ {
+       struct spi_master *master = platform_get_drvdata(pdev);
++      spi_master_get(master);
++
++      spi_unregister_master(master);
++
+       pm_runtime_force_suspend(&pdev->dev);
+       if (master->dma_tx)
+               dma_release_channel(master->dma_tx);
+       if (master->dma_rx)
+               dma_release_channel(master->dma_rx);
++
++      spi_master_put(master);
++
+       return 0;
+ }
diff --git a/queue-6.1/spi-syncuacer-fix-controller-deregistration.patch b/queue-6.1/spi-syncuacer-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..91658fc
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-246979-greg=kroah.com@vger.kernel.org Wed May 13 23:15:05 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:44:55 -0400
+Subject: spi: syncuacer: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Masahisa Kojima <masahisa.kojima@linaro.org>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513174455.3896307-3-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 75d849c3452e9611de031db45b3149ba9a99035f ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: b0823ee35cf9 ("spi: Add spi driver for Socionext SynQuacer platform")
+Cc: stable@vger.kernel.org     # 5.3
+Cc: Masahisa Kojima <masahisa.kojima@linaro.org>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-21-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-synquacer.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -719,7 +719,7 @@ static int synquacer_spi_probe(struct pl
+       pm_runtime_set_active(sspi->dev);
+       pm_runtime_enable(sspi->dev);
+-      ret = devm_spi_register_controller(sspi->dev, host);
++      ret = spi_register_controller(host);
+       if (ret)
+               goto disable_pm;
+@@ -740,9 +740,15 @@ static void synquacer_spi_remove(struct
+       struct spi_controller *host = platform_get_drvdata(pdev);
+       struct synquacer_spi *sspi = spi_controller_get_devdata(host);
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       pm_runtime_disable(sspi->dev);
+       clk_disable_unprepare(sspi->clk);
++
++      spi_controller_put(host);
+ }
+ static int __maybe_unused synquacer_spi_suspend(struct device *dev)
diff --git a/queue-6.1/spi-synquacer-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/spi-synquacer-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..25008bb
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-246977-greg=kroah.com@vger.kernel.org Wed May 13 23:25:36 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:44:53 -0400
+Subject: spi: synquacer: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513174455.3896307-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 1972cdc47df737f5b90ac2132080004f5e413e91 ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20230303172041.2103336-78-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 75d849c3452e ("spi: syncuacer: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-synquacer.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -735,7 +735,7 @@ put_spi:
+       return ret;
+ }
+-static int synquacer_spi_remove(struct platform_device *pdev)
++static void synquacer_spi_remove(struct platform_device *pdev)
+ {
+       struct spi_master *master = platform_get_drvdata(pdev);
+       struct synquacer_spi *sspi = spi_master_get_devdata(master);
+@@ -743,8 +743,6 @@ static int synquacer_spi_remove(struct p
+       pm_runtime_disable(sspi->dev);
+       clk_disable_unprepare(sspi->clk);
+-
+-      return 0;
+ }
+ static int __maybe_unused synquacer_spi_suspend(struct device *dev)
+@@ -820,7 +818,7 @@ static struct platform_driver synquacer_
+               .acpi_match_table = ACPI_PTR(synquacer_hsspi_acpi_ids),
+       },
+       .probe = synquacer_spi_probe,
+-      .remove = synquacer_spi_remove,
++      .remove_new = synquacer_spi_remove,
+ };
+ module_platform_driver(synquacer_spi_driver);
diff --git a/queue-6.1/spi-synquacer-switch-to-use-modern-name.patch b/queue-6.1/spi-synquacer-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..414d69a
--- /dev/null
@@ -0,0 +1,260 @@
+From stable+bounces-246978-greg=kroah.com@vger.kernel.org Wed May 13 23:25:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:44:54 -0400
+Subject: spi: synquacer: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513174455.3896307-2-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 3524d1b727a66712f02f92807219a3650e5cf910 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-10-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 75d849c3452e ("spi: syncuacer: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-synquacer.c |   84 ++++++++++++++++++++++----------------------
+ 1 file changed, 42 insertions(+), 42 deletions(-)
+
+--- a/drivers/spi/spi-synquacer.c
++++ b/drivers/spi/spi-synquacer.c
+@@ -225,11 +225,11 @@ static int write_fifo(struct synquacer_s
+       return 0;
+ }
+-static int synquacer_spi_config(struct spi_master *master,
++static int synquacer_spi_config(struct spi_controller *host,
+                               struct spi_device *spi,
+                               struct spi_transfer *xfer)
+ {
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       unsigned int speed, mode, bpw, cs, bus_width, transfer_mode;
+       u32 rate, val, div;
+@@ -263,7 +263,7 @@ static int synquacer_spi_config(struct s
+       }
+       sspi->transfer_mode = transfer_mode;
+-      rate = master->max_speed_hz;
++      rate = host->max_speed_hz;
+       div = DIV_ROUND_UP(rate, speed);
+       if (div > 254) {
+@@ -350,11 +350,11 @@ static int synquacer_spi_config(struct s
+       return 0;
+ }
+-static int synquacer_spi_transfer_one(struct spi_master *master,
++static int synquacer_spi_transfer_one(struct spi_controller *host,
+                                     struct spi_device *spi,
+                                     struct spi_transfer *xfer)
+ {
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+       int status = 0;
+       u32 words;
+@@ -378,7 +378,7 @@ static int synquacer_spi_transfer_one(st
+       if (bpw == 8 && !(xfer->len % 4) && !(spi->mode & SPI_LSB_FIRST))
+               xfer->bits_per_word = 32;
+-      ret = synquacer_spi_config(master, spi, xfer);
++      ret = synquacer_spi_config(host, spi, xfer);
+       /* restore */
+       xfer->bits_per_word = bpw;
+@@ -482,7 +482,7 @@ static int synquacer_spi_transfer_one(st
+ static void synquacer_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+-      struct synquacer_spi *sspi = spi_master_get_devdata(spi->master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       val = readl(sspi->regs + SYNQUACER_HSSPI_REG_DMSTART);
+@@ -517,11 +517,11 @@ static int synquacer_spi_wait_status_upd
+       return -EBUSY;
+ }
+-static int synquacer_spi_enable(struct spi_master *master)
++static int synquacer_spi_enable(struct spi_controller *host)
+ {
+       u32 val;
+       int status;
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       /* Disable module */
+       writel(0, sspi->regs + SYNQUACER_HSSPI_REG_MCTRL);
+@@ -601,18 +601,18 @@ static irqreturn_t sq_spi_tx_handler(int
+ static int synquacer_spi_probe(struct platform_device *pdev)
+ {
+       struct device_node *np = pdev->dev.of_node;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct synquacer_spi *sspi;
+       int ret;
+       int rx_irq, tx_irq;
+-      master = spi_alloc_master(&pdev->dev, sizeof(*sspi));
+-      if (!master)
++      host = spi_alloc_host(&pdev->dev, sizeof(*sspi));
++      if (!host)
+               return -ENOMEM;
+-      platform_set_drvdata(pdev, master);
++      platform_set_drvdata(pdev, host);
+-      sspi = spi_master_get_devdata(master);
++      sspi = spi_controller_get_devdata(host);
+       sspi->dev = &pdev->dev;
+       init_completion(&sspi->transfer_done);
+@@ -625,7 +625,7 @@ static int synquacer_spi_probe(struct pl
+       sspi->clk_src_type = SYNQUACER_HSSPI_CLOCK_SRC_IHCLK; /* Default */
+       device_property_read_u32(&pdev->dev, "socionext,ihclk-rate",
+-                               &master->max_speed_hz); /* for ACPI */
++                               &host->max_speed_hz); /* for ACPI */
+       if (dev_of_node(&pdev->dev)) {
+               if (device_property_match_string(&pdev->dev,
+@@ -655,21 +655,21 @@ static int synquacer_spi_probe(struct pl
+                       goto put_spi;
+               }
+-              master->max_speed_hz = clk_get_rate(sspi->clk);
++              host->max_speed_hz = clk_get_rate(sspi->clk);
+       }
+-      if (!master->max_speed_hz) {
++      if (!host->max_speed_hz) {
+               dev_err(&pdev->dev, "missing clock source\n");
+               ret = -EINVAL;
+               goto disable_clk;
+       }
+-      master->min_speed_hz = master->max_speed_hz / 254;
++      host->min_speed_hz = host->max_speed_hz / 254;
+       sspi->aces = device_property_read_bool(&pdev->dev,
+                                              "socionext,set-aces");
+       sspi->rtm = device_property_read_bool(&pdev->dev, "socionext,use-rtm");
+-      master->num_chipselect = SYNQUACER_HSSPI_NUM_CHIP_SELECT;
++      host->num_chipselect = SYNQUACER_HSSPI_NUM_CHIP_SELECT;
+       rx_irq = platform_get_irq(pdev, 0);
+       if (rx_irq <= 0) {
+@@ -699,27 +699,27 @@ static int synquacer_spi_probe(struct pl
+               goto disable_clk;
+       }
+-      master->dev.of_node = np;
+-      master->dev.fwnode = pdev->dev.fwnode;
+-      master->auto_runtime_pm = true;
+-      master->bus_num = pdev->id;
+-
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL |
+-                          SPI_TX_QUAD | SPI_RX_QUAD;
+-      master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
+-                                   SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
++      host->dev.of_node = np;
++      host->dev.fwnode = pdev->dev.fwnode;
++      host->auto_runtime_pm = true;
++      host->bus_num = pdev->id;
++
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL |
++                        SPI_TX_QUAD | SPI_RX_QUAD;
++      host->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(24) |
++                                 SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
+-      master->set_cs = synquacer_spi_set_cs;
+-      master->transfer_one = synquacer_spi_transfer_one;
++      host->set_cs = synquacer_spi_set_cs;
++      host->transfer_one = synquacer_spi_transfer_one;
+-      ret = synquacer_spi_enable(master);
++      ret = synquacer_spi_enable(host);
+       if (ret)
+               goto disable_clk;
+       pm_runtime_set_active(sspi->dev);
+       pm_runtime_enable(sspi->dev);
+-      ret = devm_spi_register_master(sspi->dev, master);
++      ret = devm_spi_register_controller(sspi->dev, host);
+       if (ret)
+               goto disable_pm;
+@@ -730,15 +730,15 @@ disable_pm:
+ disable_clk:
+       clk_disable_unprepare(sspi->clk);
+ put_spi:
+-      spi_master_put(master);
++      spi_controller_put(host);
+       return ret;
+ }
+ static void synquacer_spi_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = platform_get_drvdata(pdev);
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = platform_get_drvdata(pdev);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       pm_runtime_disable(sspi->dev);
+@@ -747,11 +747,11 @@ static void synquacer_spi_remove(struct
+ static int __maybe_unused synquacer_spi_suspend(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+-      ret = spi_master_suspend(master);
++      ret = spi_controller_suspend(host);
+       if (ret)
+               return ret;
+@@ -763,8 +763,8 @@ static int __maybe_unused synquacer_spi_
+ static int __maybe_unused synquacer_spi_resume(struct device *dev)
+ {
+-      struct spi_master *master = dev_get_drvdata(dev);
+-      struct synquacer_spi *sspi = spi_master_get_devdata(master);
++      struct spi_controller *host = dev_get_drvdata(dev);
++      struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+       int ret;
+       if (!pm_runtime_suspended(dev)) {
+@@ -778,7 +778,7 @@ static int __maybe_unused synquacer_spi_
+                       return ret;
+               }
+-              ret = synquacer_spi_enable(master);
++              ret = synquacer_spi_enable(host);
+               if (ret) {
+                       clk_disable_unprepare(sspi->clk);
+                       dev_err(dev, "failed to enable spi (%d)\n", ret);
+@@ -786,7 +786,7 @@ static int __maybe_unused synquacer_spi_
+               }
+       }
+-      ret = spi_master_resume(master);
++      ret = spi_controller_resume(host);
+       if (ret < 0)
+               clk_disable_unprepare(sspi->clk);
diff --git a/queue-6.1/spi-tegra114-fix-controller-deregistration.patch b/queue-6.1/spi-tegra114-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..a53b4b2
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-247173-greg=kroah.com@vger.kernel.org Thu May 14 17:16:10 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 07:45:54 -0400
+Subject: spi: tegra114: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Jingoo Han <jg1.han@samsung.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514114554.179180-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 9c9c27ff2058142d8f800de3186d6864184958de ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: 5c8096439600 ("spi: tegra114: use devm_spi_register_master()")
+Cc: stable@vger.kernel.org     # 3.13
+Cc: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-22-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+[ renamed spi_controller/host APIs to spi_master/master equivalents and placed spi_master_put() before the existing return 0 in remove ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-tegra114.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-tegra114.c
++++ b/drivers/spi/spi-tegra114.c
+@@ -1415,7 +1415,7 @@ static int tegra_spi_probe(struct platfo
+       }
+       master->dev.of_node = pdev->dev.of_node;
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = spi_register_master(master);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "can not register to master err %d\n", ret);
+               goto exit_free_irq;
+@@ -1441,6 +1441,10 @@ static int tegra_spi_remove(struct platf
+       struct spi_master *master = platform_get_drvdata(pdev);
+       struct tegra_spi_data   *tspi = spi_master_get_devdata(master);
++      spi_master_get(master);
++
++      spi_unregister_master(master);
++
+       free_irq(tspi->irq, tspi);
+       if (tspi->tx_dma_chan)
+@@ -1453,6 +1457,8 @@ static int tegra_spi_remove(struct platf
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               tegra_spi_runtime_suspend(&pdev->dev);
++      spi_master_put(master);
++
+       return 0;
+ }
diff --git a/queue-6.1/spi-tegra20-sflash-fix-controller-deregistration.patch b/queue-6.1/spi-tegra20-sflash-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..6224390
--- /dev/null
@@ -0,0 +1,58 @@
+From stable+bounces-247174-greg=kroah.com@vger.kernel.org Thu May 14 17:21:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 07:46:26 -0400
+Subject: spi: tegra20-sflash: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Jingoo Han <jg1.han@samsung.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514114626.180398-1-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit ad7310e983327f939dd6c4e801eab13238992572 ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Fixes: f12f7318c44a ("spi: tegra20-sflash: use devm_spi_register_master()")
+Cc: stable@vger.kernel.org     # 3.13
+Cc: Jingoo Han <jg1.han@samsung.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-23-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+[ renamed spi_controller/host APIs to spi_master/master equivalents and switched devm_spi_register_master to spi_register_master ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-tegra20-sflash.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-tegra20-sflash.c
++++ b/drivers/spi/spi-tegra20-sflash.c
+@@ -506,7 +506,7 @@ static int tegra_sflash_probe(struct pla
+       pm_runtime_put(&pdev->dev);
+       master->dev.of_node = pdev->dev.of_node;
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = spi_register_master(master);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "can not register to master err %d\n", ret);
+               goto exit_pm_disable;
+@@ -529,12 +529,18 @@ static int tegra_sflash_remove(struct pl
+       struct spi_master *master = platform_get_drvdata(pdev);
+       struct tegra_sflash_data        *tsd = spi_master_get_devdata(master);
++      spi_master_get(master);
++
++      spi_unregister_master(master);
++
+       free_irq(tsd->irq, tsd);
+       pm_runtime_disable(&pdev->dev);
+       if (!pm_runtime_status_suspended(&pdev->dev))
+               tegra_sflash_runtime_suspend(&pdev->dev);
++      spi_master_put(master);
++
+       return 0;
+ }
diff --git a/queue-6.1/spi-ti-qspi-fix-controller-deregistration.patch b/queue-6.1/spi-ti-qspi-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..8bd9356
--- /dev/null
@@ -0,0 +1,69 @@
+From stable+bounces-247006-greg=kroah.com@vger.kernel.org Wed May 13 23:57:12 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 14:20:17 -0400
+Subject: spi: ti-qspi: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Sebastian Andrzej Siewior <bigeasy@linutronix.de>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513182017.3918352-4-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 0c18a1bacbb1d8b8aa34d3d004a2cb8226c8b1ea ]
+
+Make sure to deregister the controller before disabling underlying
+resources like clocks during driver unbind.
+
+Note that the controller is suspended before disabling and releasing
+resources since commit 3ac066e2227c ("spi: spi-ti-qspi: Suspend the
+queue before removing the device") which avoids issues like unclocked
+accesses but prevents SPI device drivers from doing I/O during
+deregistration.
+
+Fixes: 3b3a80019ff1 ("spi: ti-qspi: one only one interrupt handler")
+Cc: stable@vger.kernel.org     # 3.13
+Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-24-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-ti-qspi.c |   14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+--- a/drivers/spi/spi-ti-qspi.c
++++ b/drivers/spi/spi-ti-qspi.c
+@@ -897,7 +897,7 @@ no_dma:
+       qspi->mmap_enabled = false;
+       qspi->current_cs = -1;
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (!ret)
+               return 0;
+@@ -912,19 +912,17 @@ free_host:
+ static void ti_qspi_remove(struct platform_device *pdev)
+ {
+       struct ti_qspi *qspi = platform_get_drvdata(pdev);
+-      int rc;
+-      rc = spi_controller_suspend(qspi->host);
+-      if (rc) {
+-              dev_alert(&pdev->dev, "spi_controller_suspend() failed (%pe)\n",
+-                        ERR_PTR(rc));
+-              return;
+-      }
++      spi_controller_get(qspi->host);
++
++      spi_unregister_controller(qspi->host);
+       pm_runtime_put_sync(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+       ti_qspi_dma_cleanup(qspi);
++
++      spi_controller_put(qspi->host);
+ }
+ static const struct dev_pm_ops ti_qspi_pm_ops = {
diff --git a/queue-6.1/spi-topcliff-pch-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/spi-topcliff-pch-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..be2e433
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-247679-greg=kroah.com@vger.kernel.org Fri May 15 17:52:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 07:45:14 -0400
+Subject: spi: topcliff-pch: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260515114516.3021914-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit b082694f18bdff807b42a3bccc62c3a524168f23 ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20230303172041.2103336-83-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 5d6f477d6fc0 ("spi: topcliff-pch: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-topcliff-pch.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-topcliff-pch.c
++++ b/drivers/spi/spi-topcliff-pch.c
+@@ -1396,7 +1396,7 @@ err_pci_iomap:
+       return ret;
+ }
+-static int pch_spi_pd_remove(struct platform_device *plat_dev)
++static void pch_spi_pd_remove(struct platform_device *plat_dev)
+ {
+       struct pch_spi_board_data *board_dat = dev_get_platdata(&plat_dev->dev);
+       struct pch_spi_data *data = platform_get_drvdata(plat_dev);
+@@ -1434,8 +1434,6 @@ static int pch_spi_pd_remove(struct plat
+       pci_iounmap(board_dat->pdev, data->io_remap_addr);
+       spi_unregister_master(data->master);
+-
+-      return 0;
+ }
+ #ifdef CONFIG_PM
+ static int pch_spi_pd_suspend(struct platform_device *pd_dev,
+@@ -1516,7 +1514,7 @@ static struct platform_driver pch_spi_pd
+               .name = "pch-spi",
+       },
+       .probe = pch_spi_pd_probe,
+-      .remove = pch_spi_pd_remove,
++      .remove_new = pch_spi_pd_remove,
+       .suspend = pch_spi_pd_suspend,
+       .resume = pch_spi_pd_resume
+ };
diff --git a/queue-6.1/spi-uniphier-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/spi-uniphier-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..9c030d1
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-247182-greg=kroah.com@vger.kernel.org Thu May 14 17:32:42 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 08:02:30 -0400
+Subject: spi: uniphier: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260514120233.192698-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit 1b13d196d2813dadc1947940dbd4aaad6ae21c02 ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20230303172041.2103336-84-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0245435f7772 ("spi: uniphier: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-uniphier.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-uniphier.c
++++ b/drivers/spi/spi-uniphier.c
+@@ -775,7 +775,7 @@ out_master_put:
+       return ret;
+ }
+-static int uniphier_spi_remove(struct platform_device *pdev)
++static void uniphier_spi_remove(struct platform_device *pdev)
+ {
+       struct spi_master *master = platform_get_drvdata(pdev);
+       struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
+@@ -786,8 +786,6 @@ static int uniphier_spi_remove(struct pl
+               dma_release_channel(master->dma_rx);
+       clk_disable_unprepare(priv->clk);
+-
+-      return 0;
+ }
+ static const struct of_device_id uniphier_spi_match[] = {
+@@ -798,7 +796,7 @@ MODULE_DEVICE_TABLE(of, uniphier_spi_mat
+ static struct platform_driver uniphier_spi_driver = {
+       .probe = uniphier_spi_probe,
+-      .remove = uniphier_spi_remove,
++      .remove_new = uniphier_spi_remove,
+       .driver = {
+               .name = "uniphier-spi",
+               .of_match_table = uniphier_spi_match,
diff --git a/queue-6.1/spi-uniphier-fix-controller-deregistration.patch b/queue-6.1/spi-uniphier-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..41951bb
--- /dev/null
@@ -0,0 +1,59 @@
+From stable+bounces-247185-greg=kroah.com@vger.kernel.org Thu May 14 17:32:49 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 08:02:33 -0400
+Subject: spi: uniphier: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Keiji Hayashibara <hayashibara.keiji@socionext.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514120233.192698-4-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit 0245435f777264ac45945ed2f325dd095a41d1af ]
+
+Make sure to deregister the controller before releasing underlying
+resources like DMA during driver unbind.
+
+Note that clocks were also disabled before the recent commit
+fdca270f8f87 ("spi: uniphier: Simplify clock handling with
+devm_clk_get_enabled()").
+
+Fixes: 5ba155a4d4cc ("spi: add SPI controller driver for UniPhier SoC")
+Cc: stable@vger.kernel.org     # 4.19
+Cc: Keiji Hayashibara <hayashibara.keiji@socionext.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-25-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-uniphier.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/spi/spi-uniphier.c
++++ b/drivers/spi/spi-uniphier.c
+@@ -747,7 +747,7 @@ static int uniphier_spi_probe(struct pla
+       host->max_dma_len = min(dma_tx_burst, dma_rx_burst);
+-      ret = devm_spi_register_controller(&pdev->dev, host);
++      ret = spi_register_controller(host);
+       if (ret)
+               goto out_release_dma;
+@@ -772,10 +772,16 @@ static void uniphier_spi_remove(struct p
+ {
+       struct spi_controller *host = platform_get_drvdata(pdev);
++      spi_controller_get(host);
++
++      spi_unregister_controller(host);
++
+       if (host->dma_tx)
+               dma_release_channel(host->dma_tx);
+       if (host->dma_rx)
+               dma_release_channel(host->dma_rx);
++
++      spi_controller_put(host);
+ }
+ static const struct of_device_id uniphier_spi_match[] = {
diff --git a/queue-6.1/spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch b/queue-6.1/spi-uniphier-simplify-clock-handling-with-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..3b833c7
--- /dev/null
@@ -0,0 +1,99 @@
+From stable+bounces-247184-greg=kroah.com@vger.kernel.org Thu May 14 17:33:02 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 08:02:32 -0400
+Subject: spi: uniphier: Simplify clock handling with devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Pei Xiao <xiaopei01@kylinos.cn>, Kunihiko Hayashi <hayashi.kunihiko@socionext.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514120233.192698-3-sashal@kernel.org>
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit fdca270f8f87cae2eb5b619234b9dd11a863ce6b ]
+
+Replace devm_clk_get() followed by clk_prepare_enable() with
+devm_clk_get_enabled() for the clock. This removes the need for
+explicit clock enable and disable calls, as the managed API automatically
+handles clock disabling on device removal or probe failure.
+
+Remove the now-unnecessary clk_disable_unprepare() calls from the probe
+error path and the remove callback. Adjust error labels accordingly.
+
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Reviewed-by: Kunihiko Hayashi <hayashi.kunihiko@socionext.com>
+Link: https://patch.msgid.link/b2deeefd4ef1a4bce71116aabfcb7e81400f6d37.1775546948.git.xiaopei01@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0245435f7772 ("spi: uniphier: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-uniphier.c |   18 ++++--------------
+ 1 file changed, 4 insertions(+), 14 deletions(-)
+
+--- a/drivers/spi/spi-uniphier.c
++++ b/drivers/spi/spi-uniphier.c
+@@ -666,28 +666,24 @@ static int uniphier_spi_probe(struct pla
+       }
+       priv->base_dma_addr = res->start;
+-      priv->clk = devm_clk_get(&pdev->dev, NULL);
++      priv->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+       if (IS_ERR(priv->clk)) {
+               dev_err(&pdev->dev, "failed to get clock\n");
+               ret = PTR_ERR(priv->clk);
+               goto out_host_put;
+       }
+-      ret = clk_prepare_enable(priv->clk);
+-      if (ret)
+-              goto out_host_put;
+-
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+               ret = irq;
+-              goto out_disable_clk;
++              goto out_host_put;
+       }
+       ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler,
+                              0, "uniphier-spi", priv);
+       if (ret) {
+               dev_err(&pdev->dev, "failed to request IRQ\n");
+-              goto out_disable_clk;
++              goto out_host_put;
+       }
+       init_completion(&priv->xfer_done);
+@@ -717,7 +713,7 @@ static int uniphier_spi_probe(struct pla
+       if (IS_ERR_OR_NULL(host->dma_tx)) {
+               if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+-                      goto out_disable_clk;
++                      goto out_host_put;
+               }
+               host->dma_tx = NULL;
+               dma_tx_burst = INT_MAX;
+@@ -767,9 +763,6 @@ out_release_dma:
+               host->dma_tx = NULL;
+       }
+-out_disable_clk:
+-      clk_disable_unprepare(priv->clk);
+-
+ out_host_put:
+       spi_controller_put(host);
+       return ret;
+@@ -778,14 +771,11 @@ out_host_put:
+ static void uniphier_spi_remove(struct platform_device *pdev)
+ {
+       struct spi_controller *host = platform_get_drvdata(pdev);
+-      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       if (host->dma_tx)
+               dma_release_channel(host->dma_tx);
+       if (host->dma_rx)
+               dma_release_channel(host->dma_rx);
+-
+-      clk_disable_unprepare(priv->clk);
+ }
+ static const struct of_device_id uniphier_spi_match[] = {
diff --git a/queue-6.1/spi-uniphier-switch-to-use-modern-name.patch b/queue-6.1/spi-uniphier-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..78a0dc2
--- /dev/null
@@ -0,0 +1,513 @@
+From stable+bounces-247183-greg=kroah.com@vger.kernel.org Thu May 14 17:32:59 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 14 May 2026 08:02:31 -0400
+Subject: spi: uniphier: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260514120233.192698-2-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 4c2ee0991013ca8a32bb093a017d460204790112 ]
+
+Change legacy name master to modern name host or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-19-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: 0245435f7772 ("spi: uniphier: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-uniphier.c |  198 ++++++++++++++++++++++-----------------------
+ 1 file changed, 99 insertions(+), 99 deletions(-)
+
+--- a/drivers/spi/spi-uniphier.c
++++ b/drivers/spi/spi-uniphier.c
+@@ -26,7 +26,7 @@ struct uniphier_spi_priv {
+       void __iomem *base;
+       dma_addr_t base_dma_addr;
+       struct clk *clk;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct completion xfer_done;
+       int error;
+@@ -127,7 +127,7 @@ static inline void uniphier_spi_irq_disa
+ static void uniphier_spi_set_mode(struct spi_device *spi)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val1, val2;
+       /*
+@@ -180,7 +180,7 @@ static void uniphier_spi_set_mode(struct
+ static void uniphier_spi_set_transfer_size(struct spi_device *spi, int size)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       val = readl(priv->base + SSI_TXWDS);
+@@ -198,7 +198,7 @@ static void uniphier_spi_set_transfer_si
+ static void uniphier_spi_set_baudrate(struct spi_device *spi,
+                                     unsigned int speed)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val, ckdiv;
+       /*
+@@ -217,7 +217,7 @@ static void uniphier_spi_set_baudrate(st
+ static void uniphier_spi_setup_transfer(struct spi_device *spi,
+                                      struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       priv->error = 0;
+@@ -333,7 +333,7 @@ static void uniphier_spi_fill_tx_fifo(st
+ static void uniphier_spi_set_cs(struct spi_device *spi, bool enable)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(spi->master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(spi->controller);
+       u32 val;
+       val = readl(priv->base + SSI_FPS);
+@@ -346,16 +346,16 @@ static void uniphier_spi_set_cs(struct s
+       writel(val, priv->base + SSI_FPS);
+ }
+-static bool uniphier_spi_can_dma(struct spi_master *master,
++static bool uniphier_spi_can_dma(struct spi_controller *host,
+                                struct spi_device *spi,
+                                struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       unsigned int bpw = bytes_per_word(priv->bits_per_word);
+-      if ((!master->dma_tx && !master->dma_rx)
+-          || (!master->dma_tx && t->tx_buf)
+-          || (!master->dma_rx && t->rx_buf))
++      if ((!host->dma_tx && !host->dma_rx)
++          || (!host->dma_tx && t->tx_buf)
++          || (!host->dma_rx && t->rx_buf))
+               return false;
+       return DIV_ROUND_UP(t->len, bpw) > SSI_FIFO_DEPTH;
+@@ -363,33 +363,33 @@ static bool uniphier_spi_can_dma(struct
+ static void uniphier_spi_dma_rxcb(void *data)
+ {
+-      struct spi_master *master = data;
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct spi_controller *host = data;
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       int state = atomic_fetch_andnot(SSI_DMA_RX_BUSY, &priv->dma_busy);
+       uniphier_spi_irq_disable(priv, SSI_IE_RXRE);
+       if (!(state & SSI_DMA_TX_BUSY))
+-              spi_finalize_current_transfer(master);
++              spi_finalize_current_transfer(host);
+ }
+ static void uniphier_spi_dma_txcb(void *data)
+ {
+-      struct spi_master *master = data;
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct spi_controller *host = data;
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       int state = atomic_fetch_andnot(SSI_DMA_TX_BUSY, &priv->dma_busy);
+       uniphier_spi_irq_disable(priv, SSI_IE_TXRE);
+       if (!(state & SSI_DMA_RX_BUSY))
+-              spi_finalize_current_transfer(master);
++              spi_finalize_current_transfer(host);
+ }
+-static int uniphier_spi_transfer_one_dma(struct spi_master *master,
++static int uniphier_spi_transfer_one_dma(struct spi_controller *host,
+                                        struct spi_device *spi,
+                                        struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       struct dma_async_tx_descriptor *rxdesc = NULL, *txdesc = NULL;
+       int buswidth;
+@@ -412,23 +412,23 @@ static int uniphier_spi_transfer_one_dma
+                       .src_maxburst = SSI_FIFO_BURST_NUM,
+               };
+-              dmaengine_slave_config(master->dma_rx, &rxconf);
++              dmaengine_slave_config(host->dma_rx, &rxconf);
+               rxdesc = dmaengine_prep_slave_sg(
+-                      master->dma_rx,
++                      host->dma_rx,
+                       t->rx_sg.sgl, t->rx_sg.nents,
+                       DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (!rxdesc)
+                       goto out_err_prep;
+               rxdesc->callback = uniphier_spi_dma_rxcb;
+-              rxdesc->callback_param = master;
++              rxdesc->callback_param = host;
+               uniphier_spi_irq_enable(priv, SSI_IE_RXRE);
+               atomic_or(SSI_DMA_RX_BUSY, &priv->dma_busy);
+               dmaengine_submit(rxdesc);
+-              dma_async_issue_pending(master->dma_rx);
++              dma_async_issue_pending(host->dma_rx);
+       }
+       if (priv->tx_buf) {
+@@ -439,23 +439,23 @@ static int uniphier_spi_transfer_one_dma
+                       .dst_maxburst = SSI_FIFO_BURST_NUM,
+               };
+-              dmaengine_slave_config(master->dma_tx, &txconf);
++              dmaengine_slave_config(host->dma_tx, &txconf);
+               txdesc = dmaengine_prep_slave_sg(
+-                      master->dma_tx,
++                      host->dma_tx,
+                       t->tx_sg.sgl, t->tx_sg.nents,
+                       DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (!txdesc)
+                       goto out_err_prep;
+               txdesc->callback = uniphier_spi_dma_txcb;
+-              txdesc->callback_param = master;
++              txdesc->callback_param = host;
+               uniphier_spi_irq_enable(priv, SSI_IE_TXRE);
+               atomic_or(SSI_DMA_TX_BUSY, &priv->dma_busy);
+               dmaengine_submit(txdesc);
+-              dma_async_issue_pending(master->dma_tx);
++              dma_async_issue_pending(host->dma_tx);
+       }
+       /* signal that we need to wait for completion */
+@@ -463,17 +463,17 @@ static int uniphier_spi_transfer_one_dma
+ out_err_prep:
+       if (rxdesc)
+-              dmaengine_terminate_sync(master->dma_rx);
++              dmaengine_terminate_sync(host->dma_rx);
+       return -EINVAL;
+ }
+-static int uniphier_spi_transfer_one_irq(struct spi_master *master,
++static int uniphier_spi_transfer_one_irq(struct spi_controller *host,
+                                        struct spi_device *spi,
+                                        struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
+-      struct device *dev = master->dev.parent;
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
++      struct device *dev = host->dev.parent;
+       unsigned long time_left;
+       reinit_completion(&priv->xfer_done);
+@@ -495,11 +495,11 @@ static int uniphier_spi_transfer_one_irq
+       return priv->error;
+ }
+-static int uniphier_spi_transfer_one_poll(struct spi_master *master,
++static int uniphier_spi_transfer_one_poll(struct spi_controller *host,
+                                         struct spi_device *spi,
+                                         struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       int loop = SSI_POLL_TIMEOUT_US * 10;
+       while (priv->tx_bytes) {
+@@ -520,14 +520,14 @@ static int uniphier_spi_transfer_one_pol
+       return 0;
+ irq_transfer:
+-      return uniphier_spi_transfer_one_irq(master, spi, t);
++      return uniphier_spi_transfer_one_irq(host, spi, t);
+ }
+-static int uniphier_spi_transfer_one(struct spi_master *master,
++static int uniphier_spi_transfer_one(struct spi_controller *host,
+                                    struct spi_device *spi,
+                                    struct spi_transfer *t)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       unsigned long threshold;
+       bool use_dma;
+@@ -537,9 +537,9 @@ static int uniphier_spi_transfer_one(str
+       uniphier_spi_setup_transfer(spi, t);
+-      use_dma = master->can_dma ? master->can_dma(master, spi, t) : false;
++      use_dma = host->can_dma ? host->can_dma(host, spi, t) : false;
+       if (use_dma)
+-              return uniphier_spi_transfer_one_dma(master, spi, t);
++              return uniphier_spi_transfer_one_dma(host, spi, t);
+       /*
+        * If the transfer operation will take longer than
+@@ -548,33 +548,33 @@ static int uniphier_spi_transfer_one(str
+       threshold = DIV_ROUND_UP(SSI_POLL_TIMEOUT_US * priv->speed_hz,
+                                       USEC_PER_SEC * BITS_PER_BYTE);
+       if (t->len > threshold)
+-              return uniphier_spi_transfer_one_irq(master, spi, t);
++              return uniphier_spi_transfer_one_irq(host, spi, t);
+       else
+-              return uniphier_spi_transfer_one_poll(master, spi, t);
++              return uniphier_spi_transfer_one_poll(host, spi, t);
+ }
+-static int uniphier_spi_prepare_transfer_hardware(struct spi_master *master)
++static int uniphier_spi_prepare_transfer_hardware(struct spi_controller *host)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       writel(SSI_CTL_EN, priv->base + SSI_CTL);
+       return 0;
+ }
+-static int uniphier_spi_unprepare_transfer_hardware(struct spi_master *master)
++static int uniphier_spi_unprepare_transfer_hardware(struct spi_controller *host)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       writel(0, priv->base + SSI_CTL);
+       return 0;
+ }
+-static void uniphier_spi_handle_err(struct spi_master *master,
++static void uniphier_spi_handle_err(struct spi_controller *host,
+                                   struct spi_message *msg)
+ {
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+       u32 val;
+       /* stop running spi transfer */
+@@ -587,12 +587,12 @@ static void uniphier_spi_handle_err(stru
+       uniphier_spi_irq_disable(priv, SSI_IE_ALL_MASK);
+       if (atomic_read(&priv->dma_busy) & SSI_DMA_TX_BUSY) {
+-              dmaengine_terminate_async(master->dma_tx);
++              dmaengine_terminate_async(host->dma_tx);
+               atomic_andnot(SSI_DMA_TX_BUSY, &priv->dma_busy);
+       }
+       if (atomic_read(&priv->dma_busy) & SSI_DMA_RX_BUSY) {
+-              dmaengine_terminate_async(master->dma_rx);
++              dmaengine_terminate_async(host->dma_rx);
+               atomic_andnot(SSI_DMA_RX_BUSY, &priv->dma_busy);
+       }
+ }
+@@ -641,7 +641,7 @@ done:
+ static int uniphier_spi_probe(struct platform_device *pdev)
+ {
+       struct uniphier_spi_priv *priv;
+-      struct spi_master *master;
++      struct spi_controller *host;
+       struct resource *res;
+       struct dma_slave_caps caps;
+       u32 dma_tx_burst = 0, dma_rx_burst = 0;
+@@ -649,20 +649,20 @@ static int uniphier_spi_probe(struct pla
+       int irq;
+       int ret;
+-      master = spi_alloc_master(&pdev->dev, sizeof(*priv));
+-      if (!master)
++      host = spi_alloc_host(&pdev->dev, sizeof(*priv));
++      if (!host)
+               return -ENOMEM;
+-      platform_set_drvdata(pdev, master);
++      platform_set_drvdata(pdev, host);
+-      priv = spi_master_get_devdata(master);
+-      priv->master = master;
++      priv = spi_controller_get_devdata(host);
++      priv->host = host;
+       priv->is_save_param = false;
+       priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+       if (IS_ERR(priv->base)) {
+               ret = PTR_ERR(priv->base);
+-              goto out_master_put;
++              goto out_host_put;
+       }
+       priv->base_dma_addr = res->start;
+@@ -670,12 +670,12 @@ static int uniphier_spi_probe(struct pla
+       if (IS_ERR(priv->clk)) {
+               dev_err(&pdev->dev, "failed to get clock\n");
+               ret = PTR_ERR(priv->clk);
+-              goto out_master_put;
++              goto out_host_put;
+       }
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+-              goto out_master_put;
++              goto out_host_put;
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0) {
+@@ -694,35 +694,35 @@ static int uniphier_spi_probe(struct pla
+       clk_rate = clk_get_rate(priv->clk);
+-      master->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER);
+-      master->min_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MAX_CLK_DIVIDER);
+-      master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
+-      master->dev.of_node = pdev->dev.of_node;
+-      master->bus_num = pdev->id;
+-      master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
+-
+-      master->set_cs = uniphier_spi_set_cs;
+-      master->transfer_one = uniphier_spi_transfer_one;
+-      master->prepare_transfer_hardware
++      host->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER);
++      host->min_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MAX_CLK_DIVIDER);
++      host->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LSB_FIRST;
++      host->dev.of_node = pdev->dev.of_node;
++      host->bus_num = pdev->id;
++      host->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
++
++      host->set_cs = uniphier_spi_set_cs;
++      host->transfer_one = uniphier_spi_transfer_one;
++      host->prepare_transfer_hardware
+                               = uniphier_spi_prepare_transfer_hardware;
+-      master->unprepare_transfer_hardware
++      host->unprepare_transfer_hardware
+                               = uniphier_spi_unprepare_transfer_hardware;
+-      master->handle_err = uniphier_spi_handle_err;
+-      master->can_dma = uniphier_spi_can_dma;
++      host->handle_err = uniphier_spi_handle_err;
++      host->can_dma = uniphier_spi_can_dma;
+-      master->num_chipselect = 1;
+-      master->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
++      host->num_chipselect = 1;
++      host->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
+-      master->dma_tx = dma_request_chan(&pdev->dev, "tx");
+-      if (IS_ERR_OR_NULL(master->dma_tx)) {
+-              if (PTR_ERR(master->dma_tx) == -EPROBE_DEFER) {
++      host->dma_tx = dma_request_chan(&pdev->dev, "tx");
++      if (IS_ERR_OR_NULL(host->dma_tx)) {
++              if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto out_disable_clk;
+               }
+-              master->dma_tx = NULL;
++              host->dma_tx = NULL;
+               dma_tx_burst = INT_MAX;
+       } else {
+-              ret = dma_get_slave_caps(master->dma_tx, &caps);
++              ret = dma_get_slave_caps(host->dma_tx, &caps);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get TX DMA capacities: %d\n",
+                               ret);
+@@ -731,16 +731,16 @@ static int uniphier_spi_probe(struct pla
+               dma_tx_burst = caps.max_burst;
+       }
+-      master->dma_rx = dma_request_chan(&pdev->dev, "rx");
+-      if (IS_ERR_OR_NULL(master->dma_rx)) {
+-              if (PTR_ERR(master->dma_rx) == -EPROBE_DEFER) {
++      host->dma_rx = dma_request_chan(&pdev->dev, "rx");
++      if (IS_ERR_OR_NULL(host->dma_rx)) {
++              if (PTR_ERR(host->dma_rx) == -EPROBE_DEFER) {
+                       ret = -EPROBE_DEFER;
+                       goto out_release_dma;
+               }
+-              master->dma_rx = NULL;
++              host->dma_rx = NULL;
+               dma_rx_burst = INT_MAX;
+       } else {
+-              ret = dma_get_slave_caps(master->dma_rx, &caps);
++              ret = dma_get_slave_caps(host->dma_rx, &caps);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to get RX DMA capacities: %d\n",
+                               ret);
+@@ -749,41 +749,41 @@ static int uniphier_spi_probe(struct pla
+               dma_rx_burst = caps.max_burst;
+       }
+-      master->max_dma_len = min(dma_tx_burst, dma_rx_burst);
++      host->max_dma_len = min(dma_tx_burst, dma_rx_burst);
+-      ret = devm_spi_register_master(&pdev->dev, master);
++      ret = devm_spi_register_controller(&pdev->dev, host);
+       if (ret)
+               goto out_release_dma;
+       return 0;
+ out_release_dma:
+-      if (!IS_ERR_OR_NULL(master->dma_rx)) {
+-              dma_release_channel(master->dma_rx);
+-              master->dma_rx = NULL;
+-      }
+-      if (!IS_ERR_OR_NULL(master->dma_tx)) {
+-              dma_release_channel(master->dma_tx);
+-              master->dma_tx = NULL;
++      if (!IS_ERR_OR_NULL(host->dma_rx)) {
++              dma_release_channel(host->dma_rx);
++              host->dma_rx = NULL;
++      }
++      if (!IS_ERR_OR_NULL(host->dma_tx)) {
++              dma_release_channel(host->dma_tx);
++              host->dma_tx = NULL;
+       }
+ out_disable_clk:
+       clk_disable_unprepare(priv->clk);
+-out_master_put:
+-      spi_master_put(master);
++out_host_put:
++      spi_controller_put(host);
+       return ret;
+ }
+ static void uniphier_spi_remove(struct platform_device *pdev)
+ {
+-      struct spi_master *master = platform_get_drvdata(pdev);
+-      struct uniphier_spi_priv *priv = spi_master_get_devdata(master);
++      struct spi_controller *host = platform_get_drvdata(pdev);
++      struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+-      if (master->dma_tx)
+-              dma_release_channel(master->dma_tx);
+-      if (master->dma_rx)
+-              dma_release_channel(master->dma_rx);
++      if (host->dma_tx)
++              dma_release_channel(host->dma_tx);
++      if (host->dma_rx)
++              dma_release_channel(host->dma_rx);
+       clk_disable_unprepare(priv->clk);
+ }
diff --git a/queue-6.1/spi-zynq-qspi-convert-to-platform-remove-callback-returning-void.patch b/queue-6.1/spi-zynq-qspi-convert-to-platform-remove-callback-returning-void.patch
new file mode 100644 (file)
index 0000000..3a80a45
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-247024-greg=kroah.com@vger.kernel.org Thu May 14 01:04:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 15:34:16 -0400
+Subject: spi: zynq-qspi: Convert to platform remove callback returning void
+To: stable@vger.kernel.org
+Cc: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>, "Mark Brown" <broonie@kernel.org>, "Sasha Levin" <sashal@kernel.org>
+Message-ID: <20260513193420.3938432-1-sashal@kernel.org>
+
+From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+
+[ Upstream commit ae9084b6458d34ebf3e377d0407ebe513e41ac71 ]
+
+The .remove() callback for a platform driver returns an int which makes
+many driver authors wrongly assume it's possible to do error handling by
+returning an error code. However the value returned is (mostly) ignored
+and this typically results in resource leaks. To improve here there is a
+quest to make the remove callback return void. In the first step of this
+quest all drivers are converted to .remove_new() which already returns
+void.
+
+Trivially convert this driver from always returning zero in the remove
+callback to the void returning variant.
+
+Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
+Link: https://lore.kernel.org/r/20230303172041.2103336-87-u.kleine-koenig@pengutronix.de
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: c9c012706c9f ("spi: zynq-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c |    6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -750,7 +750,7 @@ remove_master:
+  *
+  * Return:    0 on success and error value on failure
+  */
+-static int zynq_qspi_remove(struct platform_device *pdev)
++static void zynq_qspi_remove(struct platform_device *pdev)
+ {
+       struct zynq_qspi *xqspi = platform_get_drvdata(pdev);
+@@ -758,8 +758,6 @@ static int zynq_qspi_remove(struct platf
+       clk_disable_unprepare(xqspi->refclk);
+       clk_disable_unprepare(xqspi->pclk);
+-
+-      return 0;
+ }
+ static const struct of_device_id zynq_qspi_of_match[] = {
+@@ -774,7 +772,7 @@ MODULE_DEVICE_TABLE(of, zynq_qspi_of_mat
+  */
+ static struct platform_driver zynq_qspi_driver = {
+       .probe = zynq_qspi_probe,
+-      .remove = zynq_qspi_remove,
++      .remove_new = zynq_qspi_remove,
+       .driver = {
+               .name = "zynq-qspi",
+               .of_match_table = zynq_qspi_of_match,
diff --git a/queue-6.1/spi-zynq-qspi-fix-controller-deregistration.patch b/queue-6.1/spi-zynq-qspi-fix-controller-deregistration.patch
new file mode 100644 (file)
index 0000000..ef70bb4
--- /dev/null
@@ -0,0 +1,73 @@
+From stable+bounces-247028-greg=kroah.com@vger.kernel.org Thu May 14 01:04:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 15:34:20 -0400
+Subject: spi: zynq-qspi: fix controller deregistration
+To: stable@vger.kernel.org
+Cc: Johan Hovold <johan@kernel.org>, Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513193420.3938432-5-sashal@kernel.org>
+
+From: Johan Hovold <johan@kernel.org>
+
+[ Upstream commit c9c012706c9fa8ca6d129a9161caf92ab625a3fd ]
+
+Make sure to deregister the controller before disabling it during driver
+unbind.
+
+Note that clocks were also disabled before the recent commit
+1f8fd9490e31 ("spi: zynq-qspi: Simplify clock handling with
+devm_clk_get_enabled()").
+
+Fixes: 67dca5e580f1 ("spi: spi-mem: Add support for Zynq QSPI controller")
+Cc: stable@vger.kernel.org     # 5.2: 8eb2fd00f65a
+Cc: stable@vger.kernel.org     # 5.2
+Cc: Naga Sureshkumar Relli <naga.sureshkumar.relli@xilinx.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://patch.msgid.link/20260410081757.503099-27-johan@kernel.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -641,7 +641,7 @@ static int zynq_qspi_probe(struct platfo
+       xqspi = spi_controller_get_devdata(ctlr);
+       xqspi->dev = dev;
+-      platform_set_drvdata(pdev, xqspi);
++      platform_set_drvdata(pdev, ctlr);
+       xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(xqspi->regs)) {
+               ret = PTR_ERR(xqspi->regs);
+@@ -699,9 +699,9 @@ static int zynq_qspi_probe(struct platfo
+       /* QSPI controller initializations */
+       zynq_qspi_init_hw(xqspi, ctlr->num_chipselect);
+-      ret = devm_spi_register_controller(&pdev->dev, ctlr);
++      ret = spi_register_controller(ctlr);
+       if (ret) {
+-              dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
++              dev_err(&pdev->dev, "failed to register controller\n");
+               goto remove_ctlr;
+       }
+@@ -725,9 +725,16 @@ remove_ctlr:
+  */
+ static void zynq_qspi_remove(struct platform_device *pdev)
+ {
+-      struct zynq_qspi *xqspi = platform_get_drvdata(pdev);
++      struct spi_controller *ctlr = platform_get_drvdata(pdev);
++      struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
++
++      spi_controller_get(ctlr);
++
++      spi_unregister_controller(ctlr);
+       zynq_qspi_write(xqspi, ZYNQ_QSPI_ENABLE_OFFSET, 0);
++
++      spi_controller_put(ctlr);
+ }
+ static const struct of_device_id zynq_qspi_of_match[] = {
diff --git a/queue-6.1/spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch b/queue-6.1/spi-zynq-qspi-simplify-clock-handling-with-devm_clk_get_enabled.patch
new file mode 100644 (file)
index 0000000..3214f28
--- /dev/null
@@ -0,0 +1,142 @@
+From stable+bounces-247027-greg=kroah.com@vger.kernel.org Thu May 14 01:11:40 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 15:34:19 -0400
+Subject: spi: zynq-qspi: Simplify clock handling with devm_clk_get_enabled()
+To: stable@vger.kernel.org
+Cc: Pei Xiao <xiaopei01@kylinos.cn>, Michal Simek <michal.simek@amd.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513193420.3938432-4-sashal@kernel.org>
+
+From: Pei Xiao <xiaopei01@kylinos.cn>
+
+[ Upstream commit 1f8fd9490e3184e9a2394df2e682901a1d57ce71 ]
+
+Replace devm_clk_get() followed by clk_prepare_enable() with
+devm_clk_get_enabled() for both "pclk" and "ref_clk". This removes
+the need for explicit clock enable and disable calls, as the managed
+API automatically disables the clocks on device removal or probe
+failure.
+
+Remove the now-unnecessary clk_disable_unprepare() calls from the
+probe error paths and the remove callback. Simplify error handling
+by jumping directly to the remove_ctlr label.
+
+Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
+Acked-by: Michal Simek <michal.simek@amd.com>
+Link: https://patch.msgid.link/24043625f89376da36feca2408f990a85be7ab36.1775555500.git.xiaopei01@kylinos.cn
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: c9c012706c9f ("spi: zynq-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c |   42 ++++++------------------------------------
+ 1 file changed, 6 insertions(+), 36 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -379,21 +379,10 @@ static int zynq_qspi_setup_op(struct spi
+ {
+       struct spi_controller *ctlr = spi->controller;
+       struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
+-      int ret;
+       if (ctlr->busy)
+               return -EBUSY;
+-      ret = clk_enable(qspi->refclk);
+-      if (ret)
+-              return ret;
+-
+-      ret = clk_enable(qspi->pclk);
+-      if (ret) {
+-              clk_disable(qspi->refclk);
+-              return ret;
+-      }
+-
+       zynq_qspi_write(qspi, ZYNQ_QSPI_ENABLE_OFFSET,
+                       ZYNQ_QSPI_ENABLE_ENABLE_MASK);
+@@ -659,7 +648,7 @@ static int zynq_qspi_probe(struct platfo
+               goto remove_ctlr;
+       }
+-      xqspi->pclk = devm_clk_get(&pdev->dev, "pclk");
++      xqspi->pclk = devm_clk_get_enabled(&pdev->dev, "pclk");
+       if (IS_ERR(xqspi->pclk)) {
+               dev_err(&pdev->dev, "pclk clock not found.\n");
+               ret = PTR_ERR(xqspi->pclk);
+@@ -668,36 +657,24 @@ static int zynq_qspi_probe(struct platfo
+       init_completion(&xqspi->data_completion);
+-      xqspi->refclk = devm_clk_get(&pdev->dev, "ref_clk");
++      xqspi->refclk = devm_clk_get_enabled(&pdev->dev, "ref_clk");
+       if (IS_ERR(xqspi->refclk)) {
+               dev_err(&pdev->dev, "ref_clk clock not found.\n");
+               ret = PTR_ERR(xqspi->refclk);
+               goto remove_ctlr;
+       }
+-      ret = clk_prepare_enable(xqspi->pclk);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Unable to enable APB clock.\n");
+-              goto remove_ctlr;
+-      }
+-
+-      ret = clk_prepare_enable(xqspi->refclk);
+-      if (ret) {
+-              dev_err(&pdev->dev, "Unable to enable device clock.\n");
+-              goto clk_dis_pclk;
+-      }
+-
+       xqspi->irq = platform_get_irq(pdev, 0);
+       if (xqspi->irq < 0) {
+               ret = xqspi->irq;
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       }
+       ret = devm_request_irq(&pdev->dev, xqspi->irq, zynq_qspi_irq,
+                              0, pdev->name, xqspi);
+       if (ret != 0) {
+               ret = -ENXIO;
+               dev_err(&pdev->dev, "request_irq failed\n");
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       }
+       ret = of_property_read_u32(np, "num-cs",
+@@ -707,7 +684,7 @@ static int zynq_qspi_probe(struct platfo
+       } else if (num_cs > ZYNQ_QSPI_MAX_NUM_CS) {
+               ret = -EINVAL;
+               dev_err(&pdev->dev, "only 2 chip selects are available\n");
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       } else {
+               ctlr->num_chipselect = num_cs;
+       }
+@@ -725,15 +702,11 @@ static int zynq_qspi_probe(struct platfo
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
+       if (ret) {
+               dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
+-              goto clk_dis_all;
++              goto remove_ctlr;
+       }
+       return ret;
+-clk_dis_all:
+-      clk_disable_unprepare(xqspi->refclk);
+-clk_dis_pclk:
+-      clk_disable_unprepare(xqspi->pclk);
+ remove_ctlr:
+       spi_controller_put(ctlr);
+@@ -755,9 +728,6 @@ static void zynq_qspi_remove(struct plat
+       struct zynq_qspi *xqspi = platform_get_drvdata(pdev);
+       zynq_qspi_write(xqspi, ZYNQ_QSPI_ENABLE_OFFSET, 0);
+-
+-      clk_disable_unprepare(xqspi->refclk);
+-      clk_disable_unprepare(xqspi->pclk);
+ }
+ static const struct of_device_id zynq_qspi_of_match[] = {
diff --git a/queue-6.1/spi-zynq-qspi-switch-to-use-modern-name.patch b/queue-6.1/spi-zynq-qspi-switch-to-use-modern-name.patch
new file mode 100644 (file)
index 0000000..f68bc39
--- /dev/null
@@ -0,0 +1,145 @@
+From stable+bounces-247026-greg=kroah.com@vger.kernel.org Thu May 14 01:04:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 15:34:18 -0400
+Subject: spi: zynq-qspi: switch to use modern name
+To: stable@vger.kernel.org
+Cc: Yang Yingliang <yangyingliang@huawei.com>, Mark Brown <broonie@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513193420.3938432-3-sashal@kernel.org>
+
+From: Yang Yingliang <yangyingliang@huawei.com>
+
+[ Upstream commit 178ebb0c505b0a35edb4fb2a0e23a1f29e1db14d ]
+
+Change legacy name master/slave to modern name host/target or controller.
+
+No functional changed.
+
+Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
+Link: https://msgid.link/r/20231128093031.3707034-24-yangyingliang@huawei.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Stable-dep-of: c9c012706c9f ("spi: zynq-qspi: fix controller deregistration")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/spi/spi-zynq-qspi.c |   28 ++++++++++++++--------------
+ 1 file changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/spi/spi-zynq-qspi.c
++++ b/drivers/spi/spi-zynq-qspi.c
+@@ -54,10 +54,10 @@
+ #define ZYNQ_QSPI_CONFIG_MSTREN_MASK  BIT(0) /* Master Mode */
+ /*
+- * QSPI Configuration Register - Baud rate and slave select
++ * QSPI Configuration Register - Baud rate and target select
+  *
+  * These are the values used in the calculation of baud rate divisor and
+- * setting the slave select.
++ * setting the target select.
+  */
+ #define ZYNQ_QSPI_CONFIG_BAUD_DIV_MAX GENMASK(2, 0) /* Baud rate maximum */
+ #define ZYNQ_QSPI_CONFIG_BAUD_DIV_SHIFT       3 /* Baud rate divisor shift */
+@@ -164,14 +164,14 @@ static inline void zynq_qspi_write(struc
+  *
+  * The default settings of the QSPI controller's configurable parameters on
+  * reset are
+- *    - Master mode
++ *    - Host mode
+  *    - Baud rate divisor is set to 2
+  *    - Tx threshold set to 1l Rx threshold set to 32
+  *    - Flash memory interface mode enabled
+  *    - Size of the word to be transferred as 8 bit
+  * This function performs the following actions
+  *    - Disable and clear all the interrupts
+- *    - Enable manual slave select
++ *    - Enable manual target select
+  *    - Enable manual start
+  *    - Deselect all the chip select lines
+  *    - Set the size of the word to be transferred as 32 bit
+@@ -289,7 +289,7 @@ static void zynq_qspi_txfifo_op(struct z
+  */
+ static void zynq_qspi_chipselect(struct spi_device *spi, bool assert)
+ {
+-      struct spi_controller *ctlr = spi->master;
++      struct spi_controller *ctlr = spi->controller;
+       struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
+       u32 config_reg;
+@@ -377,7 +377,7 @@ static int zynq_qspi_config_op(struct zy
+  */
+ static int zynq_qspi_setup_op(struct spi_device *spi)
+ {
+-      struct spi_controller *ctlr = spi->master;
++      struct spi_controller *ctlr = spi->controller;
+       struct zynq_qspi *qspi = spi_controller_get_devdata(ctlr);
+       int ret;
+@@ -534,7 +534,7 @@ static irqreturn_t zynq_qspi_irq(int irq
+ static int zynq_qspi_exec_mem_op(struct spi_mem *mem,
+                                const struct spi_mem_op *op)
+ {
+-      struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->master);
++      struct zynq_qspi *xqspi = spi_controller_get_devdata(mem->spi->controller);
+       int err = 0, i;
+       u8 *tmpbuf;
+@@ -646,7 +646,7 @@ static int zynq_qspi_probe(struct platfo
+       struct zynq_qspi *xqspi;
+       u32 num_cs;
+-      ctlr = spi_alloc_master(&pdev->dev, sizeof(*xqspi));
++      ctlr = spi_alloc_host(&pdev->dev, sizeof(*xqspi));
+       if (!ctlr)
+               return -ENOMEM;
+@@ -656,14 +656,14 @@ static int zynq_qspi_probe(struct platfo
+       xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(xqspi->regs)) {
+               ret = PTR_ERR(xqspi->regs);
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       xqspi->pclk = devm_clk_get(&pdev->dev, "pclk");
+       if (IS_ERR(xqspi->pclk)) {
+               dev_err(&pdev->dev, "pclk clock not found.\n");
+               ret = PTR_ERR(xqspi->pclk);
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       init_completion(&xqspi->data_completion);
+@@ -672,13 +672,13 @@ static int zynq_qspi_probe(struct platfo
+       if (IS_ERR(xqspi->refclk)) {
+               dev_err(&pdev->dev, "ref_clk clock not found.\n");
+               ret = PTR_ERR(xqspi->refclk);
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       ret = clk_prepare_enable(xqspi->pclk);
+       if (ret) {
+               dev_err(&pdev->dev, "Unable to enable APB clock.\n");
+-              goto remove_master;
++              goto remove_ctlr;
+       }
+       ret = clk_prepare_enable(xqspi->refclk);
+@@ -724,7 +724,7 @@ static int zynq_qspi_probe(struct platfo
+       ret = devm_spi_register_controller(&pdev->dev, ctlr);
+       if (ret) {
+-              dev_err(&pdev->dev, "spi_register_master failed\n");
++              dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
+               goto clk_dis_all;
+       }
+@@ -734,7 +734,7 @@ clk_dis_all:
+       clk_disable_unprepare(xqspi->refclk);
+ clk_dis_pclk:
+       clk_disable_unprepare(xqspi->pclk);
+-remove_master:
++remove_ctlr:
+       spi_controller_put(ctlr);
+       return ret;
diff --git a/queue-6.1/thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch b/queue-6.1/thunderbolt-property-cap-recursion-depth-in-__tb_property_parse_dir.patch
new file mode 100644 (file)
index 0000000..8c3b82b
--- /dev/null
@@ -0,0 +1,112 @@
+From stable+bounces-260814-greg=kroah.com@vger.kernel.org Sat Jun  6 01:20:34 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:50:25 -0400
+Subject: thunderbolt: property: Cap recursion depth in __tb_property_parse_dir()
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Mika Westerberg <mika.westerberg@linux.intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605195025.2190023-1-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit 928abe19fbf0127003abcb1ea69cabc1c897d0ab ]
+
+A DIRECTORY entry's value field is used as the dir_offset for a
+recursive call into __tb_property_parse_dir() with no depth counter.
+A crafted peer that chains DIRECTORY entries into a back-reference
+loop drives the parser until the kernel stack is exhausted and the
+guard page fires.  Any untrusted XDomain peer (cable, dock, in-line
+inspector, adjacent host) that reaches the PROPERTIES_REQUEST
+control-plane exchange can trigger this without authentication.
+
+Thread a depth counter through tb_property_parse() and
+__tb_property_parse_dir(), and reject blocks that exceed
+TB_PROPERTY_MAX_DEPTH = 8.  That is comfortably larger than any
+observed legitimate XDomain layout.
+
+Operators who do not need XDomain host-to-host discovery can disable
+the path entirely with thunderbolt.xdomain=0 on the kernel command
+line.
+
+Fixes: cdae7c07e3e3 ("thunderbolt: Add support for XDomain properties")
+Cc: stable@vger.kernel.org
+Assisted-by: Claude:claude-opus-4-6
+Assisted-by: Codex:gpt-5-4
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/thunderbolt/property.c |   18 ++++++++++++------
+ 1 file changed, 12 insertions(+), 6 deletions(-)
+
+--- a/drivers/thunderbolt/property.c
++++ b/drivers/thunderbolt/property.c
+@@ -35,10 +35,11 @@ struct tb_property_dir_entry {
+ };
+ #define TB_PROPERTY_ROOTDIR_MAGIC     0x55584401
++#define TB_PROPERTY_MAX_DEPTH         8
+ static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
+       size_t block_len, unsigned int dir_offset, size_t dir_len,
+-      bool is_root);
++      bool is_root, unsigned int depth);
+ static inline void parse_dwdata(void *dst, const void *src, size_t dwords)
+ {
+@@ -99,7 +100,8 @@ tb_property_alloc(const char *key, enum
+ }
+ static struct tb_property *tb_property_parse(const u32 *block, size_t block_len,
+-                                      const struct tb_property_entry *entry)
++                                      const struct tb_property_entry *entry,
++                                      unsigned int depth)
+ {
+       char key[TB_PROPERTY_KEY_SIZE + 1];
+       struct tb_property *property;
+@@ -120,7 +122,7 @@ static struct tb_property *tb_property_p
+       switch (property->type) {
+       case TB_PROPERTY_TYPE_DIRECTORY:
+               dir = __tb_property_parse_dir(block, block_len, entry->value,
+-                                            entry->length, false);
++                                            entry->length, false, depth + 1);
+               if (!dir) {
+                       kfree(property);
+                       return NULL;
+@@ -165,13 +167,17 @@ static struct tb_property *tb_property_p
+ }
+ static struct tb_property_dir *__tb_property_parse_dir(const u32 *block,
+-      size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root)
++      size_t block_len, unsigned int dir_offset, size_t dir_len, bool is_root,
++      unsigned int depth)
+ {
+       const struct tb_property_entry *entries;
+       size_t i, content_len, nentries;
+       unsigned int content_offset;
+       struct tb_property_dir *dir;
++      if (depth > TB_PROPERTY_MAX_DEPTH)
++              return NULL;
++
+       dir = kzalloc(sizeof(*dir), GFP_KERNEL);
+       if (!dir)
+               return NULL;
+@@ -206,7 +212,7 @@ static struct tb_property_dir *__tb_prop
+       for (i = 0; i < nentries; i++) {
+               struct tb_property *property;
+-              property = tb_property_parse(block, block_len, &entries[i]);
++              property = tb_property_parse(block, block_len, &entries[i], depth);
+               if (!property) {
+                       tb_property_free_dir(dir);
+                       return NULL;
+@@ -243,7 +249,7 @@ struct tb_property_dir *tb_property_pars
+               return NULL;
+       return __tb_property_parse_dir(block, block_len, 0, rootdir->length,
+-                                     true);
++                                     true, 0);
+ }
+ /**
diff --git a/queue-6.1/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch b/queue-6.1/tracepoint-balance-regfunc-on-func_add-failure-in-tracepoint_add_func.patch
new file mode 100644 (file)
index 0000000..cfe0f60
--- /dev/null
@@ -0,0 +1,56 @@
+From stable+bounces-245090-greg=kroah.com@vger.kernel.org Mon May 11 05:40:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 May 2026 20:10:41 -0400
+Subject: tracepoint: balance regfunc() on func_add() failure in tracepoint_add_func()
+To: stable@vger.kernel.org
+Cc: David Carlier <devnexen@gmail.com>, Masami Hiramatsu <mhiramat@kernel.org>, Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, "Steven Rostedt (Google)" <rostedt@goodmis.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260511001041.752593-1-sashal@kernel.org>
+
+From: David Carlier <devnexen@gmail.com>
+
+[ Upstream commit fad217e16fded7f3c09f8637b0f6a224d58b5f2e ]
+
+When a tracepoint goes through the 0 -> 1 transition, tracepoint_add_func()
+invokes the subsystem's ext->regfunc() before attempting to install the
+new probe via func_add(). If func_add() then fails (for example, when
+allocate_probes() cannot allocate a new probe array under memory pressure
+and returns -ENOMEM), the function returns the error without calling the
+matching ext->unregfunc(), leaving the side effects of regfunc() behind
+with no installed probe to justify them.
+
+For syscall tracepoints this is particularly unpleasant: syscall_regfunc()
+bumps sys_tracepoint_refcount and sets SYSCALL_TRACEPOINT on every task.
+After a leaked failure, the refcount is stuck at a non-zero value with no
+consumer, and every task continues paying the syscall trace entry/exit
+overhead until reboot. Other subsystems providing regfunc()/unregfunc()
+pairs exhibit similarly scoped persistent state.
+
+Mirror the existing 1 -> 0 cleanup and call ext->unregfunc() in the
+func_add() error path, gated on the same condition used there so the
+unwind is symmetric with the registration.
+
+Fixes: 8cf868affdc4 ("tracing: Have the reg function allow to fail")
+Cc: stable@vger.kernel.org
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Link: https://patch.msgid.link/20260413190601.21993-1-devnexen@gmail.com
+Signed-off-by: David Carlier <devnexen@gmail.com>
+Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
+[ changed `tp->ext->unregfunc` to `tp->unregfunc` to match older struct layout ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/tracepoint.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/kernel/tracepoint.c
++++ b/kernel/tracepoint.c
+@@ -337,6 +337,8 @@ static int tracepoint_add_func(struct tr
+                       lockdep_is_held(&tracepoints_mutex));
+       old = func_add(&tp_funcs, func, prio);
+       if (IS_ERR(old)) {
++              if (tp->unregfunc && !static_key_enabled(&tp->key))
++                      tp->unregfunc();
+               WARN_ON_ONCE(warn && PTR_ERR(old) != -ENOMEM);
+               return PTR_ERR(old);
+       }
diff --git a/queue-6.1/tracing-probes-limit-size-of-event-probe-to-3k.patch b/queue-6.1/tracing-probes-limit-size-of-event-probe-to-3k.patch
new file mode 100644 (file)
index 0000000..28d2ceb
--- /dev/null
@@ -0,0 +1,70 @@
+From stable+bounces-247799-greg=kroah.com@vger.kernel.org Fri May 15 20:26:35 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 15 May 2026 10:48:40 -0400
+Subject: tracing/probes: Limit size of event probe to 3K
+To: stable@vger.kernel.org
+Cc: Steven Rostedt <rostedt@goodmis.org>, Mathieu Desnoyers <mathieu.desnoyers@efficios.com>, "Masami Hiramatsu (Google)" <mhiramat@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260515144840.3249487-1-sashal@kernel.org>
+
+From: Steven Rostedt <rostedt@goodmis.org>
+
+[ Upstream commit b2aa3b4d64e460ac606f386c24e7d8a873ce6f1a ]
+
+There currently isn't a max limit an event probe can be. One could make an
+event greater than PAGE_SIZE, which makes the event useless because if
+it's bigger than the max event that can be recorded into the ring buffer,
+then it will never be recorded.
+
+A event probe should never need to be greater than 3K, so make that the
+max size. As long as the max is less than the max that can be recorded
+onto the ring buffer, it should be fine.
+
+Cc: stable@vger.kernel.org
+Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
+Fixes: 93ccae7a22274 ("tracing/kprobes: Support basic types on dynamic events")
+Link: https://patch.msgid.link/20260428122302.706610ba@gandalf.local.home
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+[ changed `ctx->offset` to `offset` and `goto fail` to `goto out` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ kernel/trace/trace_probe.c |    6 ++++++
+ kernel/trace/trace_probe.h |    4 +++-
+ 2 files changed, 9 insertions(+), 1 deletion(-)
+
+--- a/kernel/trace/trace_probe.c
++++ b/kernel/trace/trace_probe.c
+@@ -651,6 +651,12 @@ static int traceprobe_parse_probe_arg_bo
+       parg->offset = *size;
+       *size += parg->type->size * (parg->count ?: 1);
++      if (*size > MAX_PROBE_EVENT_SIZE) {
++              ret = -E2BIG;
++              trace_probe_log_err(offset, EVENT_TOO_BIG);
++              goto out;
++      }
++
+       ret = -ENOMEM;
+       if (parg->count) {
+               len = strlen(parg->type->fmttype) + 6;
+--- a/kernel/trace/trace_probe.h
++++ b/kernel/trace/trace_probe.h
+@@ -33,6 +33,7 @@
+ #define MAX_ARRAY_LEN         64
+ #define MAX_ARG_NAME_LEN      32
+ #define MAX_STRING_SIZE               PATH_MAX
++#define MAX_PROBE_EVENT_SIZE  3072
+ /* Reserved field names */
+ #define FIELD_STRING_IP               "__probe_ip"
+@@ -458,7 +459,8 @@ extern int traceprobe_define_arg_fields(
+       C(NO_EVENT_INFO,        "This requires both group and event name to attach"),\
+       C(BAD_ATTACH_EVENT,     "Attached event does not exist"),\
+       C(BAD_ATTACH_ARG,       "Attached event does not have this field"),\
+-      C(NO_EP_FILTER,         "No filter rule after 'if'"),
++      C(NO_EP_FILTER,         "No filter rule after 'if'"),           \
++      C(EVENT_TOO_BIG,        "Event too big (too many fields?)"),
+ #undef C
+ #define C(a, b)               TP_ERR_##a
diff --git a/queue-6.1/tty-serial-qcom-geni-serial-align-define-values.patch b/queue-6.1/tty-serial-qcom-geni-serial-align-define-values.patch
new file mode 100644 (file)
index 0000000..2cdcb39
--- /dev/null
@@ -0,0 +1,115 @@
+From stable+bounces-260846-greg=kroah.com@vger.kernel.org Sat Jun  6 08:19:26 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 22:47:08 -0400
+Subject: tty: serial: qcom-geni-serial: align #define values
+To: stable@vger.kernel.org
+Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>, Konrad Dybcio <konrad.dybcio@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606024709.2514691-2-sashal@kernel.org>
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 6cde11dbf4b65170eeefba48df730c93d75e01a3 ]
+
+Keep the #define symbols aligned for better readability.
+
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20221229155030.418800-5-brgl@bgdev.pl
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: ca2584d841b6 ("serial: qcom-geni: fix UART_RX_PAR_EN bit position")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c |   60 +++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 30 deletions(-)
+
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -39,57 +39,57 @@
+ #define SE_UART_MANUAL_RFR            0x2ac
+ /* SE_UART_TRANS_CFG */
+-#define UART_TX_PAR_EN                BIT(0)
+-#define UART_CTS_MASK         BIT(1)
++#define UART_TX_PAR_EN                        BIT(0)
++#define UART_CTS_MASK                 BIT(1)
+ /* SE_UART_TX_STOP_BIT_LEN */
+-#define TX_STOP_BIT_LEN_1     0
+-#define TX_STOP_BIT_LEN_2     2
++#define TX_STOP_BIT_LEN_1             0
++#define TX_STOP_BIT_LEN_2             2
+ /* SE_UART_RX_TRANS_CFG */
+-#define UART_RX_PAR_EN                BIT(3)
++#define UART_RX_PAR_EN                        BIT(3)
+ /* SE_UART_RX_WORD_LEN */
+-#define RX_WORD_LEN_MASK      GENMASK(9, 0)
++#define RX_WORD_LEN_MASK              GENMASK(9, 0)
+ /* SE_UART_RX_STALE_CNT */
+-#define RX_STALE_CNT          GENMASK(23, 0)
++#define RX_STALE_CNT                  GENMASK(23, 0)
+ /* SE_UART_TX_PARITY_CFG/RX_PARITY_CFG */
+-#define PAR_CALC_EN           BIT(0)
+-#define PAR_EVEN              0x00
+-#define PAR_ODD                       0x01
+-#define PAR_SPACE             0x10
++#define PAR_CALC_EN                   BIT(0)
++#define PAR_EVEN                      0x00
++#define PAR_ODD                               0x01
++#define PAR_SPACE                     0x10
+ /* SE_UART_MANUAL_RFR register fields */
+-#define UART_MANUAL_RFR_EN    BIT(31)
+-#define UART_RFR_NOT_READY    BIT(1)
+-#define UART_RFR_READY                BIT(0)
++#define UART_MANUAL_RFR_EN            BIT(31)
++#define UART_RFR_NOT_READY            BIT(1)
++#define UART_RFR_READY                        BIT(0)
+ /* UART M_CMD OP codes */
+-#define UART_START_TX         0x1
++#define UART_START_TX                 0x1
+ /* UART S_CMD OP codes */
+-#define UART_START_READ               0x1
++#define UART_START_READ                       0x1
+-#define UART_OVERSAMPLING     32
+-#define STALE_TIMEOUT         16
+-#define DEFAULT_BITS_PER_CHAR 10
+-#define GENI_UART_CONS_PORTS  1
+-#define GENI_UART_PORTS               3
+-#define DEF_FIFO_DEPTH_WORDS  16
+-#define DEF_TX_WM             2
+-#define DEF_FIFO_WIDTH_BITS   32
+-#define UART_RX_WM            2
++#define UART_OVERSAMPLING             32
++#define STALE_TIMEOUT                 16
++#define DEFAULT_BITS_PER_CHAR         10
++#define GENI_UART_CONS_PORTS          1
++#define GENI_UART_PORTS                       3
++#define DEF_FIFO_DEPTH_WORDS          16
++#define DEF_TX_WM                     2
++#define DEF_FIFO_WIDTH_BITS           32
++#define UART_RX_WM                    2
+ /* SE_UART_LOOPBACK_CFG */
+-#define RX_TX_SORTED  BIT(0)
+-#define CTS_RTS_SORTED        BIT(1)
+-#define RX_TX_CTS_RTS_SORTED  (RX_TX_SORTED | CTS_RTS_SORTED)
++#define RX_TX_SORTED                  BIT(0)
++#define CTS_RTS_SORTED                        BIT(1)
++#define RX_TX_CTS_RTS_SORTED          (RX_TX_SORTED | CTS_RTS_SORTED)
+ /* UART pin swap value */
+-#define DEFAULT_IO_MACRO_IO0_IO1_MASK         GENMASK(3, 0)
++#define DEFAULT_IO_MACRO_IO0_IO1_MASK GENMASK(3, 0)
+ #define IO_MACRO_IO0_SEL              0x3
+-#define DEFAULT_IO_MACRO_IO2_IO3_MASK         GENMASK(15, 4)
++#define DEFAULT_IO_MACRO_IO2_IO3_MASK GENMASK(15, 4)
+ #define IO_MACRO_IO2_IO3_SWAP         0x4640
+ /* We always configure 4 bytes per FIFO word */
diff --git a/queue-6.1/tty-serial-qcom-geni-serial-remove-unused-symbols.patch b/queue-6.1/tty-serial-qcom-geni-serial-remove-unused-symbols.patch
new file mode 100644 (file)
index 0000000..b97d6ea
--- /dev/null
@@ -0,0 +1,73 @@
+From stable+bounces-260845-greg=kroah.com@vger.kernel.org Sat Jun  6 08:17:17 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 22:47:07 -0400
+Subject: tty: serial: qcom-geni-serial: remove unused symbols
+To: stable@vger.kernel.org
+Cc: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>, Konrad Dybcio <konrad.dybcio@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606024709.2514691-1-sashal@kernel.org>
+
+From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+
+[ Upstream commit 68c6bd92c86cbc4937834c79963b27c77ee3bf51 ]
+
+Drop all unused symbols from the driver.
+
+Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
+Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
+Link: https://lore.kernel.org/r/20221229155030.418800-4-brgl@bgdev.pl
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: ca2584d841b6 ("serial: qcom-geni: fix UART_RX_PAR_EN bit position")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/qcom_geni_serial.c |   15 ---------------
+ 1 file changed, 15 deletions(-)
+
+--- a/drivers/tty/serial/qcom_geni_serial.c
++++ b/drivers/tty/serial/qcom_geni_serial.c
+@@ -42,20 +42,11 @@
+ #define UART_TX_PAR_EN                BIT(0)
+ #define UART_CTS_MASK         BIT(1)
+-/* SE_UART_TX_WORD_LEN */
+-#define TX_WORD_LEN_MSK               GENMASK(9, 0)
+-
+ /* SE_UART_TX_STOP_BIT_LEN */
+-#define TX_STOP_BIT_LEN_MSK   GENMASK(23, 0)
+ #define TX_STOP_BIT_LEN_1     0
+-#define TX_STOP_BIT_LEN_1_5   1
+ #define TX_STOP_BIT_LEN_2     2
+-/* SE_UART_TX_TRANS_LEN */
+-#define TX_TRANS_LEN_MSK      GENMASK(23, 0)
+-
+ /* SE_UART_RX_TRANS_CFG */
+-#define UART_RX_INS_STATUS_BIT        BIT(2)
+ #define UART_RX_PAR_EN                BIT(3)
+ /* SE_UART_RX_WORD_LEN */
+@@ -66,12 +57,9 @@
+ /* SE_UART_TX_PARITY_CFG/RX_PARITY_CFG */
+ #define PAR_CALC_EN           BIT(0)
+-#define PAR_MODE_MSK          GENMASK(2, 1)
+-#define PAR_MODE_SHFT         1
+ #define PAR_EVEN              0x00
+ #define PAR_ODD                       0x01
+ #define PAR_SPACE             0x10
+-#define PAR_MARK              0x11
+ /* SE_UART_MANUAL_RFR register fields */
+ #define UART_MANUAL_RFR_EN    BIT(31)
+@@ -80,11 +68,8 @@
+ /* UART M_CMD OP codes */
+ #define UART_START_TX         0x1
+-#define UART_START_BREAK      0x4
+-#define UART_STOP_BREAK               0x5
+ /* UART S_CMD OP codes */
+ #define UART_START_READ               0x1
+-#define UART_PARAM            0x1
+ #define UART_OVERSAMPLING     32
+ #define STALE_TIMEOUT         16
diff --git a/queue-6.1/tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch b/queue-6.1/tty-serial-samsung-remove-redundant-port-lock-acquisition-in-rx-helpers.patch
new file mode 100644 (file)
index 0000000..3416851
--- /dev/null
@@ -0,0 +1,85 @@
+From stable+bounces-260728-greg=kroah.com@vger.kernel.org Fri Jun  5 21:15:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 11:31:04 -0400
+Subject: tty: serial: samsung: Remove redundant port lock acquisition in rx helpers
+To: stable@vger.kernel.org
+Cc: Tudor Ambarus <tudor.ambarus@linaro.org>, stable <stable@kernel.org>, John Ogness <john.ogness@linutronix.de>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605153104.1929085-3-sashal@kernel.org>
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit a3bb136bff5e6a5e48cdd813246c9c4686feaaa9 ]
+
+Sashiko identified a deadlock when the console flow is engaged [1].
+
+When console flow control is enabled (UPF_CONS_FLOW),
+s3c24xx_serial_stop_tx() calls s3c24xx_serial_rx_enable() and
+s3c24xx_serial_start_tx() calls s3c24xx_serial_rx_disable().
+
+The serial core framework invokes the .stop_tx() and .start_tx()
+callbacks with the port->lock spinlock already held. Furthermore, all
+internal driver paths that invoke stop_tx (such as the DMA TX
+completion handler s3c24xx_serial_tx_dma_complete() or the PIO TX IRQ
+handler s3c24xx_serial_tx_irq()) also acquire port->lock prior to
+calling it. (Note that s3c24xx_serial_start_tx() is only invoked by the
+serial core).
+
+However, s3c24xx_serial_rx_enable() and s3c24xx_serial_rx_disable()
+unconditionally attempt to acquire port->lock again using
+uart_port_lock_irqsave(). Since spinlocks are not recursive, this
+causes a deadlock on the same CPU when console flow control is engaged.
+
+Remove the redundant lock acquisition from both rx helper functions.
+
+Cc: stable <stable@kernel.org>
+Fixes: b497549a035c ("[ARM] S3C24XX: Split serial driver into core and per-cpu drivers")
+Reported-by: John Ogness <john.ogness@linutronix.de>
+Closes: https://sashiko.dev/#/patchset/20260506121606.5805-1-john.ogness%40linutronix.de [1]
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://patch.msgid.link/20260515-samsung-tty-flow-control-deadlock-v1-1-93255edbc9bc@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c |    8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -247,12 +247,9 @@ static int s3c24xx_serial_txempty_nofifo
+ static void s3c24xx_serial_rx_enable(struct uart_port *port)
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      unsigned long flags;
+       int count = 10000;
+       u32 ucon, ufcon;
+-      uart_port_lock_irqsave(port, &flags);
+-
+       while (--count && !s3c24xx_serial_txempty_nofifo(port))
+               udelay(100);
+@@ -265,23 +262,18 @@ static void s3c24xx_serial_rx_enable(str
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 1;
+-      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_rx_disable(struct uart_port *port)
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      unsigned long flags;
+       u32 ucon;
+-      uart_port_lock_irqsave(port, &flags);
+-
+       ucon = rd_regl(port, S3C2410_UCON);
+       ucon &= ~S3C2410_UCON_RXIRQMODE;
+       wr_regl(port, S3C2410_UCON, ucon);
+       ourport->rx_enabled = 0;
+-      uart_port_unlock_irqrestore(port, flags);
+ }
+ static void s3c24xx_serial_stop_tx(struct uart_port *port)
diff --git a/queue-6.1/tty-serial-samsung-use-u32-for-register-interactions.patch b/queue-6.1/tty-serial-samsung-use-u32-for-register-interactions.patch
new file mode 100644 (file)
index 0000000..f5859c2
--- /dev/null
@@ -0,0 +1,354 @@
+From stable+bounces-260727-greg=kroah.com@vger.kernel.org Fri Jun  5 21:15:51 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 11:31:03 -0400
+Subject: tty: serial: samsung: use u32 for register interactions
+To: stable@vger.kernel.org
+Cc: Tudor Ambarus <tudor.ambarus@linaro.org>, Sam Protsenko <semen.protsenko@linaro.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605153104.1929085-2-sashal@kernel.org>
+
+From: Tudor Ambarus <tudor.ambarus@linaro.org>
+
+[ Upstream commit 032a725c16add79332d774348d7ad7d0d4b86479 ]
+
+All registers of the IP have 32 bits. Use u32 variables when reading
+or writing from/to the registers. The purpose of those variables becomes
+clearer.
+
+Reviewed-by: Sam Protsenko <semen.protsenko@linaro.org>
+Signed-off-by: Tudor Ambarus <tudor.ambarus@linaro.org>
+Link: https://lore.kernel.org/r/20240119104526.1221243-9-tudor.ambarus@linaro.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: a3bb136bff5e ("tty: serial: samsung: Remove redundant port lock acquisition in rx helpers")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/serial/samsung_tty.c |   80 +++++++++++++++++++--------------------
+ 1 file changed, 40 insertions(+), 40 deletions(-)
+
+--- a/drivers/tty/serial/samsung_tty.c
++++ b/drivers/tty/serial/samsung_tty.c
+@@ -202,7 +202,7 @@ static void wr_reg(const struct uart_por
+ /* Byte-order aware bit setting/clearing functions. */
+ static inline void s3c24xx_set_bit(const struct uart_port *port, int idx,
+-                                 unsigned int reg)
++                                 u32 reg)
+ {
+       unsigned long flags;
+       u32 val;
+@@ -215,7 +215,7 @@ static inline void s3c24xx_set_bit(const
+ }
+ static inline void s3c24xx_clear_bit(const struct uart_port *port, int idx,
+-                                   unsigned int reg)
++                                   u32 reg)
+ {
+       unsigned long flags;
+       u32 val;
+@@ -248,8 +248,8 @@ static void s3c24xx_serial_rx_enable(str
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       unsigned long flags;
+-      unsigned int ucon, ufcon;
+       int count = 10000;
++      u32 ucon, ufcon;
+       uart_port_lock_irqsave(port, &flags);
+@@ -272,7 +272,7 @@ static void s3c24xx_serial_rx_disable(st
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       unsigned long flags;
+-      unsigned int ucon;
++      u32 ucon;
+       uart_port_lock_irqsave(port, &flags);
+@@ -597,7 +597,7 @@ static inline const struct s3c2410_uartc
+ }
+ static int s3c24xx_serial_rx_fifocnt(const struct s3c24xx_uart_port *ourport,
+-                                   unsigned long ufstat)
++                                   u32 ufstat)
+ {
+       const struct s3c24xx_uart_info *info = ourport->info;
+@@ -669,7 +669,7 @@ static void s3c64xx_start_rx_dma(struct
+ static void enable_rx_dma(struct s3c24xx_uart_port *ourport)
+ {
+       struct uart_port *port = &ourport->port;
+-      unsigned int ucon;
++      u32 ucon;
+       /* set Rx mode to DMA mode */
+       ucon = rd_regl(port, S3C2410_UCON);
+@@ -692,7 +692,7 @@ static void enable_rx_dma(struct s3c24xx
+ static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
+ {
+       struct uart_port *port = &ourport->port;
+-      unsigned int ucon;
++      u32 ucon;
+       /* set Rx mode to DMA mode */
+       ucon = rd_regl(port, S3C2410_UCON);
+@@ -717,13 +717,14 @@ static void s3c24xx_serial_rx_drain_fifo
+ static irqreturn_t s3c24xx_serial_rx_chars_dma(void *dev_id)
+ {
+-      unsigned int utrstat, received;
+       struct s3c24xx_uart_port *ourport = dev_id;
+       struct uart_port *port = &ourport->port;
+       struct s3c24xx_uart_dma *dma = ourport->dma;
+       struct tty_struct *tty = tty_port_tty_get(&ourport->port.state->port);
+       struct tty_port *t = &port->state->port;
+       struct dma_tx_state state;
++      unsigned int received;
++      u32 utrstat;
+       utrstat = rd_regl(port, S3C2410_UTRSTAT);
+       rd_regl(port, S3C2410_UFSTAT);
+@@ -765,9 +766,10 @@ finish:
+ static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport)
+ {
+       struct uart_port *port = &ourport->port;
+-      unsigned int ufcon, ch, flag, ufstat, uerstat;
+       unsigned int fifocnt = 0;
+       int max_count = port->fifosize;
++      u32 ufcon, ufstat, uerstat;
++      u8 ch, flag;
+       while (max_count-- > 0) {
+               /*
+@@ -951,7 +953,7 @@ static irqreturn_t s3c64xx_serial_handle
+ {
+       const struct s3c24xx_uart_port *ourport = id;
+       const struct uart_port *port = &ourport->port;
+-      unsigned int pend = rd_regl(port, S3C64XX_UINTP);
++      u32 pend = rd_regl(port, S3C64XX_UINTP);
+       irqreturn_t ret = IRQ_HANDLED;
+       if (pend & S3C64XX_UINTM_RXD_MSK) {
+@@ -970,7 +972,7 @@ static irqreturn_t apple_serial_handle_i
+ {
+       const struct s3c24xx_uart_port *ourport = id;
+       const struct uart_port *port = &ourport->port;
+-      unsigned int pend = rd_regl(port, S3C2410_UTRSTAT);
++      u32 pend = rd_regl(port, S3C2410_UTRSTAT);
+       irqreturn_t ret = IRQ_NONE;
+       if (pend & (APPLE_S5L_UTRSTAT_RXTHRESH | APPLE_S5L_UTRSTAT_RXTO)) {
+@@ -989,8 +991,8 @@ static irqreturn_t apple_serial_handle_i
+ static unsigned int s3c24xx_serial_tx_empty(struct uart_port *port)
+ {
+       const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned long ufstat = rd_regl(port, S3C2410_UFSTAT);
+-      unsigned long ufcon = rd_regl(port, S3C2410_UFCON);
++      u32 ufstat = rd_regl(port, S3C2410_UFSTAT);
++      u32 ufcon = rd_regl(port, S3C2410_UFCON);
+       if (ufcon & S3C2410_UFCON_FIFOMODE) {
+               if ((ufstat & info->tx_fifomask) != 0 ||
+@@ -1005,7 +1007,7 @@ static unsigned int s3c24xx_serial_tx_em
+ /* no modem control lines */
+ static unsigned int s3c24xx_serial_get_mctrl(struct uart_port *port)
+ {
+-      unsigned int umstat = rd_reg(port, S3C2410_UMSTAT);
++      u32 umstat = rd_reg(port, S3C2410_UMSTAT);
+       if (umstat & S3C2410_UMSTAT_CTS)
+               return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+@@ -1015,8 +1017,8 @@ static unsigned int s3c24xx_serial_get_m
+ static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
+ {
+-      unsigned int umcon = rd_regl(port, S3C2410_UMCON);
+-      unsigned int ucon = rd_regl(port, S3C2410_UCON);
++      u32 umcon = rd_regl(port, S3C2410_UMCON);
++      u32 ucon = rd_regl(port, S3C2410_UCON);
+       if (mctrl & TIOCM_RTS)
+               umcon |= S3C2410_UMCOM_RTS_LOW;
+@@ -1036,7 +1038,7 @@ static void s3c24xx_serial_set_mctrl(str
+ static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
+ {
+       unsigned long flags;
+-      unsigned int ucon;
++      u32 ucon;
+       uart_port_lock_irqsave(port, &flags);
+@@ -1217,7 +1219,7 @@ static void apple_s5l_serial_shutdown(st
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      unsigned int ucon;
++      u32 ucon;
+       ucon = rd_regl(port, S3C2410_UCON);
+       ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
+@@ -1285,7 +1287,7 @@ static int s3c64xx_serial_startup(struct
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       unsigned long flags;
+-      unsigned int ufcon;
++      u32 ufcon;
+       int ret;
+       wr_regl(port, S3C64XX_UINTM, 0xf);
+@@ -1330,7 +1332,7 @@ static int apple_s5l_serial_startup(stru
+ {
+       struct s3c24xx_uart_port *ourport = to_ourport(port);
+       unsigned long flags;
+-      unsigned int ufcon;
++      u32 ufcon;
+       int ret;
+       wr_regl(port, S3C2410_UTRSTAT, APPLE_S5L_UTRSTAT_ALL_FLAGS);
+@@ -1415,7 +1417,7 @@ static void s3c24xx_serial_pm(struct uar
+ static inline int s3c24xx_serial_getsource(struct uart_port *port)
+ {
+       const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned int ucon;
++      u32 ucon;
+       if (info->num_clks == 1)
+               return 0;
+@@ -1429,7 +1431,7 @@ static void s3c24xx_serial_setsource(str
+                       unsigned int clk_sel)
+ {
+       const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned int ucon;
++      u32 ucon;
+       if (info->num_clks == 1)
+               return;
+@@ -1548,9 +1550,8 @@ static void s3c24xx_serial_set_termios(s
+       struct clk *clk = ERR_PTR(-EINVAL);
+       unsigned long flags;
+       unsigned int baud, quot, clk_sel = 0;
+-      unsigned int ulcon;
+-      unsigned int umcon;
+       unsigned int udivslot = 0;
++      u32 ulcon, umcon;
+       /*
+        * We don't support modem control lines.
+@@ -1857,7 +1858,7 @@ static void s3c24xx_serial_resetport(str
+                                    const struct s3c2410_uartcfg *cfg)
+ {
+       const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned long ucon = rd_regl(port, S3C2410_UCON);
++      u32 ucon = rd_regl(port, S3C2410_UCON);
+       ucon &= (info->clksel_mask | info->ucon_mask);
+       wr_regl(port, S3C2410_UCON, ucon | cfg->ucon);
+@@ -2100,7 +2101,7 @@ static int s3c24xx_serial_init_port(stru
+               wr_regl(port, S3C64XX_UINTSP, 0xf);
+               break;
+       case TYPE_APPLE_S5L: {
+-              unsigned int ucon;
++              u32 ucon;
+               ucon = rd_regl(port, S3C2410_UCON);
+               ucon &= ~(APPLE_S5L_UCON_TXTHRESH_ENA_MSK |
+@@ -2312,7 +2313,7 @@ static int s3c24xx_serial_resume_noirq(s
+               /* restore IRQ mask */
+               switch (ourport->info->type) {
+               case TYPE_S3C6400: {
+-                      unsigned int uintm = 0xf;
++                      u32 uintm = 0xf;
+                       if (ourport->tx_enabled)
+                               uintm &= ~S3C64XX_UINTM_TXD_MSK;
+@@ -2328,7 +2329,7 @@ static int s3c24xx_serial_resume_noirq(s
+                       break;
+               }
+               case TYPE_APPLE_S5L: {
+-                      unsigned int ucon;
++                      u32 ucon;
+                       int ret;
+                       ret = clk_prepare_enable(ourport->clk);
+@@ -2391,10 +2392,10 @@ static const struct dev_pm_ops s3c24xx_s
+ static struct uart_port *cons_uart;
+ static int
+-s3c24xx_serial_console_txrdy(struct uart_port *port, unsigned int ufcon)
++s3c24xx_serial_console_txrdy(struct uart_port *port, u32 ufcon)
+ {
+       const struct s3c24xx_uart_info *info = s3c24xx_port_to_info(port);
+-      unsigned long ufstat, utrstat;
++      u32 ufstat, utrstat;
+       if (ufcon & S3C2410_UFCON_FIFOMODE) {
+               /* fifo mode - check amount of data in fifo registers... */
+@@ -2410,7 +2411,7 @@ s3c24xx_serial_console_txrdy(struct uart
+ }
+ static bool
+-s3c24xx_port_configured(unsigned int ucon)
++s3c24xx_port_configured(u32 ucon)
+ {
+       /* consider the serial port configured if the tx/rx mode set */
+       return (ucon & 0xf) != 0;
+@@ -2425,7 +2426,7 @@ s3c24xx_port_configured(unsigned int uco
+ static int s3c24xx_serial_get_poll_char(struct uart_port *port)
+ {
+       const struct s3c24xx_uart_port *ourport = to_ourport(port);
+-      unsigned int ufstat;
++      u32 ufstat;
+       ufstat = rd_regl(port, S3C2410_UFSTAT);
+       if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0)
+@@ -2437,8 +2438,8 @@ static int s3c24xx_serial_get_poll_char(
+ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
+               unsigned char c)
+ {
+-      unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
+-      unsigned int ucon = rd_regl(port, S3C2410_UCON);
++      u32 ufcon = rd_regl(port, S3C2410_UFCON);
++      u32 ucon = rd_regl(port, S3C2410_UCON);
+       /* not possible to xmit on unconfigured port */
+       if (!s3c24xx_port_configured(ucon))
+@@ -2454,7 +2455,7 @@ static void s3c24xx_serial_put_poll_char
+ static void
+ s3c24xx_serial_console_putchar(struct uart_port *port, unsigned char ch)
+ {
+-      unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
++      u32 ufcon = rd_regl(port, S3C2410_UFCON);
+       while (!s3c24xx_serial_console_txrdy(port, ufcon))
+               cpu_relax();
+@@ -2465,7 +2466,7 @@ static void
+ s3c24xx_serial_console_write(struct console *co, const char *s,
+                            unsigned int count)
+ {
+-      unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
++      u32 ucon = rd_regl(cons_uart, S3C2410_UCON);
+       unsigned long flags;
+       bool locked = true;
+@@ -2492,11 +2493,9 @@ s3c24xx_serial_get_options(struct uart_p
+                          int *parity, int *bits)
+ {
+       struct clk *clk;
+-      unsigned int ulcon;
+-      unsigned int ucon;
+-      unsigned int ubrdiv;
+       unsigned long rate;
+       unsigned int clk_sel;
++      u32 ulcon, ucon, ubrdiv;
+       char clk_name[MAX_CLK_NAME_LENGTH];
+       ulcon  = rd_regl(port, S3C2410_ULCON);
+@@ -3010,7 +3009,8 @@ static int samsung_early_read(struct con
+ {
+       struct earlycon_device *dev = con->data;
+       const struct samsung_early_console_data *data = dev->port.private_data;
+-      int ch, ufstat, num_read = 0;
++      int num_read = 0;
++      u32 ch, ufstat;
+       while (num_read < n) {
+               ufstat = rd_regl(&dev->port, S3C2410_UFSTAT);
diff --git a/queue-6.1/udf-fix-partition-descriptor-append-bookkeeping.patch b/queue-6.1/udf-fix-partition-descriptor-append-bookkeeping.patch
new file mode 100644 (file)
index 0000000..cc972eb
--- /dev/null
@@ -0,0 +1,61 @@
+From stable+bounces-244831-greg=kroah.com@vger.kernel.org Sat May  9 02:47:36 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 17:17:31 -0400
+Subject: udf: fix partition descriptor append bookkeeping
+To: stable@vger.kernel.org
+Cc: Seohyeon Maeng <bioloidgp@gmail.com>, Jan Kara <jack@suse.cz>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260508211731.1959991-1-sashal@kernel.org>
+
+From: Seohyeon Maeng <bioloidgp@gmail.com>
+
+[ Upstream commit 08841b06fa64d8edbd1a21ca6e613420c90cc4b8 ]
+
+Mounting a crafted UDF image with repeated partition descriptors can
+trigger a heap out-of-bounds write in part_descs_loc[].
+
+handle_partition_descriptor() deduplicates entries by partition number,
+but appended slots never record partnum. As a result duplicate
+Partition Descriptors are appended repeatedly and num_part_descs keeps
+growing.
+
+Once the table is full, the growth path still sizes the allocation from
+partnum even though inserts are indexed by num_part_descs. If partnum is
+already aligned to PART_DESC_ALLOC_STEP, ALIGN(partnum, step) can keep
+the old capacity and the next append writes past the end of the table.
+
+Store partnum in the appended slot and size growth from the next append
+count so deduplication and capacity tracking follow the same model.
+
+Fixes: ee4af50ca94f ("udf: Fix mounting of Win7 created UDF filesystems")
+Cc: stable@vger.kernel.org
+Signed-off-by: Seohyeon Maeng <bioloidgp@gmail.com>
+Link: https://patch.msgid.link/20260310081652.21220-1-bioloidgp@gmail.com
+Signed-off-by: Jan Kara <jack@suse.cz>
+[ replaced kzalloc_objs() helper with equivalent kcalloc() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/udf/super.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -1657,8 +1657,9 @@ static struct udf_vds_record *handle_par
+                       return &(data->part_descs_loc[i].rec);
+       if (data->num_part_descs >= data->size_part_descs) {
+               struct part_desc_seq_scan_data *new_loc;
+-              unsigned int new_size = ALIGN(partnum, PART_DESC_ALLOC_STEP);
++              unsigned int new_size;
++              new_size = data->num_part_descs + PART_DESC_ALLOC_STEP;
+               new_loc = kcalloc(new_size, sizeof(*new_loc), GFP_KERNEL);
+               if (!new_loc)
+                       return ERR_PTR(-ENOMEM);
+@@ -1668,6 +1669,7 @@ static struct udf_vds_record *handle_par
+               data->part_descs_loc = new_loc;
+               data->size_part_descs = new_size;
+       }
++      data->part_descs_loc[data->num_part_descs].partnum = partnum;
+       return &(data->part_descs_loc[data->num_part_descs++].rec);
+ }
diff --git a/queue-6.1/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch b/queue-6.1/usb-cdns3-plat-fix-leaked-usb2_phy-initialization-on-usb3_phy-acquisition-failure.patch
new file mode 100644 (file)
index 0000000..43691f7
--- /dev/null
@@ -0,0 +1,48 @@
+From stable+bounces-260594-greg=kroah.com@vger.kernel.org Fri Jun  5 06:05:07 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu,  4 Jun 2026 20:34:56 -0400
+Subject: usb: cdns3: plat: fix leaked usb2_phy initialization on usb3_phy acquisition failure
+To: stable@vger.kernel.org
+Cc: Peter Chen <peter.chen@cixtech.com>, stable <stable@kernel.org>, sashiko-bot <sashiko-bot@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605003456.2707466-1-sashal@kernel.org>
+
+From: Peter Chen <peter.chen@cixtech.com>
+
+[ Upstream commit e6970cda63fd4b4546aeed9d0e2f53a7c95cd09c ]
+
+Move usb2_phy initialization after usb3_phy acquisition.
+
+Fixes: f738957277ba ("usb: cdns3: Split core.c into cdns3-plat and core.c file")
+Cc: stable <stable@kernel.org>
+Reported-by: sashiko-bot <sashiko-bot@kernel.org>
+Closes: https://lore.kernel.org/linux-devicetree/agKaEePSFknhDBg2@nchen-desktop/T/#m21e1d9c1574eb127ce03c0c2a1a49002ce435b52
+Signed-off-by: Peter Chen <peter.chen@cixtech.com>
+Link: https://patch.msgid.link/20260513085310.2217547-2-peter.chen@cixtech.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/cdns3/cdns3-plat.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/cdns3/cdns3-plat.c
++++ b/drivers/usb/cdns3/cdns3-plat.c
+@@ -120,14 +120,14 @@ static int cdns3_plat_probe(struct platf
+       if (IS_ERR(cdns->usb2_phy))
+               return PTR_ERR(cdns->usb2_phy);
+-      ret = phy_init(cdns->usb2_phy);
+-      if (ret)
+-              return ret;
+-
+       cdns->usb3_phy = devm_phy_optional_get(dev, "cdns3,usb3-phy");
+       if (IS_ERR(cdns->usb3_phy))
+               return PTR_ERR(cdns->usb3_phy);
++      ret = phy_init(cdns->usb2_phy);
++      if (ret)
++              return ret;
++
+       ret = phy_init(cdns->usb3_phy);
+       if (ret)
+               goto err_phy3_init;
diff --git a/queue-6.1/usb-dwc3-move-guid-programming-after-phy-initialization.patch b/queue-6.1/usb-dwc3-move-guid-programming-after-phy-initialization.patch
new file mode 100644 (file)
index 0000000..5712ddc
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-246864-greg=kroah.com@vger.kernel.org Wed May 13 19:27:04 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 09:32:57 -0400
+Subject: usb: dwc3: Move GUID programming after PHY initialization
+To: stable@vger.kernel.org
+Cc: Selvarasu Ganesan <selvarasu.g@samsung.com>, stable <stable@kernel.org>, Pritam Manohar Sutar <pritam.sutar@samsung.com>, Thinh Nguyen <Thinh.Nguyen@synopsys.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513133257.3732683-1-sashal@kernel.org>
+
+From: Selvarasu Ganesan <selvarasu.g@samsung.com>
+
+[ Upstream commit aad35f9c926ec220b0742af1ada45666ae667956 ]
+
+The Linux Version Code is currently written to the GUID register before
+PHY initialization. Certain PHY implementations (such as Synopsys eUSB
+PHY performing link_sw_reset) clear the GUID register to its default
+value during initialization, causing the kernel version information to
+be lost.
+
+Move the GUID register programming to occur after PHY initialization
+completes to ensure the Linux version information persists.
+
+Fixes: fa0ea13e9f1c ("usb: dwc3: core: write LINUX_VERSION_CODE to our GUID register")
+Cc: stable <stable@kernel.org>
+Reported-by: Pritam Manohar Sutar <pritam.sutar@samsung.com>
+Signed-off-by: Selvarasu Ganesan <selvarasu.g@samsung.com>
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Link: https://patch.msgid.link/20260417063314.2359-1-selvarasu.g@samsung.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ adapted dwc3_writel(dwc, ...) to dwc3_writel(dwc->regs, ...) ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/core.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -1239,12 +1239,6 @@ static int dwc3_core_init(struct dwc3 *d
+       hw_mode = DWC3_GHWPARAMS0_MODE(dwc->hwparams.hwparams0);
+-      /*
+-       * Write Linux Version Code to our GUID register so it's easy to figure
+-       * out which kernel version a bug was found.
+-       */
+-      dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
+-
+       ret = dwc3_phy_setup(dwc);
+       if (ret)
+               goto err0;
+@@ -1284,6 +1278,12 @@ static int dwc3_core_init(struct dwc3 *d
+       if (ret)
+               goto err1;
++      /*
++       * Write Linux Version Code to our GUID register so it's easy to figure
++       * out which kernel version a bug was found.
++       */
++      dwc3_writel(dwc->regs, DWC3_GUID, LINUX_VERSION_CODE);
++
+       dwc3_core_setup_global_control(dwc);
+       dwc3_core_num_eps(dwc);
diff --git a/queue-6.1/usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch b/queue-6.1/usb-dwc3-xilinx-fix-error-handling-in-zynqmp-init-error-paths.patch
new file mode 100644 (file)
index 0000000..c0fc1d9
--- /dev/null
@@ -0,0 +1,95 @@
+From sashal@kernel.org Sat Jun  6 00:01:21 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 14:31:18 -0400
+Subject: usb: dwc3: xilinx: fix error handling in zynqmp init error paths
+To: stable@vger.kernel.org
+Cc: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>, Thinh Nguyen <Thinh.Nguyen@synopsys.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605183118.2054817-1-sashal@kernel.org>
+
+From: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+
+[ Upstream commit c1a0ecbf32c4b397353204e2ec94c5bb9f3300ed ]
+
+Fix error handling and resource cleanup i.e remove invalid
+phy_exit() after failed phy_init(), route failures through
+proper cleanup paths and return 0 explicitly on success.
+
+Fixes: 84770f028fab ("usb: dwc3: Add driver for Xilinx platforms")
+Cc: stable@vger.kernel.org
+Acked-by: Thinh Nguyen <Thinh.Nguyen@synopsys.com>
+Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@amd.com>
+Link: https://patch.msgid.link/20260519115529.2980421-1-radhey.shyam.pandey@amd.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/dwc3/dwc3-xilinx.c |   26 ++++++++++++++------------
+ 1 file changed, 14 insertions(+), 12 deletions(-)
+
+--- a/drivers/usb/dwc3/dwc3-xilinx.c
++++ b/drivers/usb/dwc3/dwc3-xilinx.c
+@@ -171,15 +171,13 @@ static int dwc3_xlnx_init_zynqmp(struct
+       }
+       ret = phy_init(priv_data->usb3_phy);
+-      if (ret < 0) {
+-              phy_exit(priv_data->usb3_phy);
++      if (ret < 0)
+               goto err;
+-      }
+       ret = reset_control_deassert(apbrst);
+       if (ret < 0) {
+               dev_err(dev, "Failed to release APB reset\n");
+-              goto err;
++              goto err_phy_exit;
+       }
+       /* Set PIPE Power Present signal in FPD Power Present Register*/
+@@ -191,27 +189,25 @@ static int dwc3_xlnx_init_zynqmp(struct
+       ret = reset_control_deassert(crst);
+       if (ret < 0) {
+               dev_err(dev, "Failed to release core reset\n");
+-              goto err;
++              goto err_phy_exit;
+       }
+       ret = reset_control_deassert(hibrst);
+       if (ret < 0) {
+               dev_err(dev, "Failed to release hibernation reset\n");
+-              goto err;
++              goto err_phy_exit;
+       }
+       ret = phy_power_on(priv_data->usb3_phy);
+-      if (ret < 0) {
+-              phy_exit(priv_data->usb3_phy);
+-              goto err;
+-      }
++      if (ret < 0)
++              goto err_phy_exit;
+ skip_usb3_phy:
+       /* ulpi reset via gpio-modepin or gpio-framework driver */
+       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");
++              ret = PTR_ERR(reset_gpio);
++              goto err_phy_power_off;
+       }
+       if (reset_gpio) {
+@@ -231,6 +227,12 @@ skip_usb3_phy:
+               writel(reg, priv_data->regs + XLNX_USB_TRAFFIC_ROUTE_CONFIG);
+       }
++      return 0;
++
++err_phy_power_off:
++      phy_power_off(priv_data->usb3_phy);
++err_phy_exit:
++      phy_exit(priv_data->usb3_phy);
+ err:
+       return ret;
+ }
diff --git a/queue-6.1/usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch b/queue-6.1/usb-gadget-f_hid-fix-device-reference-leak-in-hidg_alloc.patch
new file mode 100644 (file)
index 0000000..3a742a4
--- /dev/null
@@ -0,0 +1,58 @@
+From sashal@kernel.org Sat Jun  6 00:47:15 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:17:11 -0400
+Subject: usb: gadget: f_hid: fix device reference leak in hidg_alloc()
+To: stable@vger.kernel.org
+Cc: Guangshuo Li <lgs201920130244@gmail.com>, stable <stable@kernel.org>, Johan Hovold <johan@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605191711.2132578-2-sashal@kernel.org>
+
+From: Guangshuo Li <lgs201920130244@gmail.com>
+
+[ Upstream commit 4f88d65def6f3c90121601b4f62a4c967f3063a6 ]
+
+hidg_alloc() initializes hidg->dev with device_initialize() before
+calling dev_set_name(). If dev_set_name() fails, the function currently
+jumps to err_unlock and returns without calling put_device().
+
+This leaves the device reference unbalanced and prevents hidg_release()
+from being called. Calling put_device() here is also safe, since
+hidg_release() only frees resources owned by hidg.
+
+The issue was identified by a static analysis tool I developed and
+confirmed by manual review.
+
+Route the dev_set_name() failure path through err_put_device so the
+device reference is dropped properly.
+
+Fixes: 89ff3dfac604 ("usb: gadget: f_hid: fix f_hidg lifetime vs cdev")
+Cc: stable <stable@kernel.org>
+Reviewed-by: Johan Hovold <johan@kernel.org>
+Signed-off-by: Guangshuo Li <lgs201920130244@gmail.com>
+Reviewed-by: Johan Hovold johan@kernel.org
+Link: https://patch.msgid.link/20260413142119.2977716-1-lgs201920130244@gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1278,7 +1278,7 @@ static struct usb_function *hidg_alloc(s
+       hidg->dev.devt = MKDEV(major, opts->minor);
+       ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
+       if (ret)
+-              goto err_unlock;
++              goto err_put_device;
+       hidg->bInterfaceSubClass = opts->subclass;
+       hidg->bInterfaceProtocol = opts->protocol;
+@@ -1313,7 +1313,6 @@ static struct usb_function *hidg_alloc(s
+ err_put_device:
+       put_device(&hidg->dev);
+-err_unlock:
+       mutex_unlock(&opts->lock);
+       return ERR_PTR(ret);
+ }
diff --git a/queue-6.1/usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch b/queue-6.1/usb-gadget-f_hid-tidy-error-handling-in-hidg_alloc.patch
new file mode 100644 (file)
index 0000000..3c38414
--- /dev/null
@@ -0,0 +1,87 @@
+From sashal@kernel.org Sat Jun  6 00:47:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:17:10 -0400
+Subject: usb: gadget: f_hid: tidy error handling in hidg_alloc
+To: stable@vger.kernel.org
+Cc: John Keeping <john@metanate.com>, Lee Jones <lee@kernel.org>, Andrzej Pietrasiewicz <andrzej.p@collabora.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605191711.2132578-1-sashal@kernel.org>
+
+From: John Keeping <john@metanate.com>
+
+[ Upstream commit 944fe915d00d3cb1bacb1e77cabfb6dc82e6f8b8 ]
+
+Unify error handling at the end of the function, reducing the risk of
+missing something on one of the error paths.
+
+Moving the increment of opts->refcnt later means there is no need to
+decrement it on the error path and is safe as this is guarded by
+opts->lock which is held for this entire section.
+
+Tested-by: Lee Jones <lee@kernel.org>
+Reviewed-by: Andrzej Pietrasiewicz <andrzej.p@collabora.com>
+Reviewed-by: Lee Jones <lee@kernel.org>
+Signed-off-by: John Keeping <john@metanate.com>
+Link: https://lore.kernel.org/r/20221122123523.3068034-4-john@metanate.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Stable-dep-of: 4f88d65def6f ("usb: gadget: f_hid: fix device reference leak in hidg_alloc()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/gadget/function/f_hid.c |   21 +++++++++++----------
+ 1 file changed, 11 insertions(+), 10 deletions(-)
+
+--- a/drivers/usb/gadget/function/f_hid.c
++++ b/drivers/usb/gadget/function/f_hid.c
+@@ -1265,7 +1265,6 @@ static struct usb_function *hidg_alloc(s
+       opts = container_of(fi, struct f_hid_opts, func_inst);
+       mutex_lock(&opts->lock);
+-      ++opts->refcnt;
+       spin_lock_init(&hidg->write_spinlock);
+       spin_lock_init(&hidg->read_spinlock);
+@@ -1278,11 +1277,8 @@ static struct usb_function *hidg_alloc(s
+       hidg->dev.class = hidg_class;
+       hidg->dev.devt = MKDEV(major, opts->minor);
+       ret = dev_set_name(&hidg->dev, "hidg%d", opts->minor);
+-      if (ret) {
+-              --opts->refcnt;
+-              mutex_unlock(&opts->lock);
+-              return ERR_PTR(ret);
+-      }
++      if (ret)
++              goto err_unlock;
+       hidg->bInterfaceSubClass = opts->subclass;
+       hidg->bInterfaceProtocol = opts->protocol;
+@@ -1293,14 +1289,13 @@ static struct usb_function *hidg_alloc(s
+                                           opts->report_desc_length,
+                                           GFP_KERNEL);
+               if (!hidg->report_desc) {
+-                      put_device(&hidg->dev);
+-                      --opts->refcnt;
+-                      mutex_unlock(&opts->lock);
+-                      return ERR_PTR(-ENOMEM);
++                      ret = -ENOMEM;
++                      goto err_put_device;
+               }
+       }
+       hidg->use_out_ep = !opts->no_out_endpoint;
++      ++opts->refcnt;
+       mutex_unlock(&opts->lock);
+       hidg->func.name    = "hid";
+@@ -1315,6 +1310,12 @@ static struct usb_function *hidg_alloc(s
+       hidg->qlen         = 4;
+       return &hidg->func;
++
++err_put_device:
++      put_device(&hidg->dev);
++err_unlock:
++      mutex_unlock(&opts->lock);
++      return ERR_PTR(ret);
+ }
+ DECLARE_USB_FUNCTION_INIT(hid, hidg_alloc_inst, hidg_alloc);
diff --git a/queue-6.1/usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch b/queue-6.1/usb-musb-omap2430-fix-use-after-free-in-omap2430_probe.patch
new file mode 100644 (file)
index 0000000..ff0d072
--- /dev/null
@@ -0,0 +1,54 @@
+From sashal@kernel.org Sat Jun  6 00:01:24 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 14:31:21 -0400
+Subject: usb: musb: omap2430: Fix use-after-free in omap2430_probe()
+To: stable@vger.kernel.org
+Cc: Wentao Liang <vulab@iscas.ac.cn>, stable <stable@kernel.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605183121.2054969-1-sashal@kernel.org>
+
+From: Wentao Liang <vulab@iscas.ac.cn>
+
+[ Upstream commit e194ce048f5a6c549b3a23a8c568c6470f40f772 ]
+
+In omap2430_probe(), of_node_put(np) is called prematurely before the
+last access to np, leading to a use-after-free if the node's reference
+count drops to zero. Move the of_node_put() calls after the last use of
+np in both the success and error paths.
+
+Fixes: ffbe2feac59b ("usb: musb: omap2430: Fix probe regression for missing resources")
+Cc: stable <stable@kernel.org>
+Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
+Link: https://patch.msgid.link/20260409101104.480623-1-vulab@iscas.ac.cn
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/musb/omap2430.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/musb/omap2430.c
++++ b/drivers/usb/musb/omap2430.c
+@@ -340,7 +340,6 @@ static int omap2430_probe(struct platfor
+       } else {
+               device_set_of_node_from_dev(&musb->dev, &pdev->dev);
+       }
+-      of_node_put(np);
+       glue->dev                       = &pdev->dev;
+       glue->musb                      = musb;
+@@ -458,6 +457,7 @@ static int omap2430_probe(struct platfor
+               dev_err(&pdev->dev, "failed to register musb device\n");
+               goto err3;
+       }
++      of_node_put(np);
+       return 0;
+@@ -467,6 +467,7 @@ err_put_control_otghs:
+       if (!IS_ERR(glue->control_otghs))
+               put_device(glue->control_otghs);
+ err2:
++      of_node_put(np);
+       platform_device_put(musb);
+ err0:
diff --git a/queue-6.1/usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch b/queue-6.1/usb-typec-ucsi-check-if-power-role-change-actually-happened-before-handling.patch
new file mode 100644 (file)
index 0000000..b175511
--- /dev/null
@@ -0,0 +1,68 @@
+From stable+bounces-260810-greg=kroah.com@vger.kernel.org Sat Jun  6 01:08:35 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  5 Jun 2026 15:38:29 -0400
+Subject: usb: typec: ucsi: Check if power role change actually happened before handling
+To: stable@vger.kernel.org
+Cc: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>, stable <stable@kernel.org>, Sergey Senozhatsky <senozhatsky@chromium.org>, Heikki Krogerus <heikki.krogerus@linux.intel.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260605193829.2169488-1-sashal@kernel.org>
+
+From: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+
+[ Upstream commit b80e7d34c7ea6a564525119d6138fbb577a23dba ]
+
+The CrOS EC may send a connector status change event with the power
+direction changed flag set even if the power direction hasn't actually
+changed after initiating a SET_PDR command internally [1]. In practice
+this happens on every system suspend due to other changes performed by
+the EC [2][3][4], causing suspend to fail.
+
+Fix this by checking if the power role change actually happened before
+handling it.
+
+[1]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=1689;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+[2]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=3923;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+[3]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=5094;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+[4]: https://source.chromium.org/chromiumos/chromiumos/codesearch/+/main:src/platform/ec/zephyr/subsys/pd_controller/pdc_power_mgmt.c;l=2229;drc=2d5a1cffce4e5ac8a39442cb3b764d2d5e1cf794
+
+Cc: stable <stable@kernel.org>
+Fixes: 7616f006db07 ("usb: typec: ucsi: Update power_supply on power role change")
+Signed-off-by: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+Reported-and-tested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
+Link: https://patch.msgid.link/20260519-ucsi-fix-2-v1-1-6f1239535187@qtmlabs.xyz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -783,7 +783,7 @@ static void ucsi_handle_connector_change
+       struct ucsi_connector *con = container_of(work, struct ucsi_connector,
+                                                 work);
+       struct ucsi *ucsi = con->ucsi;
+-      enum typec_role role;
++      enum typec_role role, prev_role;
+       u64 command;
+       int ret;
+@@ -791,6 +791,8 @@ static void ucsi_handle_connector_change
+       command = UCSI_GET_CONNECTOR_STATUS | UCSI_CONNECTOR_NUMBER(con->num);
++      prev_role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
++
+       ret = ucsi_send_command_common(ucsi, command, &con->status,
+                                      sizeof(con->status), true);
+       if (ret < 0) {
+@@ -804,7 +806,7 @@ static void ucsi_handle_connector_change
+       role = !!(con->status.flags & UCSI_CONSTAT_PWR_DIR);
+-      if (con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) {
++      if ((con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) && role != prev_role) {
+               typec_set_pwr_role(con->port, role);
+               ucsi_port_psy_changed(con);
diff --git a/queue-6.1/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch b/queue-6.1/usb-typec-ucsi-don-t-update-power_supply-on-power-role-change-if-not-connected.patch
new file mode 100644 (file)
index 0000000..1a46986
--- /dev/null
@@ -0,0 +1,45 @@
+From stable+bounces-260883-greg=kroah.com@vger.kernel.org Sat Jun  6 18:55:10 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat,  6 Jun 2026 09:21:53 -0400
+Subject: usb: typec: ucsi: Don't update power_supply on power role change if not connected
+To: stable@vger.kernel.org
+Cc: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>, stable <stable@kernel.org>, Sergey Senozhatsky <senozhatsky@chromium.org>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260606132153.2949745-1-sashal@kernel.org>
+
+From: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+
+[ Upstream commit d98d413ca65d0790a8f3695d0a5845538958ab84 ]
+
+We only need to update the power_supply on power role change if the port
+is connected, because otherwise the online status should be the same for
+both cases.
+
+Cc: stable <stable@kernel.org>
+Fixes: 7616f006db07 ("usb: typec: ucsi: Update power_supply on power role change")
+Signed-off-by: Myrrh Periwinkle <myrrhperiwinkle@qtmlabs.xyz>
+Reported-and-tested-by: Sergey Senozhatsky <senozhatsky@chromium.org>
+Link: https://patch.msgid.link/20260519-ucsi-fix-2-v1-2-6f1239535187@qtmlabs.xyz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ changed `UCSI_CONSTAT(con, CONNECTED)` accessor macro to `con->status.flags & UCSI_CONSTAT_CONNECTED` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/usb/typec/ucsi/ucsi.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/usb/typec/ucsi/ucsi.c
++++ b/drivers/usb/typec/ucsi/ucsi.c
+@@ -808,7 +808,12 @@ static void ucsi_handle_connector_change
+       if ((con->status.change & UCSI_CONSTAT_POWER_DIR_CHANGE) && role != prev_role) {
+               typec_set_pwr_role(con->port, role);
+-              ucsi_port_psy_changed(con);
++
++              /* Some power_supply properties vary depending on the power direction when
++               * connected
++               */
++              if (con->status.flags & UCSI_CONSTAT_CONNECTED)
++                      ucsi_port_psy_changed(con);
+               /* Complete pending power role swap */
+               if (!completion_done(&con->complete))
diff --git a/queue-6.1/wifi-brcmfmac-fix-potential-use-after-free-issue-when-stopping-watchdog-task.patch b/queue-6.1/wifi-brcmfmac-fix-potential-use-after-free-issue-when-stopping-watchdog-task.patch
new file mode 100644 (file)
index 0000000..7cf11ad
--- /dev/null
@@ -0,0 +1,55 @@
+From stable+bounces-246843-greg=kroah.com@vger.kernel.org Wed May 13 18:37:14 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 08:48:41 -0400
+Subject: wifi: brcmfmac: Fix potential use-after-free issue when stopping watchdog task
+To: stable@vger.kernel.org
+Cc: Marek Szyprowski <m.szyprowski@samsung.com>, Arend van Spriel <arend.vanspriel@broadcom.com>, Johannes Berg <johannes.berg@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513124841.3712467-1-sashal@kernel.org>
+
+From: Marek Szyprowski <m.szyprowski@samsung.com>
+
+[ Upstream commit c623b63580880cc742255eaed3d79804c1b91143 ]
+
+Watchdog task might end between send_sig() and kthread_stop() calls, what
+results in the use-after-free issue. Fix this by increasing watchdog task
+reference count before calling send_sig() and dropping it by switching to
+kthread_stop_put().
+
+Cc: stable@vger.kernel.org
+Fixes: 373c83a801f1 ("brcmfmac: stop watchdog before detach and free everything")
+Fixes: a9ffda88be74 ("brcm80211: fmac: abstract bus_stop interface function pointer")
+Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Link: https://patch.msgid.link/20260416093339.2066829-1-m.szyprowski@samsung.com
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ replaced kthread_stop_put() with open-coded kthread_stop() + put_task_struct() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -2477,8 +2477,10 @@ static void brcmf_sdio_bus_stop(struct d
+       brcmf_dbg(TRACE, "Enter\n");
+       if (bus->watchdog_tsk) {
++              get_task_struct(bus->watchdog_tsk);
+               send_sig(SIGTERM, bus->watchdog_tsk, 1);
+               kthread_stop(bus->watchdog_tsk);
++              put_task_struct(bus->watchdog_tsk);
+               bus->watchdog_tsk = NULL;
+       }
+@@ -4549,8 +4551,10 @@ void brcmf_sdio_remove(struct brcmf_sdio
+       if (bus) {
+               /* Stop watchdog task */
+               if (bus->watchdog_tsk) {
++                      get_task_struct(bus->watchdog_tsk);
+                       send_sig(SIGTERM, bus->watchdog_tsk, 1);
+                       kthread_stop(bus->watchdog_tsk);
++                      put_task_struct(bus->watchdog_tsk);
+                       bus->watchdog_tsk = NULL;
+               }
diff --git a/queue-6.1/wifi-mac80211-remove-station-if-connection-prep-fails.patch b/queue-6.1/wifi-mac80211-remove-station-if-connection-prep-fails.patch
new file mode 100644 (file)
index 0000000..288ecf2
--- /dev/null
@@ -0,0 +1,54 @@
+From stable+bounces-246817-greg=kroah.com@vger.kernel.org Wed May 13 17:18:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 07:48:48 -0400
+Subject: wifi: mac80211: remove station if connection prep fails
+To: stable@vger.kernel.org
+Cc: Johannes Berg <johannes.berg@intel.com>, Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513114848.3692309-1-sashal@kernel.org>
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+[ Upstream commit 283fc9e44ff5b5ac967439b4951b80bd4299f4e4 ]
+
+If connection preparation fails for MLO connections, then the
+interface is completely reset to non-MLD. In this case, we must
+not keep the station since it's related to the link of the vif
+being removed. Delete an existing station. Any "new_sta" is
+already being removed, so that doesn't need changes.
+
+This fixes a use-after-free/double-free in debugfs if that's
+enabled, because a vif going from MLD (and to MLD, but that's
+not relevant here) recreates its entire debugfs.
+
+Cc: stable@vger.kernel.org
+Fixes: 81151ce462e5 ("wifi: mac80211: support MLO authentication/association with one link")
+Reviewed-by: Miriam Rachel Korenblit <miriam.rachel.korenblit@intel.com>
+Link: https://patch.msgid.link/20260505151533.c4e52deb06ad.Iafe56cec7de8512626169496b134bce3a6c17010@changeid
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+[ used sta_info_destroy_addr() instead of __sta_info_destroy() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/mlme.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -6586,7 +6586,7 @@ static int ieee80211_prep_connection(str
+       struct ieee80211_bss *bss = (void *)cbss->priv;
+       struct sta_info *new_sta = NULL;
+       struct ieee80211_link_data *link;
+-      bool have_sta = false;
++      struct sta_info *have_sta = NULL;
+       bool mlo;
+       int err;
+@@ -6751,6 +6751,8 @@ static int ieee80211_prep_connection(str
+ out_err:
+       ieee80211_link_release_channel(&sdata->deflink);
++      if (mlo && have_sta)
++              WARN_ON(sta_info_destroy_addr(sdata, ap_mld_addr));
+       ieee80211_vif_set_links(sdata, 0);
+       return err;
+ }
diff --git a/queue-6.1/xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch b/queue-6.1/xfrm-ah-account-for-esn-high-bits-in-async-callbacks.patch
new file mode 100644 (file)
index 0000000..4cffe2f
--- /dev/null
@@ -0,0 +1,132 @@
+From stable+bounces-246948-greg=kroah.com@vger.kernel.org Wed May 13 22:31:33 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 12:52:55 -0400
+Subject: xfrm: ah: account for ESN high bits in async callbacks
+To: stable@vger.kernel.org
+Cc: Michael Bommarito <michael.bommarito@gmail.com>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513165255.3822003-3-sashal@kernel.org>
+
+From: Michael Bommarito <michael.bommarito@gmail.com>
+
+[ Upstream commit ec54093e6a8f87e800bb6aa15eb7fc1e33faa524 ]
+
+AH allocates its temporary auth/ICV layout differently when ESN is enabled:
+the async ahash setup appends a 4-byte seqhi slot before the ICV or
+auth_data area, but the async completion callbacks still reconstruct the
+temporary layout as if seqhi were absent.
+
+With an async AH implementation selected, that makes AH copy or compare
+the wrong bytes on both the IPv4 and IPv6 paths. In UML repro on IPv4 AH
+with ESN and forced async hmac(sha1), ping fails with 100% packet loss,
+and the callback logs show the pre-fix drift:
+
+  ah4 output_done: esn=1 err=0 icv_off=20 expected_off=24
+  ah4 input_done: esn=1 auth_off=20 expected_auth_off=24 icv_off=32 expected_icv_off=36
+
+Reconstruct the callback-side layout the same way the setup path built it
+by skipping the ESN seqhi slot before locating the saved auth_data or ICV.
+Per RFC 4302, the ESN high-order 32 bits participate in the AH ICV
+computation, so the async callbacks must account for the seqhi slot.
+
+Post-fix, the same IPv4 AH+ESN+forced-async-hmac(sha1) UML repro shows
+the corrected offset (ah4 output_done: esn=1 err=0 icv_off=24
+expected_off=24) and ping succeeds; net/ipv4/ah4.o and net/ipv6/ah6.o
+build clean at W=1. IPv6 AH+ESN was not exercised at runtime, and the
+change has not been tested against a real async hardware AH engine.
+
+Fixes: d4d573d0334d ("{IPv4,xfrm} Add ESN support for AH egress part")
+Fixes: d8b2a8600b0e ("{IPv4,xfrm} Add ESN support for AH ingress part")
+Fixes: 26dd70c3fad3 ("{IPv6,xfrm} Add ESN support for AH egress part")
+Fixes: 8d6da6f32557 ("{IPv6,xfrm} Add ESN support for AH ingress part")
+Cc: stable@vger.kernel.org
+Assisted-by: Codex:gpt-5-4
+Assisted-by: Claude:claude-opus-4-7
+Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ah4.c |   14 ++++++++++++--
+ net/ipv6/ah6.c |   14 ++++++++++++--
+ 2 files changed, 24 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/ah4.c
++++ b/net/ipv4/ah4.c
+@@ -124,9 +124,14 @@ static void ah_output_done(struct crypto
+       struct iphdr *top_iph = ip_hdr(skb);
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       int ihl = ip_hdrlen(skb);
++      int seqhi_len = 0;
++      __be32 *seqhi;
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       iph = AH_SKB_CB(skb)->tmp;
+-      icv = ah_tmp_icv(iph, ihl);
++      seqhi = (__be32 *)((char *)iph + ihl);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       top_iph->tos = iph->tos;
+@@ -270,12 +275,17 @@ static void ah_input_done(struct crypto_
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       int ihl = ip_hdrlen(skb);
+       int ah_hlen = (ah->hdrlen + 2) << 2;
++      int seqhi_len = 0;
++      __be32 *seqhi;
+       if (err)
+               goto out;
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       work_iph = AH_SKB_CB(skb)->tmp;
+-      auth_data = ah_tmp_auth(work_iph, ihl);
++      seqhi = (__be32 *)((char *)work_iph + ihl);
++      auth_data = ah_tmp_auth(seqhi, seqhi_len);
+       icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+--- a/net/ipv6/ah6.c
++++ b/net/ipv6/ah6.c
+@@ -317,14 +317,19 @@ static void ah6_output_done(struct crypt
+       struct ipv6hdr *top_iph = ipv6_hdr(skb);
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       struct tmp_ext *iph_ext;
++      int seqhi_len = 0;
++      __be32 *seqhi;
+       extlen = skb_network_header_len(skb) - sizeof(struct ipv6hdr);
+       if (extlen)
+               extlen += sizeof(*iph_ext);
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       iph_base = AH_SKB_CB(skb)->tmp;
+       iph_ext = ah_tmp_ext(iph_base);
+-      icv = ah_tmp_icv(iph_ext, extlen);
++      seqhi = (__be32 *)((char *)iph_ext + extlen);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       memcpy(ah->auth_data, icv, ahp->icv_trunc_len);
+       memcpy(top_iph, iph_base, IPV6HDR_BASELEN);
+@@ -471,13 +476,18 @@ static void ah6_input_done(struct crypto
+       struct ip_auth_hdr *ah = ip_auth_hdr(skb);
+       int hdr_len = skb_network_header_len(skb);
+       int ah_hlen = ipv6_authlen(ah);
++      int seqhi_len = 0;
++      __be32 *seqhi;
+       if (err)
+               goto out;
++      if (x->props.flags & XFRM_STATE_ESN)
++              seqhi_len = sizeof(*seqhi);
+       work_iph = AH_SKB_CB(skb)->tmp;
+       auth_data = ah_tmp_auth(work_iph, hdr_len);
+-      icv = ah_tmp_icv(auth_data, ahp->icv_trunc_len);
++      seqhi = (__be32 *)(auth_data + ahp->icv_trunc_len);
++      icv = ah_tmp_icv(seqhi, seqhi_len);
+       err = crypto_memneq(icv, auth_data, ahp->icv_trunc_len) ? -EBADMSG : 0;
+       if (err)
diff --git a/queue-6.1/xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch b/queue-6.1/xfrm-defensively-unhash-xfrm_state-lists-in-__xfrm_state_delete.patch
new file mode 100644 (file)
index 0000000..48460f8
--- /dev/null
@@ -0,0 +1,119 @@
+From stable+bounces-246966-greg=kroah.com@vger.kernel.org Wed May 13 23:19:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 13 May 2026 13:31:43 -0400
+Subject: xfrm: defensively unhash xfrm_state lists in __xfrm_state_delete
+To: stable@vger.kernel.org
+Cc: Michal Kosiorek <mkosiorek121@gmail.com>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260513173143.3885911-1-sashal@kernel.org>
+
+From: Michal Kosiorek <mkosiorek121@gmail.com>
+
+[ Upstream commit 14acf9652e5690de3c7486c6db5fb8dafd0a32a3 ]
+
+KASAN reproduces a slab-use-after-free in __xfrm_state_delete()'s
+hlist_del_rcu calls under syzkaller load on linux-6.12.y stable
+(reproduced on 6.12.47, also reachable via the same code path on
+torvalds/master and on the ipsec tree). Nine unique signatures cluster
+in the xfrm_state lifecycle, the load-bearing one being:
+
+  BUG: KASAN: slab-use-after-free in __hlist_del include/linux/list.h:990 [inline]
+  BUG: KASAN: slab-use-after-free in hlist_del_rcu include/linux/rculist.h:516 [inline]
+  BUG: KASAN: slab-use-after-free in __xfrm_state_delete net/xfrm/xfrm_state.c
+  Write of size 8 at addr ffff8881198bcb70 by task kworker/u8:9/435
+
+  Workqueue: netns cleanup_net
+  Call Trace:
+   __hlist_del / hlist_del_rcu
+   __xfrm_state_delete
+   xfrm_state_delete
+   xfrm_state_flush
+   xfrm_state_fini
+   ops_exit_list
+   cleanup_net
+
+The other observed signatures hit the same slab object from
+__xfrm_state_lookup, xfrm_alloc_spi, __xfrm_state_insert and an OOB
+write variant of __xfrm_state_delete, all on the byseq/byspi
+hash chains.
+
+__xfrm_state_delete() guards its byseq and byspi unhashes with
+value-based predicates:
+
+       if (x->km.seq)
+               hlist_del_rcu(&x->byseq);
+       if (x->id.spi)
+               hlist_del_rcu(&x->byspi);
+
+while everywhere else in the file (e.g. state_cache, state_cache_input)
+the safer hlist_unhashed() check is used. xfrm_alloc_spi() sets
+x->id.spi = newspi inside xfrm_state_lock and then immediately inserts
+into byspi, but a path that observes x->id.spi != 0 outside of
+xfrm_state_lock can still skip-or-hit the byspi unhash inconsistently
+with whether x is actually on the list. The same holds for x->km.seq
+versus byseq, and the bydst/bysrc unhashes have no predicate at all,
+so a second __xfrm_state_delete() on the same object writes through
+LIST_POISON pprev.
+
+The defensive change here:
+
+  - Use hlist_del_init_rcu() instead of hlist_del_rcu() on bydst,
+    bysrc, byseq and byspi so a second deletion is a no-op rather
+    than a write through LIST_POISON pprev. The byseq/byspi nodes
+    are already initialised in xfrm_state_alloc().
+  - Test hlist_unhashed() rather than the value predicate for
+    byseq/byspi, so the unhash decision tracks list state rather than
+    mutable scalar fields.
+
+Empirical verification: applied this patch on top of v6.12.47, rebuilt,
+and re-ran the same syzkaller harness for 1h16m on a previously-crashy
+configuration that produced ~100 hits each of slab-use-after-free
+Read in xfrm_alloc_spi / Read in __xfrm_state_lookup / Write in
+__xfrm_state_delete. After the patch, 7.1M execs across 32 VMs at
+~1550 exec/sec produced zero xfrm_state UAF/OOB hits. /proc/slabinfo
+confirms the xfrm_state slab is actively allocated and freed during
+the run (~143 KiB resident), so the fuzzer is still exercising those
+code paths -- they just no longer crash.
+
+Reproduction:
+
+  - Linux 6.12.47 x86_64 + KASAN_GENERIC + KASAN_INLINE + KCOV
+  - syzkaller @ 746545b8b1e4c3a128db8652b340d3df90ce61db
+  - 32 QEMU/KVM VMs x 2 vCPU on AWS c5.metal bare metal
+  - 9 unique signatures collected in ~9h, all within xfrm_state
+    lifecycle
+
+Fixes: fe9f1d8779cb ("xfrm: add state hashtable keyed by seq")
+Fixes: 7b4dc3600e48 ("[XFRM]: Do not add a state whose SPI is zero to the SPI hash.")
+Reported-by: Michal Kosiorek <mkosiorek121@gmail.com>
+Tested-by: Michal Kosiorek <mkosiorek121@gmail.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Michal Kosiorek <mkosiorek121@gmail.com>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+[ dropped state_cache/state_cache_input unhash hunks and xfrm_nat_keepalive_state_updated() call ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_state.c |   12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- a/net/xfrm/xfrm_state.c
++++ b/net/xfrm/xfrm_state.c
+@@ -682,12 +682,12 @@ int __xfrm_state_delete(struct xfrm_stat
+               x->km.state = XFRM_STATE_DEAD;
+               spin_lock(&net->xfrm.xfrm_state_lock);
+               list_del(&x->km.all);
+-              hlist_del_rcu(&x->bydst);
+-              hlist_del_rcu(&x->bysrc);
+-              if (x->km.seq)
+-                      hlist_del_rcu(&x->byseq);
+-              if (x->id.spi)
+-                      hlist_del_rcu(&x->byspi);
++              hlist_del_init_rcu(&x->bydst);
++              hlist_del_init_rcu(&x->bysrc);
++              if (!hlist_unhashed(&x->byseq))
++                      hlist_del_init_rcu(&x->byseq);
++              if (!hlist_unhashed(&x->byspi))
++                      hlist_del_init_rcu(&x->byspi);
+               net->xfrm.state_num--;
+               spin_unlock(&net->xfrm.xfrm_state_lock);
diff --git a/queue-6.1/xfs-fix-a-resource-leak-in-xfs_alloc_buftarg.patch b/queue-6.1/xfs-fix-a-resource-leak-in-xfs_alloc_buftarg.patch
new file mode 100644 (file)
index 0000000..30d1d36
--- /dev/null
@@ -0,0 +1,37 @@
+From stable+bounces-244778-greg=kroah.com@vger.kernel.org Fri May  8 20:26:50 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri,  8 May 2026 10:52:06 -0400
+Subject: xfs: fix a resource leak in xfs_alloc_buftarg()
+To: stable@vger.kernel.org
+Cc: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>, "Darrick J. Wong" <djwong@kernel.org>, Carlos Maiolino <cem@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260508145206.1512706-1-sashal@kernel.org>
+
+From: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
+
+[ Upstream commit 29a7b2614357393b176ef06ba5bc3ff5afc8df69 ]
+
+In the error path, call fs_put_dax() to drop the DAX
+device reference.
+
+Fixes: 6f643c57d57c ("xfs: implement ->notify_failure() for XFS")
+Cc: stable@vger.kernel.org
+Signed-off-by: Haoxiang Li <lihaoxiang@isrc.iscas.ac.cn>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Carlos Maiolino <cem@kernel.org>
+[ kept `kmem_free(btp)` and `return NULL` instead of `kfree(btp)`/`ERR_PTR(error)` ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/xfs_buf.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/xfs/xfs_buf.c
++++ b/fs/xfs/xfs_buf.c
+@@ -2036,6 +2036,7 @@ error_pcpu:
+ error_lru:
+       list_lru_destroy(&btp->bt_lru);
+ error_free:
++      fs_put_dax(btp->bt_daxdev, mp);
+       kmem_free(btp);
+       return NULL;
+ }